diff --git a/source/blender/imbuf/intern/anim_movie.cc b/source/blender/imbuf/intern/anim_movie.cc index 3d51969dd4609b4771c8630eaf1d787caefc2bd6..f69c717b561f5f377443d2ce7521ef615e6815ee 100644 --- a/source/blender/imbuf/intern/anim_movie.cc +++ b/source/blender/imbuf/intern/anim_movie.cc @@ -43,6 +43,7 @@ extern "C" { # include <libavcodec/avcodec.h> # include <libavformat/avformat.h> +# include <libavutil/cpu.h> # include <libavutil/imgutils.h> # include <libavutil/rational.h> # include <libswscale/swscale.h> @@ -368,7 +369,13 @@ static int startffmpeg(ImBufAnim *anim) anim->pFrameRGB->width = anim->x; anim->pFrameRGB->height = anim->y; - if (av_frame_get_buffer(anim->pFrameRGB, 0) < 0) { + /* Note: even if av_frame_get_buffer suggests to pass 0 for alignment, + * as of ffmpeg 6.1/7.0 it does not use correct alignment for AVX512 + * CPU (frame.c get_video_buffer ends up always using 32 alignment, + * whereas it should have used 64). Reported upstream: + * https://trac.ffmpeg.org/ticket/11116 */ + const size_t align = av_cpu_max_align(); + if (av_frame_get_buffer(anim->pFrameRGB, align) < 0) { fprintf(stderr, "Could not allocate frame data.\n"); avcodec_free_context(&anim->pCodecCtx); avformat_close_input(&anim->pFormatCtx); @@ -1115,25 +1122,6 @@ static ImBuf *ffmpeg_fetchibuf(ImBufAnim *anim, int position, IMB_Timecode_Type anim->x = anim->pCodecCtx->width; anim->y = anim->pCodecCtx->height; - /* Certain versions of FFmpeg have a bug in libswscale which ends up in crash - * when destination buffer is not properly aligned. For example, this happens - * in FFmpeg 4.3.1. It got fixed later on, but for compatibility reasons is - * still best to avoid crash. - * - * This is achieved by using a separate allocation call rather than relying on - * IMB_allocImBuf() to do so since the IMB_allocImBuf() is not guaranteed - * to perform aligned allocation. - * - * In theory this could give better performance, since SIMD operations on - * aligned data are usually faster. - * - * Note that even though sometimes vertical flip is required it does not - * affect on alignment of data passed to sws_scale because if the X dimension - * is not 32 byte aligned special intermediate buffer is allocated. - * - * The issue was reported to FFmpeg under ticket #8747 in the FFmpeg tracker - * and is fixed in the newer versions than 4.3.1. */ - const AVPixFmtDescriptor *pix_fmt_descriptor = av_pix_fmt_desc_get(anim->pCodecCtx->pix_fmt); int planes = R_IMF_PLANES_RGBA; @@ -1144,8 +1132,9 @@ static ImBuf *ffmpeg_fetchibuf(ImBufAnim *anim, int position, IMB_Timecode_Type ImBuf *cur_frame_final = IMB_allocImBuf(anim->x, anim->y, planes, 0); /* Allocate the storage explicitly to ensure the memory is aligned. */ + const size_t align = av_cpu_max_align(); uint8_t *buffer_data = static_cast<uint8_t *>( - MEM_mallocN_aligned(size_t(4) * anim->x * anim->y, 32, "ffmpeg ibuf")); + MEM_mallocN_aligned(size_t(4) * anim->x * anim->y, align, "ffmpeg ibuf")); IMB_assign_byte_buffer(cur_frame_final, buffer_data, IB_TAKE_OWNERSHIP); cur_frame_final->byte_buffer.colorspace = colormanage_colorspace_get_named(anim->colorspace);