2014-08-12 7:56 GMT+02:00 Christophe Gisquet <christophe.gisq...@gmail.com>:
> Yeah, you're right. I have no idea how big a slice can be, as that
> seems the extra size check here. How about FF_MIN_BUFFER_SIZE ?
> Then the growth would be FFMAX(FF_MIN_BUFFER_SIZE, buf - orig_buf) ?

Here's a patch for that, and moving the warn variable to the context.
From b3543b1a9c535299b445cb0e4f86f86cc1b0419f 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 | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
index a70ae3c..19eb13d 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;
@@ -1023,6 +1024,31 @@ 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 + FF_MIN_BUFFER_SIZE) {
+                    uint8_t *start = pkt->data;
+                    // double the size
+                    int delta = FFMAX(FF_MIN_BUFFER_SIZE, buf - orig_buf);
+
+                    if (!ctx->warn) {
+                        avpriv_request_sample(avctx,
+                                              "Packet too small (%i/%i)",
+                                              pkt_size, delta);
+                        ctx->warn = 1;
+                    }
+                    ctx->frame_size_upper_bound += delta;
+                    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)
-- 
1.9.2.msysgit.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to