From 5effac3b0246cecbb2c1ede43b986099d40baf51 Mon Sep 17 00:00:00 2001 From: Lynne Date: Sun, 24 Nov 2024 15:55:14 +0100 Subject: [PATCH] ffv1enc: expose ff_ffv1_encode_buffer_size The function is quite important to ensure that the output is always going to be sufficient, and it can change version to version, so exposing it makes sense. --- libavcodec/ffv1enc.c | 34 ++++++++++++++++++++++------------ libavcodec/ffv1enc.h | 2 ++ libavcodec/ffv1enc_vulkan.c | 14 +------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 4f0bd4f973..c96c71b109 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -1172,6 +1172,26 @@ retry: return 0; } +size_t ff_ffv1_encode_buffer_size(AVCodecContext *avctx) +{ + FFV1Context *f = avctx->priv_data; + + size_t maxsize = avctx->width*avctx->height * (1 + f->transparency); + if (f->chroma_planes) + maxsize += AV_CEIL_RSHIFT(avctx->width, f->chroma_h_shift) * AV_CEIL_RSHIFT(f->height, f->chroma_v_shift) * 2; + maxsize += f->slice_count * 800; //for slice header + if (f->version > 3) { + maxsize *= f->bits_per_raw_sample + 1; + } else { + maxsize += f->slice_count * 2 * (avctx->width + avctx->height); //for bug with slices that code some pixels more than once + maxsize *= 8*(2*f->bits_per_raw_sample + 5); + } + maxsize >>= 3; + maxsize += FF_INPUT_BUFFER_MIN_SIZE; + + return maxsize; +} + static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { @@ -1228,18 +1248,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } - maxsize = avctx->width*avctx->height * (1 + f->transparency); - if (f->chroma_planes) - maxsize += AV_CEIL_RSHIFT(avctx->width, f->chroma_h_shift) * AV_CEIL_RSHIFT(f->height, f->chroma_v_shift) * 2; - maxsize += f->slice_count * 800; //for slice header - if (f->version > 3) { - maxsize *= f->bits_per_raw_sample + 1; - } else { - maxsize += f->slice_count * 2 * (avctx->width + avctx->height); //for bug with slices that code some pixels more than once - maxsize *= 8*(2*f->bits_per_raw_sample + 5); - } - maxsize >>= 3; - maxsize += FF_INPUT_BUFFER_MIN_SIZE; + /* Maximum packet size */ + maxsize = ff_ffv1_encode_buffer_size(avctx); if (maxsize > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - 32) { av_log(avctx, AV_LOG_WARNING, "Cannot allocate worst case packet size, the encoding could fail\n"); diff --git a/libavcodec/ffv1enc.h b/libavcodec/ffv1enc.h index 82c7f9da19..e22693f2a8 100644 --- a/libavcodec/ffv1enc.h +++ b/libavcodec/ffv1enc.h @@ -30,4 +30,6 @@ av_cold int ff_ffv1_write_extradata(AVCodecContext *avctx); av_cold int ff_ffv1_encode_setup_plane_info(AVCodecContext *avctx, enum AVPixelFormat pix_fmt); +size_t ff_ffv1_encode_buffer_size(AVCodecContext *avctx); + #endif /* AVCODEC_FFV1ENC_H */ diff --git a/libavcodec/ffv1enc_vulkan.c b/libavcodec/ffv1enc_vulkan.c index 3ec03b4566..f6bf9ca6fa 100644 --- a/libavcodec/ffv1enc_vulkan.c +++ b/libavcodec/ffv1enc_vulkan.c @@ -413,19 +413,7 @@ static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx, ff_vk_exec_add_dep_buf(&fv->s, exec, &fd->results_data_ref, 1, 1); /* Output buffer size */ - maxsize = avctx->width*avctx->height*(1 + f->transparency); - if (f->chroma_planes) - maxsize += AV_CEIL_RSHIFT(avctx->width, f->chroma_h_shift) * - AV_CEIL_RSHIFT(f->height, f->chroma_v_shift)*2; - maxsize += f->slice_count * 800; - if (f->version > 3) { - maxsize *= f->bits_per_raw_sample + 1; - } else { - maxsize += f->slice_count * 2 * (avctx->width + avctx->height); - maxsize *= 8*(2*f->bits_per_raw_sample + 5); - } - maxsize >>= 3; - maxsize += FF_INPUT_BUFFER_MIN_SIZE; + maxsize = ff_ffv1_encode_buffer_size(avctx); /* Allocate output buffer */ RET(ff_vk_get_pooled_buffer(&fv->s, &fv->out_data_pool,