diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-08-18 20:20:12 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-08-18 20:21:02 +0200 |
commit | e348a81a66851e35b9f6facf70c678e886bd3805 (patch) | |
tree | 2e7e193d347ef3c353a3c727521bfb0f3a279d85 /libavcodec/proresenc_kostya.c | |
parent | e8a2f8cc1209e836bbf7bd42d1087d3154903555 (diff) | |
parent | 45ce880a9b3e50cfa088f111dffaf8685bd7bc6b (diff) | |
download | ffmpeg-e348a81a66851e35b9f6facf70c678e886bd3805.tar.gz |
Merge commit '45ce880a9b3e50cfa088f111dffaf8685bd7bc6b'
* commit '45ce880a9b3e50cfa088f111dffaf8685bd7bc6b':
proresenc: Realloc if buffer is too small
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/proresenc_kostya.c')
-rw-r--r-- | libavcodec/proresenc_kostya.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c index 834698d8ed..90f08351a3 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; @@ -937,7 +938,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; @@ -1022,6 +1023,39 @@ 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, max_slice_size); + ctx->warn = 1; + } + + ret = av_grow_packet(pkt, delta); + if (ret < 0) + return ret; + + 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); @@ -1036,6 +1070,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; } } |