[FFmpeg-cvslog] avcodec/mpegvideo_enc: Allocate only a small buffer and reallocate as needed

Michael Niedermayer git at videolan.org
Mon Sep 29 22:08:43 CEST 2014


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Mon Sep 29 05:42:59 2014 +0200| [1441641d786a2deecae49c6dc2979af8791ce962] | committer: Michael Niedermayer

avcodec/mpegvideo_enc: Allocate only a small buffer and reallocate as needed

This should reduce the memory requirement

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1441641d786a2deecae49c6dc2979af8791ce962
---

 libavcodec/mpegvideo_enc.c |   36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 81298c8..045ef3d 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;



More information about the ffmpeg-cvslog mailing list