diff options
-rw-r--r-- | intern/ffmpeg/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/ffmpeg/ffmpeg_compat.h | 8 | ||||
-rw-r--r-- | intern/ffmpeg/tests/ffmpeg_codecs.cc | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/writeffmpeg.c | 48 |
4 files changed, 49 insertions, 14 deletions
diff --git a/intern/ffmpeg/CMakeLists.txt b/intern/ffmpeg/CMakeLists.txt index 0de8496f3f3..4fb5df9d4cd 100644 --- a/intern/ffmpeg/CMakeLists.txt +++ b/intern/ffmpeg/CMakeLists.txt @@ -6,6 +6,7 @@ if(WITH_GTESTS) tests/ffmpeg_codecs.cc ) set(TEST_INC + . ) set(TEST_INC_SYS ${FFMPEG_INCLUDE_DIRS} diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h index f311e04d8e0..f7d87af8bca 100644 --- a/intern/ffmpeg/ffmpeg_compat.h +++ b/intern/ffmpeg/ffmpeg_compat.h @@ -36,6 +36,14 @@ # define FFMPEG_INLINE static inline #endif +#if (LIBAVFORMAT_VERSION_MAJOR < 59) +/* For versions older than ffmpeg 5.0, use the old channel layout variables. + * We intend to only keep this workaround for around two releases (3.5, 3.6). + * If it sticks around any longer, then we should consider refactoring this. + */ +# define FFMPEG_USE_OLD_CHANNEL_VARS +#endif + #if (LIBAVFORMAT_VERSION_MAJOR < 58) || \ ((LIBAVFORMAT_VERSION_MAJOR == 58) && (LIBAVFORMAT_VERSION_MINOR < 76)) # define FFMPEG_USE_DURATION_WORKAROUND 1 diff --git a/intern/ffmpeg/tests/ffmpeg_codecs.cc b/intern/ffmpeg/tests/ffmpeg_codecs.cc index 10cbe4b938b..cd06917f59b 100644 --- a/intern/ffmpeg/tests/ffmpeg_codecs.cc +++ b/intern/ffmpeg/tests/ffmpeg_codecs.cc @@ -3,6 +3,8 @@ #include "testing/testing.h" extern "C" { +#include "ffmpeg_compat.h" + #include <libavcodec/avcodec.h> #include <libavutil/channel_layout.h> #include <libavutil/log.h> @@ -40,7 +42,11 @@ bool test_acodec(const AVCodec *codec, AVSampleFormat fmt) if (ctx) { ctx->sample_fmt = fmt; ctx->sample_rate = 48000; +#ifdef FFMPEG_USE_OLD_CHANNEL_VARS + ctx->channel_layout = AV_CH_LAYOUT_MONO; +#else av_channel_layout_from_mask(&ctx->ch_layout, AV_CH_LAYOUT_MONO); +#endif ctx->bit_rate = 128000; int open = avcodec_open2(ctx, codec, NULL); if (open >= 0) { diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index d71db8f71a5..4c11a2896a8 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -141,18 +141,25 @@ static int write_audio_frame(FFMpegContext *context) frame->pts = context->audio_time / av_q2d(c->time_base); frame->nb_samples = context->audio_input_samples; frame->format = c->sample_fmt; +# ifdef FFMPEG_USE_OLD_CHANNEL_VARS + frame->channels = c->channels; + frame->channel_layout = c->channel_layout; + const int num_channels = c->channels; +# else av_channel_layout_copy(&frame->ch_layout, &c->ch_layout); + const int num_channels = c->ch_layout.nb_channels; +# endif if (context->audio_deinterleave) { int channel, i; uint8_t *temp; - for (channel = 0; channel < c->ch_layout.nb_channels; channel++) { + for (channel = 0; channel < num_channels; channel++) { for (i = 0; i < frame->nb_samples; i++) { memcpy(context->audio_deinterleave_buffer + (i + channel * frame->nb_samples) * context->audio_sample_size, context->audio_input_buffer + - (c->ch_layout.nb_channels * i + channel) * context->audio_sample_size, + (num_channels * i + channel) * context->audio_sample_size, context->audio_sample_size); } } @@ -163,10 +170,10 @@ static int write_audio_frame(FFMpegContext *context) } avcodec_fill_audio_frame(frame, - c->ch_layout.nb_channels, + num_channels, c->sample_fmt, context->audio_input_buffer, - context->audio_input_samples * c->ch_layout.nb_channels * + context->audio_input_samples * num_channels * context->audio_sample_size, 1); @@ -944,25 +951,34 @@ static AVStream *alloc_audio_stream(FFMpegContext *context, c->sample_rate = rd->ffcodecdata.audio_mixrate; c->bit_rate = context->ffmpeg_audio_bitrate * 1000; c->sample_fmt = AV_SAMPLE_FMT_S16; - c->ch_layout.nb_channels = rd->ffcodecdata.audio_channels; + const int num_channels = rd->ffcodecdata.audio_channels; + int channel_layout_mask = 0; switch (rd->ffcodecdata.audio_channels) { case FFM_CHANNELS_MONO: - av_channel_layout_from_mask(&c->ch_layout, AV_CH_LAYOUT_MONO); + channel_layout_mask = AV_CH_LAYOUT_MONO; break; case FFM_CHANNELS_STEREO: - av_channel_layout_from_mask(&c->ch_layout, AV_CH_LAYOUT_STEREO); + channel_layout_mask = AV_CH_LAYOUT_STEREO; break; case FFM_CHANNELS_SURROUND4: - av_channel_layout_from_mask(&c->ch_layout, AV_CH_LAYOUT_QUAD); + channel_layout_mask = AV_CH_LAYOUT_QUAD; break; case FFM_CHANNELS_SURROUND51: - av_channel_layout_from_mask(&c->ch_layout, AV_CH_LAYOUT_5POINT1_BACK); + channel_layout_mask = AV_CH_LAYOUT_5POINT1_BACK; break; case FFM_CHANNELS_SURROUND71: - av_channel_layout_from_mask(&c->ch_layout, AV_CH_LAYOUT_7POINT1); + channel_layout_mask = AV_CH_LAYOUT_7POINT1; break; } + BLI_assert(channel_layout_mask != 0); + +# ifdef FFMPEG_USE_OLD_CHANNEL_VARS + c->channels = num_channels; + c->channel_layout = channel_layout_mask; +# else + av_channel_layout_from_mask(&c->ch_layout, channel_layout_mask); +# endif if (request_float_audio_buffer(codec_id)) { /* mainly for AAC codec which is experimental */ @@ -1027,7 +1043,7 @@ static AVStream *alloc_audio_stream(FFMpegContext *context, * not sure if that is needed anymore, so let's try out if there are any * complaints regarding some FFmpeg versions users might have. */ context->audio_input_samples = AV_INPUT_BUFFER_MIN_SIZE * 8 / c->bits_per_coded_sample / - c->ch_layout.nb_channels; + num_channels; } else { context->audio_input_samples = c->frame_size; @@ -1037,11 +1053,11 @@ static AVStream *alloc_audio_stream(FFMpegContext *context, context->audio_sample_size = av_get_bytes_per_sample(c->sample_fmt); - context->audio_input_buffer = (uint8_t *)av_malloc( - context->audio_input_samples * c->ch_layout.nb_channels * context->audio_sample_size); + context->audio_input_buffer = (uint8_t *)av_malloc(context->audio_input_samples * num_channels * + context->audio_sample_size); if (context->audio_deinterleave) { context->audio_deinterleave_buffer = (uint8_t *)av_malloc( - context->audio_input_samples * c->ch_layout.nb_channels * context->audio_sample_size); + context->audio_input_samples * num_channels * context->audio_sample_size); } context->audio_time = 0.0f; @@ -1432,7 +1448,11 @@ int BKE_ffmpeg_start(void *context_v, AVCodecContext *c = context->audio_codec; AUD_DeviceSpecs specs; +# ifdef FFMPEG_USE_OLD_CHANNEL_VARS + specs.channels = c->channels; +# else specs.channels = c->ch_layout.nb_channels; +# endif switch (av_get_packed_sample_fmt(c->sample_fmt)) { case AV_SAMPLE_FMT_U8: |