diff options
Diffstat (limited to 'gnu/packages')
| -rw-r--r-- | gnu/packages/games.scm | 33 | ||||
| -rw-r--r-- | gnu/packages/patches/hedgewars-fix-pascalbasic-name-conflict.patch | 51 | ||||
| -rw-r--r-- | gnu/packages/patches/hedgewars-support-ffmpegv6.patch | 456 |
3 files changed, 536 insertions, 4 deletions
diff --git a/gnu/packages/games.scm b/gnu/packages/games.scm index 0bac113b9f9..badcd8dc5a2 100644 --- a/gnu/packages/games.scm +++ b/gnu/packages/games.scm | |||
| @@ -11820,6 +11820,10 @@ play with up to four players simultaneously. It has network support.") | |||
| 11820 | (define-public hedgewars | 11820 | (define-public hedgewars |
| 11821 | (package | 11821 | (package |
| 11822 | (name "hedgewars") | 11822 | (name "hedgewars") |
| 11823 | ;; TODO: Delete phase 'import-control-dot-monad' on versions >1.0.3. | ||
| 11824 | ;; TODO: Remove patch 'hedgewars-support-ffmpegv6' on versions >1.0.2. | ||
| 11825 | ;; TODO: Remove patch 'hedgewars-fix-pascalbasic-name-conflict' | ||
| 11826 | ;; on versions >1.0.3. | ||
| 11823 | (version "1.0.2") | 11827 | (version "1.0.2") |
| 11824 | (source (origin | 11828 | (source (origin |
| 11825 | (method url-fetch) | 11829 | (method url-fetch) |
| @@ -11827,17 +11831,38 @@ play with up to four players simultaneously. It has network support.") | |||
| 11827 | "hedgewars-src-" version ".tar.bz2")) | 11831 | "hedgewars-src-" version ".tar.bz2")) |
| 11828 | (sha256 | 11832 | (sha256 |
| 11829 | (base32 | 11833 | (base32 |
| 11830 | "04pjpkjhpy720n803gv35iygmjdvsrmw13mih4ympjnqbgjfa7r0")))) | 11834 | "04pjpkjhpy720n803gv35iygmjdvsrmw13mih4ympjnqbgjfa7r0")) |
| 11835 | (patches | ||
| 11836 | (search-patches "hedgewars-fix-pascalbasic-name-conflict.patch" | ||
| 11837 | "hedgewars-support-ffmpegv6.patch")))) | ||
| 11831 | (build-system qt-build-system) | 11838 | (build-system qt-build-system) |
| 11832 | (arguments | 11839 | (arguments |
| 11833 | (list | 11840 | (list |
| 11834 | ;; XXX: Engine is built as Pascal source code, requiring Free Pascal | 11841 | ;; XXX: Engine is built as Pascal source code, requiring Free Pascal |
| 11835 | ;; Compiler, which we haven't packaged yet. With the flag below, we use | 11842 | ;; Compiler, which we haven't packaged yet. With the flag below, we use |
| 11836 | ;; a Pascal to C translator and Clang instead. | 11843 | ;; a Pascal to C translator and Clang instead. |
| 11837 | #:configure-flags #~(list "-DBUILD_ENGINE_C=ON" | 11844 | #:configure-flags |
| 11838 | "-Dhaskell_flags=-dynamic;-fPIC") | 11845 | #~'("-DBUILD_ENGINE_C=ON" |
| 11846 | "-DNOVERSIONINFOUPDATE=ON" | ||
| 11847 | "-Dhaskell_flags=-dynamic;-fPIC") | ||
| 11839 | #:phases | 11848 | #:phases |
| 11840 | #~(modify-phases %standard-phases | 11849 | #~(modify-phases %standard-phases |
| 11850 | (add-after 'unpack 'import-control-dot-monad | ||
| 11851 | (lambda _ | ||
| 11852 | (with-directory-excursion "gameServer" | ||
| 11853 | (substitute* '("ClientIO.hs" | ||
| 11854 | "HandlerUtils.hs" | ||
| 11855 | "HWProtoChecker.hs" | ||
| 11856 | "HWProtoCore.hs" | ||
| 11857 | "HWProtoLobbyState.hs" | ||
| 11858 | "HandlerUtils.hs" | ||
| 11859 | "ServerState.hs" | ||
| 11860 | "Votes.hs" | ||
| 11861 | "../tools/pas2c/Pas2C.hs") | ||
| 11862 | ;; All files define `import Control.Monad.{something}`. | ||
| 11863 | ;; Our symbols are in Control.Monad now as well. | ||
| 11864 | (("import Control\\.Monad" all) | ||
| 11865 | (string-append all "\n" "import Control.Monad")))))) | ||
| 11841 | (replace 'check | 11866 | (replace 'check |
| 11842 | (lambda* (#:key tests? #:allow-other-keys) | 11867 | (lambda* (#:key tests? #:allow-other-keys) |
| 11843 | (when tests? | 11868 | (when tests? |
| @@ -11851,7 +11876,7 @@ play with up to four players simultaneously. It has network support.") | |||
| 11851 | (string-append "../hedgewars-src-" #$version) | 11876 | (string-append "../hedgewars-src-" #$version) |
| 11852 | (install-file "misc/hedgewars.png" icons)))))))) | 11877 | (install-file "misc/hedgewars.png" icons)))))))) |
| 11853 | (inputs | 11878 | (inputs |
| 11854 | (list ffmpeg-4 | 11879 | (list ffmpeg |
| 11855 | freeglut | 11880 | freeglut |
| 11856 | ghc-entropy | 11881 | ghc-entropy |
| 11857 | ghc-hslogger | 11882 | ghc-hslogger |
diff --git a/gnu/packages/patches/hedgewars-fix-pascalbasic-name-conflict.patch b/gnu/packages/patches/hedgewars-fix-pascalbasic-name-conflict.patch new file mode 100644 index 00000000000..3c06e3cd563 --- /dev/null +++ b/gnu/packages/patches/hedgewars-fix-pascalbasic-name-conflict.patch | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | From ab3fac1e3b354890a3925235881673b97691dba2 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: unc0rr <unc0rr@gmail.com> | ||
| 3 | Date: Fri, 16 Jun 2023 08:10:45 +0200 | ||
| 4 | Subject: [PATCH] Fix pas2c build erroring after parsec added function we | ||
| 5 | already define | ||
| 6 | |||
| 7 | --- | ||
| 8 | tools/pas2c/PascalBasics.hs | 2 +- | ||
| 9 | tools/pas2c/PascalParser.hs | 2 +- | ||
| 10 | tools/pas2c/PascalPreprocessor.hs | 2 +- | ||
| 11 | 3 files changed, 3 insertions(+), 3 deletions(-) | ||
| 12 | |||
| 13 | diff --git a/tools/pas2c/PascalBasics.hs b/tools/pas2c/PascalBasics.hs | ||
| 14 | index f4eba72f87..eaf4d596db 100644 | ||
| 15 | --- a/tools/pas2c/PascalBasics.hs | ||
| 16 | +++ b/tools/pas2c/PascalBasics.hs | ||
| 17 | @@ -2,7 +2,7 @@ | ||
| 18 | module PascalBasics where | ||
| 19 | |||
| 20 | import Text.Parsec.Combinator | ||
| 21 | -import Text.Parsec.Char | ||
| 22 | +import Text.Parsec.Char hiding (string') | ||
| 23 | import Text.Parsec.Prim | ||
| 24 | import Text.Parsec.Token | ||
| 25 | import Text.Parsec.Language | ||
| 26 | diff --git a/tools/pas2c/PascalParser.hs b/tools/pas2c/PascalParser.hs | ||
| 27 | index 2edd7a2479..c97bb359aa 100644 | ||
| 28 | --- a/tools/pas2c/PascalParser.hs | ||
| 29 | +++ b/tools/pas2c/PascalParser.hs | ||
| 30 | @@ -4,7 +4,7 @@ module PascalParser ( | ||
| 31 | ) | ||
| 32 | where | ||
| 33 | |||
| 34 | -import Text.Parsec | ||
| 35 | +import Text.Parsec hiding (string') | ||
| 36 | import Text.Parsec.Token | ||
| 37 | import Text.Parsec.Expr | ||
| 38 | import Control.Monad | ||
| 39 | diff --git a/tools/pas2c/PascalPreprocessor.hs b/tools/pas2c/PascalPreprocessor.hs | ||
| 40 | index 4db8eaa8ae..93a176209c 100644 | ||
| 41 | --- a/tools/pas2c/PascalPreprocessor.hs | ||
| 42 | +++ b/tools/pas2c/PascalPreprocessor.hs | ||
| 43 | @@ -1,7 +1,7 @@ | ||
| 44 | {-# LANGUAGE ScopedTypeVariables #-} | ||
| 45 | module PascalPreprocessor where | ||
| 46 | |||
| 47 | -import Text.Parsec | ||
| 48 | +import Text.Parsec hiding (string') | ||
| 49 | import Control.Monad.IO.Class | ||
| 50 | import Control.Monad | ||
| 51 | import System.IO | ||
diff --git a/gnu/packages/patches/hedgewars-support-ffmpegv6.patch b/gnu/packages/patches/hedgewars-support-ffmpegv6.patch new file mode 100644 index 00000000000..d656a6c7cc8 --- /dev/null +++ b/gnu/packages/patches/hedgewars-support-ffmpegv6.patch | |||
| @@ -0,0 +1,456 @@ | |||
| 1 | From 9445c40eb179047e85c47acedb724eee42e3f0df Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Pekka Ristola <pekkarr@protonmail.com> | ||
| 3 | Date: Mon, 27 Jan 2025 19:08:05 +0100 | ||
| 4 | Subject: [PATCH] Add support for ffmpeg 6.0 - Use the new | ||
| 5 | send_frame/receive_packet API for encoding - Use the new channel layout API | ||
| 6 | for audio - Fix audio recording - Copy codec parameters to the stream | ||
| 7 | parameters - Set correct pts for audio frames - Read audio samples from | ||
| 8 | file directly to the refcounted AVFrame buffer instead of the `g_pSamples` | ||
| 9 | buffer - Use global AVPackets allocated with `av_packet_alloc` - Stop trying | ||
| 10 | to write more audio frames when `WriteAudioFrame` fails with a negative error | ||
| 11 | code - Fix segfault with `g_pContainer->url`. The field has to be allocated | ||
| 12 | with `av_malloc` before writing to it. It's set to `NULL` by default. - | ||
| 13 | Properly free allocations with `avcodec_free_context` and | ||
| 14 | `avformat_free_context` | ||
| 15 | |||
| 16 | --- | ||
| 17 | hedgewars/avwrapper/avwrapper.c | 234 +++++++++++++++++++++++++++----- | ||
| 18 | 1 file changed, 203 insertions(+), 31 deletions(-) | ||
| 19 | |||
| 20 | diff --git a/hedgewars/avwrapper/avwrapper.c b/hedgewars/avwrapper/avwrapper.c | ||
| 21 | index 6c0fe739b4..3daeb07b75 100644 | ||
| 22 | --- a/hedgewars/avwrapper/avwrapper.c | ||
| 23 | +++ b/hedgewars/avwrapper/avwrapper.c | ||
| 24 | @@ -42,15 +42,19 @@ | ||
| 25 | #define UNUSED(x) (void)(x) | ||
| 26 | |||
| 27 | static AVFormatContext* g_pContainer; | ||
| 28 | -static AVOutputFormat* g_pFormat; | ||
| 29 | +static const AVOutputFormat* g_pFormat; | ||
| 30 | static AVStream* g_pAStream; | ||
| 31 | static AVStream* g_pVStream; | ||
| 32 | static AVFrame* g_pAFrame; | ||
| 33 | static AVFrame* g_pVFrame; | ||
| 34 | -static AVCodec* g_pACodec; | ||
| 35 | -static AVCodec* g_pVCodec; | ||
| 36 | +static const AVCodec* g_pACodec; | ||
| 37 | +static const AVCodec* g_pVCodec; | ||
| 38 | static AVCodecContext* g_pAudio; | ||
| 39 | static AVCodecContext* g_pVideo; | ||
| 40 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 41 | +static AVPacket* g_pAPacket; | ||
| 42 | +static AVPacket* g_pVPacket; | ||
| 43 | +#endif | ||
| 44 | |||
| 45 | static int g_Width, g_Height; | ||
| 46 | static uint32_t g_Frequency, g_Channels; | ||
| 47 | @@ -58,8 +62,13 @@ static int g_VQuality; | ||
| 48 | static AVRational g_Framerate; | ||
| 49 | |||
| 50 | static FILE* g_pSoundFile; | ||
| 51 | +#if LIBAVUTIL_VERSION_MAJOR < 53 | ||
| 52 | static int16_t* g_pSamples; | ||
| 53 | +#endif | ||
| 54 | static int g_NumSamples; | ||
| 55 | +#if LIBAVCODEC_VERSION_MAJOR >= 53 | ||
| 56 | +static int64_t g_NextAudioPts; | ||
| 57 | +#endif | ||
| 58 | |||
| 59 | |||
| 60 | // compatibility section | ||
| 61 | @@ -93,6 +102,8 @@ static void rescale_ts(AVPacket *pkt, AVRational ctb, AVRational stb) | ||
| 62 | if (pkt->duration > 0) | ||
| 63 | pkt->duration = av_rescale_q(pkt->duration, ctb, stb); | ||
| 64 | } | ||
| 65 | + | ||
| 66 | +#define avcodec_free_context(ctx) do { avcodec_close(*ctx); av_freep(ctx); } while (0) | ||
| 67 | #endif | ||
| 68 | |||
| 69 | #ifndef AV_CODEC_CAP_DELAY | ||
| 70 | @@ -165,8 +176,42 @@ static void Log(const char* pFmt, ...) | ||
| 71 | AddFileLogRaw(Buffer); | ||
| 72 | } | ||
| 73 | |||
| 74 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 75 | +static int EncodeAndWriteFrame( | ||
| 76 | + const AVStream* pStream, | ||
| 77 | + AVCodecContext* pCodecContext, | ||
| 78 | + const AVFrame* pFrame, | ||
| 79 | + AVPacket* pPacket) | ||
| 80 | +{ | ||
| 81 | + int ret; | ||
| 82 | + | ||
| 83 | + ret = avcodec_send_frame(pCodecContext, pFrame); | ||
| 84 | + if (ret < 0) | ||
| 85 | + return FatalError("avcodec_send_frame failed: %d", ret); | ||
| 86 | + while (1) | ||
| 87 | + { | ||
| 88 | + ret = avcodec_receive_packet(pCodecContext, pPacket); | ||
| 89 | + if (ret == AVERROR(EAGAIN)) | ||
| 90 | + return 1; | ||
| 91 | + else if (ret == AVERROR_EOF) | ||
| 92 | + return 0; | ||
| 93 | + else if (ret < 0) | ||
| 94 | + return FatalError("avcodec_receive_packet failed: %d", ret); | ||
| 95 | + | ||
| 96 | + av_packet_rescale_ts(pPacket, pCodecContext->time_base, pStream->time_base); | ||
| 97 | + | ||
| 98 | + // Write the compressed frame to the media file. | ||
| 99 | + pPacket->stream_index = pStream->index; | ||
| 100 | + ret = av_interleaved_write_frame(g_pContainer, pPacket); | ||
| 101 | + if (ret != 0) | ||
| 102 | + return FatalError("Error while writing frame: %d", ret); | ||
| 103 | + } | ||
| 104 | +} | ||
| 105 | +#endif | ||
| 106 | + | ||
| 107 | static void AddAudioStream() | ||
| 108 | { | ||
| 109 | + int ret; | ||
| 110 | g_pAStream = avformat_new_stream(g_pContainer, g_pACodec); | ||
| 111 | if(!g_pAStream) | ||
| 112 | { | ||
| 113 | @@ -176,20 +221,44 @@ static void AddAudioStream() | ||
| 114 | g_pAStream->id = 1; | ||
| 115 | |||
| 116 | #if LIBAVCODEC_VERSION_MAJOR >= 59 | ||
| 117 | - const AVCodec *audio_st_codec = avcodec_find_decoder(g_pAStream->codecpar->codec_id); | ||
| 118 | - g_pAudio = avcodec_alloc_context3(audio_st_codec); | ||
| 119 | - avcodec_parameters_to_context(g_pAudio, g_pAStream->codecpar); | ||
| 120 | + g_pAudio = avcodec_alloc_context3(g_pACodec); | ||
| 121 | #else | ||
| 122 | g_pAudio = g_pAStream->codec; | ||
| 123 | -#endif | ||
| 124 | |||
| 125 | avcodec_get_context_defaults3(g_pAudio, g_pACodec); | ||
| 126 | g_pAudio->codec_id = g_pACodec->id; | ||
| 127 | +#endif | ||
| 128 | |||
| 129 | // put parameters | ||
| 130 | g_pAudio->sample_fmt = AV_SAMPLE_FMT_S16; | ||
| 131 | g_pAudio->sample_rate = g_Frequency; | ||
| 132 | +#if LIBAVCODEC_VERSION_MAJOR >= 60 | ||
| 133 | + const AVChannelLayout* pChLayout = g_pACodec->ch_layouts; | ||
| 134 | + if (pChLayout) | ||
| 135 | + { | ||
| 136 | + for (; pChLayout->nb_channels; pChLayout++) | ||
| 137 | + { | ||
| 138 | + if (pChLayout->nb_channels == g_Channels) | ||
| 139 | + { | ||
| 140 | + ret = av_channel_layout_copy(&g_pAudio->ch_layout, pChLayout); | ||
| 141 | + if (ret != 0) | ||
| 142 | + { | ||
| 143 | + Log("Channel layout copy failed: %d\n", ret); | ||
| 144 | + return; | ||
| 145 | + } | ||
| 146 | + break; | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | + } | ||
| 150 | + if (!g_pAudio->ch_layout.nb_channels) | ||
| 151 | + { | ||
| 152 | + // no suitable layout found | ||
| 153 | + g_pAudio->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; | ||
| 154 | + g_pAudio->ch_layout.nb_channels = g_Channels; | ||
| 155 | + } | ||
| 156 | +#else | ||
| 157 | g_pAudio->channels = g_Channels; | ||
| 158 | +#endif | ||
| 159 | |||
| 160 | // set time base as invers of sample rate | ||
| 161 | g_pAudio->time_base.den = g_pAStream->time_base.den = g_Frequency; | ||
| 162 | @@ -213,6 +282,15 @@ static void AddAudioStream() | ||
| 163 | return; | ||
| 164 | } | ||
| 165 | |||
| 166 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 167 | + ret = avcodec_parameters_from_context(g_pAStream->codecpar, g_pAudio); | ||
| 168 | + if (ret < 0) | ||
| 169 | + { | ||
| 170 | + Log("Could not copy parameters from codec context: %d\n", ret); | ||
| 171 | + return; | ||
| 172 | + } | ||
| 173 | +#endif | ||
| 174 | + | ||
| 175 | #if LIBAVCODEC_VERSION_MAJOR >= 54 | ||
| 176 | if (g_pACodec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) | ||
| 177 | #else | ||
| 178 | @@ -221,13 +299,46 @@ static void AddAudioStream() | ||
| 179 | g_NumSamples = 4096; | ||
| 180 | else | ||
| 181 | g_NumSamples = g_pAudio->frame_size; | ||
| 182 | - g_pSamples = (int16_t*)av_malloc(g_NumSamples*g_Channels*sizeof(int16_t)); | ||
| 183 | g_pAFrame = av_frame_alloc(); | ||
| 184 | if (!g_pAFrame) | ||
| 185 | { | ||
| 186 | Log("Could not allocate frame\n"); | ||
| 187 | return; | ||
| 188 | } | ||
| 189 | +#if LIBAVUTIL_VERSION_MAJOR >= 53 | ||
| 190 | +#if LIBAVCODEC_VERSION_MAJOR >= 60 | ||
| 191 | + ret = av_channel_layout_copy(&g_pAFrame->ch_layout, &g_pAudio->ch_layout); | ||
| 192 | + if (ret != 0) | ||
| 193 | + { | ||
| 194 | + Log("Channel layout copy for frame failed: %d\n", ret); | ||
| 195 | + return; | ||
| 196 | + } | ||
| 197 | +#else | ||
| 198 | + g_pAFrame->channels = g_pAudio->channels; | ||
| 199 | +#endif | ||
| 200 | + g_pAFrame->format = g_pAudio->sample_fmt; | ||
| 201 | + g_pAFrame->sample_rate = g_pAudio->sample_rate; | ||
| 202 | + g_pAFrame->nb_samples = g_NumSamples; | ||
| 203 | + ret = av_frame_get_buffer(g_pAFrame, 1); | ||
| 204 | + if (ret < 0) | ||
| 205 | + { | ||
| 206 | + Log("Failed to allocate frame buffer: %d\n", ret); | ||
| 207 | + return; | ||
| 208 | + } | ||
| 209 | +#else | ||
| 210 | + g_pSamples = (int16_t*)av_malloc(g_NumSamples*g_Channels*sizeof(int16_t)); | ||
| 211 | +#endif | ||
| 212 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 213 | + g_pAPacket = av_packet_alloc(); | ||
| 214 | + if (!g_pAPacket) | ||
| 215 | + { | ||
| 216 | + Log("Could not allocate audio packet\n"); | ||
| 217 | + return; | ||
| 218 | + } | ||
| 219 | +#endif | ||
| 220 | +#if LIBAVCODEC_VERSION_MAJOR >= 53 | ||
| 221 | + g_NextAudioPts = 0; | ||
| 222 | +#endif | ||
| 223 | } | ||
| 224 | |||
| 225 | // returns non-zero if there is more sound, -1 in case of error | ||
| 226 | @@ -236,22 +347,46 @@ static int WriteAudioFrame() | ||
| 227 | if (!g_pAStream) | ||
| 228 | return 0; | ||
| 229 | |||
| 230 | - AVPacket Packet; | ||
| 231 | - av_init_packet(&Packet); | ||
| 232 | - Packet.data = NULL; | ||
| 233 | - Packet.size = 0; | ||
| 234 | + int ret; | ||
| 235 | + int16_t* pData; | ||
| 236 | +#if LIBAVUTIL_VERSION_MAJOR >= 53 | ||
| 237 | + ret = av_frame_make_writable(g_pAFrame); | ||
| 238 | + if (ret < 0) | ||
| 239 | + return FatalError("Could not make audio frame writable: %d", ret); | ||
| 240 | + pData = (int16_t*) g_pAFrame->data[0]; | ||
| 241 | +#else | ||
| 242 | + pData = g_pSamples; | ||
| 243 | +#endif | ||
| 244 | |||
| 245 | - int NumSamples = fread(g_pSamples, 2*g_Channels, g_NumSamples, g_pSoundFile); | ||
| 246 | + int NumSamples = fread(pData, 2*g_Channels, g_NumSamples, g_pSoundFile); | ||
| 247 | |||
| 248 | #if LIBAVCODEC_VERSION_MAJOR >= 53 | ||
| 249 | AVFrame* pFrame = NULL; | ||
| 250 | if (NumSamples > 0) | ||
| 251 | { | ||
| 252 | g_pAFrame->nb_samples = NumSamples; | ||
| 253 | + g_pAFrame->pts = g_NextAudioPts; | ||
| 254 | + g_NextAudioPts += NumSamples; | ||
| 255 | +#if LIBAVUTIL_VERSION_MAJOR < 53 | ||
| 256 | avcodec_fill_audio_frame(g_pAFrame, g_Channels, AV_SAMPLE_FMT_S16, | ||
| 257 | - (uint8_t*)g_pSamples, NumSamples*2*g_Channels, 1); | ||
| 258 | + (uint8_t*)pData, NumSamples*2*g_Channels, 1); | ||
| 259 | +#endif | ||
| 260 | pFrame = g_pAFrame; | ||
| 261 | } | ||
| 262 | +#endif | ||
| 263 | + | ||
| 264 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 265 | + ret = EncodeAndWriteFrame(g_pAStream, g_pAudio, pFrame, g_pAPacket); | ||
| 266 | + if (ret < 0) | ||
| 267 | + return FatalError("Audio frame processing failed"); | ||
| 268 | + return ret; | ||
| 269 | +#else | ||
| 270 | + AVPacket Packet; | ||
| 271 | + av_init_packet(&Packet); | ||
| 272 | + Packet.data = NULL; | ||
| 273 | + Packet.size = 0; | ||
| 274 | + | ||
| 275 | +#if LIBAVCODEC_VERSION_MAJOR >= 53 | ||
| 276 | // when NumSamples == 0 we still need to call encode_audio2 to flush | ||
| 277 | int got_packet; | ||
| 278 | if (avcodec_encode_audio2(g_pAudio, &Packet, pFrame, &got_packet) != 0) | ||
| 279 | @@ -266,7 +401,7 @@ static int WriteAudioFrame() | ||
| 280 | int BufferSize = OUTBUFFER_SIZE; | ||
| 281 | if (g_pAudio->frame_size == 0) | ||
| 282 | BufferSize = NumSamples*g_Channels*2; | ||
| 283 | - Packet.size = avcodec_encode_audio(g_pAudio, g_OutBuffer, BufferSize, g_pSamples); | ||
| 284 | + Packet.size = avcodec_encode_audio(g_pAudio, g_OutBuffer, BufferSize, pData); | ||
| 285 | if (Packet.size == 0) | ||
| 286 | return 1; | ||
| 287 | if (g_pAudio->coded_frame && g_pAudio->coded_frame->pts != AV_NOPTS_VALUE) | ||
| 288 | @@ -280,25 +415,25 @@ static int WriteAudioFrame() | ||
| 289 | if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) | ||
| 290 | return FatalError("Error while writing audio frame"); | ||
| 291 | return 1; | ||
| 292 | +#endif | ||
| 293 | } | ||
| 294 | |||
| 295 | // add a video output stream | ||
| 296 | static int AddVideoStream() | ||
| 297 | { | ||
| 298 | + int ret; | ||
| 299 | g_pVStream = avformat_new_stream(g_pContainer, g_pVCodec); | ||
| 300 | if (!g_pVStream) | ||
| 301 | return FatalError("Could not allocate video stream"); | ||
| 302 | |||
| 303 | #if LIBAVCODEC_VERSION_MAJOR >= 59 | ||
| 304 | - const AVCodec *video_st_codec = avcodec_find_decoder(g_pVStream->codecpar->codec_id); | ||
| 305 | - g_pVideo = avcodec_alloc_context3(video_st_codec); | ||
| 306 | - avcodec_parameters_to_context(g_pVideo, g_pVStream->codecpar); | ||
| 307 | + g_pVideo = avcodec_alloc_context3(g_pVCodec); | ||
| 308 | #else | ||
| 309 | g_pVideo = g_pVStream->codec; | ||
| 310 | -#endif | ||
| 311 | |||
| 312 | avcodec_get_context_defaults3(g_pVideo, g_pVCodec); | ||
| 313 | g_pVideo->codec_id = g_pVCodec->id; | ||
| 314 | +#endif | ||
| 315 | |||
| 316 | // put parameters | ||
| 317 | // resolution must be a multiple of two | ||
| 318 | @@ -361,6 +496,12 @@ static int AddVideoStream() | ||
| 319 | if (avcodec_open2(g_pVideo, g_pVCodec, NULL) < 0) | ||
| 320 | return FatalError("Could not open video codec %s", g_pVCodec->long_name); | ||
| 321 | |||
| 322 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 323 | + ret = avcodec_parameters_from_context(g_pVStream->codecpar, g_pVideo); | ||
| 324 | + if (ret < 0) | ||
| 325 | + return FatalError("Could not copy parameters from codec context: %d", ret); | ||
| 326 | +#endif | ||
| 327 | + | ||
| 328 | g_pVFrame = av_frame_alloc(); | ||
| 329 | if (!g_pVFrame) | ||
| 330 | return FatalError("Could not allocate frame"); | ||
| 331 | @@ -370,6 +511,12 @@ static int AddVideoStream() | ||
| 332 | g_pVFrame->height = g_Height; | ||
| 333 | g_pVFrame->format = AV_PIX_FMT_YUV420P; | ||
| 334 | |||
| 335 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 336 | + g_pVPacket = av_packet_alloc(); | ||
| 337 | + if (!g_pVPacket) | ||
| 338 | + return FatalError("Could not allocate packet"); | ||
| 339 | +#endif | ||
| 340 | + | ||
| 341 | return avcodec_default_get_buffer2(g_pVideo, g_pVFrame, 0); | ||
| 342 | } | ||
| 343 | |||
| 344 | @@ -380,6 +527,10 @@ static int WriteFrame(AVFrame* pFrame) | ||
| 345 | // write interleaved audio frame | ||
| 346 | if (g_pAStream) | ||
| 347 | { | ||
| 348 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 349 | + if (!g_pAPacket) | ||
| 350 | + return FatalError("Error while writing video frame: g_pAPacket does not exist"); | ||
| 351 | +#endif | ||
| 352 | VideoTime = (double)g_pVFrame->pts * g_pVStream->time_base.num/g_pVStream->time_base.den; | ||
| 353 | do | ||
| 354 | { | ||
| 355 | @@ -388,7 +539,7 @@ static int WriteFrame(AVFrame* pFrame) | ||
| 356 | AudioTime = (double)g_pAFrame->pts * g_pAStream->time_base.num/g_pAStream->time_base.den; | ||
| 357 | ret = WriteAudioFrame(); | ||
| 358 | } | ||
| 359 | - while (AudioTime < VideoTime && ret); | ||
| 360 | + while (AudioTime < VideoTime && ret > 0); | ||
| 361 | if (ret < 0) | ||
| 362 | return ret; | ||
| 363 | } | ||
| 364 | @@ -396,13 +547,18 @@ static int WriteFrame(AVFrame* pFrame) | ||
| 365 | if (!g_pVStream) | ||
| 366 | return 0; | ||
| 367 | |||
| 368 | + g_pVFrame->pts++; | ||
| 369 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 370 | + ret = EncodeAndWriteFrame(g_pVStream, g_pVideo, pFrame, g_pVPacket); | ||
| 371 | + if (ret < 0) | ||
| 372 | + return FatalError("Video frame processing failed"); | ||
| 373 | + return ret; | ||
| 374 | +#else | ||
| 375 | AVPacket Packet; | ||
| 376 | av_init_packet(&Packet); | ||
| 377 | Packet.data = NULL; | ||
| 378 | Packet.size = 0; | ||
| 379 | |||
| 380 | - g_pVFrame->pts++; | ||
| 381 | -#if LIBAVCODEC_VERSION_MAJOR < 58 | ||
| 382 | if (g_pFormat->flags & AVFMT_RAWPICTURE) | ||
| 383 | { | ||
| 384 | /* raw video case. The API will change slightly in the near | ||
| 385 | @@ -417,7 +573,6 @@ static int WriteFrame(AVFrame* pFrame) | ||
| 386 | return 0; | ||
| 387 | } | ||
| 388 | else | ||
| 389 | -#endif | ||
| 390 | { | ||
| 391 | #if LIBAVCODEC_VERSION_MAJOR >= 54 | ||
| 392 | int got_packet; | ||
| 393 | @@ -447,6 +602,7 @@ static int WriteFrame(AVFrame* pFrame) | ||
| 394 | |||
| 395 | return 1; | ||
| 396 | } | ||
| 397 | +#endif | ||
| 398 | } | ||
| 399 | |||
| 400 | AVWRAP_DECL int AVWrapper_WriteFrame(uint8_t *buf) | ||
| 401 | @@ -539,9 +695,13 @@ AVWRAP_DECL int AVWrapper_Init( | ||
| 402 | char ext[16]; | ||
| 403 | strncpy(ext, g_pFormat->extensions, 16); | ||
| 404 | ext[15] = 0; | ||
| 405 | - ext[strcspn(ext,",")] = 0; | ||
| 406 | + size_t extLen = strcspn(ext, ","); | ||
| 407 | + ext[extLen] = 0; | ||
| 408 | #if LIBAVCODEC_VERSION_MAJOR >= 59 | ||
| 409 | - snprintf(g_pContainer->url, sizeof(g_pContainer->url), "%s.%s", pFilename, ext); | ||
| 410 | + // pFilename + dot + ext + null byte | ||
| 411 | + size_t urlLen = strlen(pFilename) + 1 + extLen + 1; | ||
| 412 | + g_pContainer->url = av_malloc(urlLen); | ||
| 413 | + snprintf(g_pContainer->url, urlLen, "%s.%s", pFilename, ext); | ||
| 414 | #else | ||
| 415 | snprintf(g_pContainer->filename, sizeof(g_pContainer->filename), "%s.%s", pFilename, ext); | ||
| 416 | #endif | ||
| 417 | @@ -636,21 +796,33 @@ AVWRAP_DECL int AVWrapper_Close() | ||
| 418 | // free everything | ||
| 419 | if (g_pVStream) | ||
| 420 | { | ||
| 421 | - avcodec_close(g_pVideo); | ||
| 422 | - av_free(g_pVideo); | ||
| 423 | - av_free(g_pVStream); | ||
| 424 | + avcodec_free_context(&g_pVideo); | ||
| 425 | av_frame_free(&g_pVFrame); | ||
| 426 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 427 | + av_packet_free(&g_pVPacket); | ||
| 428 | +#endif | ||
| 429 | } | ||
| 430 | if (g_pAStream) | ||
| 431 | { | ||
| 432 | - avcodec_close(g_pAudio); | ||
| 433 | - av_free(g_pAudio); | ||
| 434 | - av_free(g_pAStream); | ||
| 435 | + avcodec_free_context(&g_pAudio); | ||
| 436 | av_frame_free(&g_pAFrame); | ||
| 437 | +#if LIBAVCODEC_VERSION_MAJOR >= 58 | ||
| 438 | + av_packet_free(&g_pAPacket); | ||
| 439 | +#endif | ||
| 440 | +#if LIBAVUTIL_VERSION_MAJOR < 53 | ||
| 441 | av_free(g_pSamples); | ||
| 442 | +#endif | ||
| 443 | fclose(g_pSoundFile); | ||
| 444 | } | ||
| 445 | |||
| 446 | +#if LIBAVCODEC_VERSION_MAJOR >= 59 | ||
| 447 | + avformat_free_context(g_pContainer); | ||
| 448 | +#else | ||
| 449 | + if (g_pVStream) | ||
| 450 | + av_free(g_pVStream); | ||
| 451 | + if (g_pAStream) | ||
| 452 | + av_free(g_pAStream); | ||
| 453 | av_free(g_pContainer); | ||
| 454 | +#endif | ||
| 455 | return 0; | ||
| 456 | } | ||
