summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-09-29 05:42:59 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-09-29 21:50:53 +0200
commit1441641d786a2deecae49c6dc2979af8791ce962 (patch)
tree2055b204e6c36c1b2b9b616026b725f505f4fbd1 /libavcodec
parenta2d5f6b9dbcc81dda68309c96e9c2a227cb37976 (diff)
avcodec/mpegvideo_enc: Allocate only a small buffer and reallocate as needed
This should reduce the memory requirement Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/mpegvideo_enc.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 81298c85b2..045ef3de3b 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1701,7 +1701,11 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
/* output? */
if (s->new_picture.f->data[0]) {
- if ((ret = ff_alloc_packet2(avctx, pkt, s->mb_width*s->mb_height*(MAX_MB_BYTES+100)+10000)) < 0)
+ int growing_buffer = context_count == 1 && !pkt->data && !s->data_partitioning;
+ int pkt_size = growing_buffer ? FFMAX(s->mb_width*s->mb_height*64+10000, avctx->internal->byte_buffer_size) - FF_INPUT_BUFFER_PADDING_SIZE
+ :
+ s->mb_width*s->mb_height*(MAX_MB_BYTES+100)+10000;
+ if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size)) < 0)
return ret;
if (s->mb_info) {
s->mb_info_ptr = av_packet_new_side_data(pkt,
@@ -1726,7 +1730,13 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
if (ret < 0)
return ret;
vbv_retry:
- if (encode_picture(s, s->picture_number) < 0)
+ ret = encode_picture(s, s->picture_number);
+ if (growing_buffer) {
+ av_assert0(s->pb.buf == avctx->internal->byte_buffer);
+ pkt->data = s->pb.buf;
+ pkt->size = avctx->internal->byte_buffer_size;
+ }
+ if (ret < 0)
return -1;
avctx->header_bits = s->header_bits;
@@ -2770,6 +2780,28 @@ static int encode_thread(AVCodecContext *c, void *arg){
int dmin= INT_MAX;
int dir;
+ if ( s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES
+ && s->slice_context_count == 1
+ && s->pb.buf == s->avctx->internal->byte_buffer) {
+ int new_size = s->avctx->internal->byte_buffer_size
+ + s->avctx->internal->byte_buffer_size/4
+ + s->mb_width*MAX_MB_BYTES;
+ int lastgob_pos = s->ptr_lastgob - s->pb.buf;
+ int vbv_pos = s->vbv_delay_ptr - s->pb.buf;
+
+ uint8_t *new_buffer = NULL;
+ int new_buffer_size = 0;
+
+ av_fast_padded_malloc(&new_buffer, &new_buffer_size, new_size);
+ if (new_buffer) {
+ memcpy(new_buffer, s->avctx->internal->byte_buffer, s->avctx->internal->byte_buffer_size);
+ s->avctx->internal->byte_buffer = new_buffer;
+ s->avctx->internal->byte_buffer_size = new_buffer_size;
+ rebase_put_bits(&s->pb, new_buffer, new_buffer_size);
+ s->ptr_lastgob = s->pb.buf + lastgob_pos;
+ s->vbv_delay_ptr = s->pb.buf + vbv_pos;
+ }
+ }
if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){
av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
return -1;