Hi,
2014-08-12 12:26 GMT+02:00 Michael Niedermayer <[email protected]>:
> On Tue, Aug 12, 2014 at 11:56:21AM +0200, Christophe Gisquet wrote:
>> Hi,
>>
>> 2014-08-12 10:19 GMT+02:00 Michael Niedermayer <[email protected]>:
>> > 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 <[email protected]>
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
[email protected]
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel