https://bugs.gentoo.org/951199 Backport of [1] plus a chunk from [2] for another anim_movie.cc issue. [1] https://projects.blender.org/blender/blender/commit/b1ca2f09dba5c4a6d21806ab913a2374bf7b3b8f [2] https://projects.blender.org/blender/blender/pulls/121947 --- a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp +++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp @@ -28,7 +28,12 @@ AUD_NAMESPACE_BEGIN +/* FFmpeg < 4.0 */ #if LIBAVCODEC_VERSION_MAJOR < 58 #define FFMPEG_OLD_CODE #endif +/* FFmpeg < 5.0 */ +#if LIBAVCODEC_VERSION_MAJOR < 59 +#define FFMPEG_OLD_CH_LAYOUT +#endif SampleFormat FFMPEGReader::convertSampleFormat(AVSampleFormat format) @@ -113,5 +118,11 @@ break; - int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, m_frame->nb_samples, m_codecCtx->sample_fmt, 1); + #ifdef FFMPEG_OLD_CH_LAYOUT + int channels = m_codecCtx->channels; + #else + int channels = m_codecCtx->ch_layout.nb_channels; + #endif + + int data_size = av_samples_get_buffer_size(nullptr, channels, m_frame->nb_samples, m_codecCtx->sample_fmt, 1); if(buf_size - buf_pos < data_size) @@ -123,10 +134,10 @@ if(m_tointerleave) { - int single_size = data_size / m_codecCtx->channels / m_frame->nb_samples; - for(int channel = 0; channel < m_codecCtx->channels; channel++) + int single_size = data_size / channels / m_frame->nb_samples; + for(int channel = 0; channel < channels; channel++) { for(int i = 0; i < m_frame->nb_samples; i++) { - std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size, + std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((channels * i) + channel) * single_size, m_frame->data[channel] + i * single_size, single_size); } @@ -208,5 +219,10 @@ AUD_THROW(FileException, "File couldn't be read, ffmpeg codec couldn't be opened."); - m_specs.channels = (Channels) m_codecCtx->channels; + #ifdef FFMPEG_OLD_CH_LAYOUT + int channels = m_codecCtx->channels; + #else + int channels = m_codecCtx->ch_layout.nb_channels; + #endif + m_specs.channels = (Channels) channels; m_tointerleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt); @@ -346,5 +362,10 @@ info.specs.format = convertSampleFormat(m_formatCtx->streams[i]->codec->sample_fmt); #else - info.specs.channels = Channels(m_formatCtx->streams[i]->codecpar->channels); + #ifdef FFMPEG_OLD_CH_LAYOUT + int channels = m_formatCtx->streams[i]->codecpar->channels; + #else + int channels = m_formatCtx->streams[i]->codecpar->ch_layout.nb_channels; + #endif + info.specs.channels = Channels(channels); info.specs.rate = m_formatCtx->streams[i]->codecpar->sample_rate; info.specs.format = convertSampleFormat(AVSampleFormat(m_formatCtx->streams[i]->codecpar->format)); --- a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp +++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp @@ -31,7 +31,12 @@ AUD_NAMESPACE_BEGIN +/* FFmpeg < 4.0 */ #if LIBAVCODEC_VERSION_MAJOR < 58 #define FFMPEG_OLD_CODE #endif +/* FFmpeg < 5.0 */ +#if LIBAVCODEC_VERSION_MAJOR < 59 +#define FFMPEG_OLD_CH_LAYOUT +#endif void FFMPEGWriter::encode() @@ -78,6 +83,11 @@ m_frame->nb_samples = m_input_samples; m_frame->format = m_codecCtx->sample_fmt; +#ifdef FFMPEG_OLD_CH_LAYOUT m_frame->channel_layout = m_codecCtx->channel_layout; m_frame->channels = m_specs.channels; +#else + if(av_channel_layout_copy(&m_frame->ch_layout, &m_codecCtx->ch_layout) < 0) + AUD_THROW(FileException, "File couldn't be written, couldn't copy audio channel layout."); +#endif if(avcodec_fill_audio_frame(m_frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast(data), m_input_buffer.getSize(), 0) < 0) @@ -406,6 +416,11 @@ m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO; m_codecCtx->bit_rate = bitrate; +#ifdef FFMPEG_OLD_CH_LAYOUT m_codecCtx->channel_layout = channel_layout; m_codecCtx->channels = m_specs.channels; +#else + av_channel_layout_uninit(&m_codecCtx->ch_layout); + av_channel_layout_from_mask(&m_codecCtx->ch_layout, channel_layout); +#endif m_stream->time_base.num = m_codecCtx->time_base.num = 1; m_stream->time_base.den = m_codecCtx->time_base.den = m_codecCtx->sample_rate; --- a/intern/ffmpeg/ffmpeg_compat.h +++ b/intern/ffmpeg/ffmpeg_compat.h @@ -41,4 +41,11 @@ #endif +#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(58, 29, 100) +/* In ffmpeg 6.1 usage of the "key_frame" variable from "AVFrame" has been deprecated. + * used the new method to query for the "AV_FRAME_FLAG_KEY" flag instead. + */ +# define FFMPEG_OLD_KEY_FRAME_QUERY_METHOD +#endif + #if (LIBAVFORMAT_VERSION_MAJOR < 59) /* For versions older than ffmpeg 5.0, use the old channel layout variables. --- a/source/blender/imbuf/intern/anim_movie.cc +++ b/source/blender/imbuf/intern/anim_movie.cc @@ -657,5 +657,9 @@ anim->cur_pts = av_get_pts_from_frame(anim->pFrame); +# ifdef FFMPEG_OLD_KEY_FRAME_QUERY_METHOD if (anim->pFrame->key_frame) { +# else + if (anim->pFrame->flags & AV_FRAME_FLAG_KEY) { +# endif anim->cur_key_frame_pts = anim->cur_pts; } @@ -1036,9 +1040,8 @@ AVFormatContext *format_ctx = anim->pFormatCtx; - if (format_ctx->iformat->read_seek2 || format_ctx->iformat->read_seek) { - ret = av_seek_frame(anim->pFormatCtx, anim->videoStream, seek_pos, AVSEEK_FLAG_BACKWARD); - } - else { - ret = ffmpeg_generic_seek_workaround(anim, &seek_pos, pts_to_search); + int ret = av_seek_frame(anim->pFormatCtx, anim->videoStream, seek_pos, AVSEEK_FLAG_BACKWARD); + + if (ret < 0) { + ret = ffmpeg_generic_seek_workaround(anim, &seek_pos, pts_to_search);\ av_log(anim->pFormatCtx, AV_LOG_DEBUG,