Hi, 2014-08-12 12:26 GMT+02:00 Michael Niedermayer <michae...@gmx.at>: > On Tue, Aug 12, 2014 at 11:56:21AM +0200, Christophe Gisquet wrote: >> Hi, >> >> 2014-08-12 10:19 GMT+02:00 Michael Niedermayer <michae...@gmx.at>: >> > the "serious undersizing" check already depends on the assumtation >> > that FF_MIN_BUFFER_SIZE is larger than a slice, >> >> Yes, and here lies the issue: if we haven't been able to guess it >> correctly previously, how likely are we to guess it correctly here? >> Take 2*max(previous_slice_size) ? > > I think if we allocate based on a upper bound and that turns out > not enough, its better to fail and tell the user to report a bug > than to try to reallocate.
Hopefully, the warning should incite the user to report it, but I agree that trying to handle it may cut us for those reports. As you like, but if you prefer failing, then maybe something like: if (pkt_size <= buf - orig_buf + 2*max_slice_size) return AVERROR_BUFFER_TOO_SMALL; is enough? > for the per slice check we could take 2 or 3 times the upper bound > of a slice and allocate more by that. And then check that we still > have that amount before we start each slice. This should give us > a 2-3 times saftey factor for underestimating slice sizes. While only > slightly increasing the overall buffer size I chose 2 times in the attached patch. I have no strong opinion on which solution is best, though reallocating was a specific request I got. -- Christophe
From 4934f42ce3b96e269786240f9eeee90da47bef2c Mon Sep 17 00:00:00 2001 From: Christophe Gisquet <christophe.gisq...@gmail.com> Date: Mon, 11 Aug 2014 19:37:39 +0200 Subject: [PATCH 1/2] proresenc_kostya: realloc if buffer too small The buffer allocation may be incorrect (e.g. with an alpha plane), and currently causes the buffer to be set to NULL by init_put_bits, later on causing crashing. So, detect that situation, and if detected, reallocate the buffer and ask a sample if it happens. Fixes ticket #2760 --- libavcodec/proresenc_kostya.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c index a70ae3c..46acbf3 100644 --- a/libavcodec/proresenc_kostya.c +++ b/libavcodec/proresenc_kostya.c @@ -209,6 +209,7 @@ typedef struct ProresContext { int bits_per_mb; int force_quant; int alpha_bits; + int warn; char *vendor; int quant_sel; @@ -938,7 +939,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, int sizes[4] = { 0 }; int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1); int frame_size, picture_size, slice_size; - int pkt_size, ret; + int pkt_size, ret, max_slice_size = 0; uint8_t frame_flags; *avctx->coded_frame = *pic; @@ -1023,6 +1024,38 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream_put_byte(&buf, slice_hdr_size << 3); slice_hdr = buf; buf += slice_hdr_size - 1; + if (pkt_size <= buf - orig_buf + 2*max_slice_size) { + uint8_t *start = pkt->data; + // Recompute new size according to max_slice_size + // and deduce delta + int delta = 200 + ctx->pictures_per_frame * + ctx->slices_per_picture * max_slice_size + - pkt_size; + + delta = FFMAX(delta, 2*max_slice_size); + ctx->frame_size_upper_bound += delta; + + if (!ctx->warn) { + avpriv_request_sample(avctx, + "Packet too small: is %i," + " needs %i (slice: %i). " + "Correct allocation", + pkt_size, delta); + ctx->warn = 1; + } + ret = av_grow_packet(pkt, delta); + if (ret < 0) + return AVERROR(ENOMEM); + + pkt_size += delta; + // restore pointers + orig_buf = pkt->data + (orig_buf - start); + buf = pkt->data + (buf - start); + picture_size_pos = pkt->data + (picture_size_pos - start); + slice_sizes = pkt->data + (slice_sizes - start); + slice_hdr = pkt->data + (slice_hdr - start); + tmp = pkt->data + (tmp - start); + } init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8); ret = encode_slice(avctx, pic, &pb, sizes, x, y, q, mbs_per_slice); if (ret < 0) @@ -1036,6 +1069,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } bytestream_put_be16(&slice_sizes, slice_size); buf += slice_size - slice_hdr_size; + if (max_slice_size < slice_size) + max_slice_size = slice_size; } } -- 1.9.2.msysgit.0
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel