changeset 1684:19e781619e3f libavcodec

stuffing to stay above min_bitrate
author michael
date Fri, 12 Dec 2003 21:30:47 +0000
parents 043b6d933fc6
children cb09cf265a87
files mpegvideo.c mpegvideo.h ratecontrol.c
diffstat 3 files changed, 40 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/mpegvideo.c	Fri Dec 12 19:26:55 2003 +0000
+++ b/mpegvideo.c	Fri Dec 12 21:30:47 2003 +0000
@@ -1715,7 +1715,7 @@
 {
     MpegEncContext *s = avctx->priv_data;
     AVFrame *pic_arg = data;
-    int i;
+    int i, stuffing_count;
 
     if(avctx->pix_fmt != PIX_FMT_YUV420P){
         av_log(avctx, AV_LOG_ERROR, "this codec supports only YUV420P\n");
@@ -1767,11 +1767,35 @@
 
     flush_put_bits(&s->pb);
     s->frame_bits  = (pbBufPtr(&s->pb) - s->pb.buf) * 8;
+
+    stuffing_count= ff_vbv_update(s, s->frame_bits);
+    if(stuffing_count){
+        switch(s->codec_id){
+        case CODEC_ID_MPEG1VIDEO:
+        case CODEC_ID_MPEG2VIDEO:
+            while(stuffing_count--){
+                put_bits(&s->pb, 8, 0);
+            }
+        break;
+        case CODEC_ID_MPEG4:
+            put_bits(&s->pb, 16, 0);
+            put_bits(&s->pb, 16, 0x1C3);
+            stuffing_count -= 4;
+            while(stuffing_count--){
+                put_bits(&s->pb, 8, 0xFF);
+            }
+        break;
+        default:
+            av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n");
+        }
+        flush_put_bits(&s->pb);
+        s->frame_bits  = (pbBufPtr(&s->pb) - s->pb.buf) * 8;
+    }
     
     s->total_bits += s->frame_bits;
     avctx->frame_bits  = s->frame_bits;
     
-    return pbBufPtr(&s->pb) - s->pb.buf;
+    return s->frame_bits/8;
 }
 
 #endif //CONFIG_ENCODERS
--- a/mpegvideo.h	Fri Dec 12 19:26:55 2003 +0000
+++ b/mpegvideo.h	Fri Dec 12 21:30:47 2003 +0000
@@ -897,6 +897,7 @@
                double (**func1)(void *, double), const char **func1_name,
                double (**func2)(void *, double, double), char **func2_name,
                void *opaque);
+int ff_vbv_update(MpegEncContext *s, int frame_size);
 
 
 #endif /* AVCODEC_MPEGVIDEO_H */
--- a/ratecontrol.c	Fri Dec 12 19:26:55 2003 +0000
+++ b/ratecontrol.c	Fri Dec 12 21:30:47 2003 +0000
@@ -195,7 +195,7 @@
     return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ bits;
 }
     
-static void update_rc_buffer(MpegEncContext *s, int frame_size){
+int ff_vbv_update(MpegEncContext *s, int frame_size){
     RateControlContext *rcc= &s->rc_context;
     const double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base;
     const double buffer_size= s->avctx->rc_buffer_size;
@@ -216,10 +216,19 @@
         rcc->buffer_index += clip(left, min_rate, max_rate);
 
         if(rcc->buffer_index > s->avctx->rc_buffer_size){
-            av_log(s->avctx, AV_LOG_ERROR, "rc buffer overflow\n");
-            rcc->buffer_index= s->avctx->rc_buffer_size;
+            int stuffing= ceil((rcc->buffer_index - s->avctx->rc_buffer_size)/8);
+            
+            if(stuffing < 4 && s->codec_id == CODEC_ID_MPEG4)
+                stuffing=4;
+            rcc->buffer_index -= 8*stuffing;
+            
+            if(s->avctx->debug & FF_DEBUG_RC)
+                av_log(s->avctx, AV_LOG_DEBUG, "stuffing %d bytes\n", stuffing);
+
+            return stuffing;
         }
     }
+    return 0;
 }
 
 /**
@@ -619,9 +628,6 @@
         rce->b_code   = s->b_code;
         rce->misc_bits= 1;
 
-        if(picture_number>0)
-            update_rc_buffer(s, s->frame_bits);
-
         bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));
         if(pict_type== I_TYPE){
             rce->i_count   = s->mb_num;
@@ -814,7 +820,7 @@
             rce->new_qscale= modify_qscale(s, rce, blured_qscale[i], i);
             bits= qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
 //printf("%d %f\n", rce->new_bits, blured_qscale[i]);
-            update_rc_buffer(s, bits);
+            bits += 8*ff_vbv_update(s, bits);
 
             rce->expected_bits= expected_bits;
             expected_bits += bits;