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.
This commit is contained in:
Lynne 2024-11-24 15:55:14 +01:00
parent d8f301cdf2
commit 5effac3b02
No known key found for this signature in database
GPG Key ID: A2FEA5F03F034464
3 changed files with 25 additions and 25 deletions

View File

@ -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");

View File

@ -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 */

View File

@ -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,