]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/ratecontrol.c
moved the tables into header files (and applied the 'static' patch). Nick: why do...
[ffmpeg] / libavcodec / ratecontrol.c
index e4f2340c745b9750b04f2be4f74f4d8eb08b875a..80f65d9242fa9f630f242bafe7c547277e8bcce3 100644 (file)
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <math.h>
-#include "common.h"
+
+/**
+ * @file ratecontrol.c
+ * Rate control for video encoders.
+ */ 
+
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
 #undef NDEBUG // allways check asserts, the speed effect is far too small to disable them
 #include <assert.h>
 
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
 #ifndef M_E
 #define M_E 2.718281828
 #endif
@@ -164,7 +164,7 @@ int ff_rate_control_init(MpegEncContext *s)
                 bits= rce.i_tex_bits + rce.p_tex_bits;
 
                 q= get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i);
-                rcc->pass1_wanted_bits+= s->bit_rate/(s->frame_rate / (double)FRAME_RATE_BASE);
+                rcc->pass1_wanted_bits+= s->bit_rate/(s->avctx->frame_rate / (double)s->avctx->frame_rate_base);
             }
         }
 
@@ -197,7 +197,7 @@ static inline double bits2qp(RateControlEntry *rce, double bits){
     
 static void update_rc_buffer(MpegEncContext *s, int frame_size){
     RateControlContext *rcc= &s->rc_context;
-    const double fps= (double)s->frame_rate / FRAME_RATE_BASE;
+    const double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base;
     const double buffer_size= s->avctx->rc_buffer_size;
     const double min_rate= s->avctx->rc_min_rate/fps;
     const double max_rate= s->avctx->rc_max_rate/fps;
@@ -256,7 +256,7 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_f
         (rcc->i_cplx_sum[pict_type] + rcc->p_cplx_sum[pict_type]) / (double)rcc->frame_count[pict_type],
         0
     };
-    char *const_names[]={
+    static const char *const_names[]={
         "PI",
         "E",
         "iTex",
@@ -288,7 +288,7 @@ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_f
         (void *)qp2bits,
         NULL
     };
-    char *func1_names[]={
+    static const char *func1_names[]={
         "bits2qp",
         "qp2bits",
         NULL
@@ -330,7 +330,7 @@ static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, doubl
     const int pict_type= rce->new_pict_type;
     const double last_p_q    = rcc->last_qscale_for[P_TYPE];
     const double last_non_b_q= rcc->last_qscale_for[rcc->last_non_b_pict_type];
-
+    
     if     (pict_type==I_TYPE && (a->i_quant_factor>0.0 || rcc->last_non_b_pict_type==P_TYPE))
         q= last_p_q    *ABS(a->i_quant_factor) + a->i_quant_offset;
     else if(pict_type==B_TYPE && a->b_quant_factor>0.0)
@@ -339,6 +339,7 @@ static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, doubl
     /* last qscale / qdiff stuff */
     if(rcc->last_non_b_pict_type==pict_type || pict_type!=I_TYPE){
         double last_q= rcc->last_qscale_for[pict_type];
+
         if     (q > last_q + a->max_qdiff) q= last_q + a->max_qdiff;
         else if(q < last_q - a->max_qdiff) q= last_q - a->max_qdiff;
     }
@@ -355,8 +356,8 @@ static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, doubl
  * gets the qmin & qmax for pict_type
  */
 static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type){
-    int qmin= s->qmin;                                                       
-    int qmax= s->qmax;
+    int qmin= s->avctx->qmin;                                                       
+    int qmax= s->avctx->qmax;
 
     if(pict_type==B_TYPE){
         qmin= (int)(qmin*ABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5);
@@ -367,7 +368,7 @@ static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pic
     }
 
     if(qmin<1) qmin=1;
-    if(qmin==1 && s->qmin>1) qmin=2; //avoid qmin=1 unless the user wants qmin=1
+    if(qmin==1 && s->avctx->qmin>1) qmin=2; //avoid qmin=1 unless the user wants qmin=1
 
     if(qmin<3 && s->max_qcoeff<=128 && pict_type==I_TYPE) qmin=3; //reduce cliping problems
 
@@ -445,11 +446,13 @@ static double predict_size(Predictor *p, double q, double var)
      return p->coeff*var / (q*p->count);
 }
 
+/*
 static double predict_qp(Predictor *p, double size, double var)
 {
 //printf("coeff:%f, count:%f, var:%f, size:%f//\n", p->coeff, p->count, var, size);
      return p->coeff*var / (size*p->count);
 }
+*/
 
 static void update_predictor(Predictor *p, double q, double var, double size)
 {
@@ -473,20 +476,22 @@ static void adaptive_quantization(MpegEncContext *s, double q){
     float cplx_sum= 0.0;
     float cplx_tab[s->mb_num];
     float bits_tab[s->mb_num];
-    const int qmin= 2; //s->avctx->mb_qmin;
-    const int qmax= 31; //s->avctx->mb_qmax;
+    const int qmin= s->avctx->mb_qmin;
+    const int qmax= s->avctx->mb_qmax;
     Picture * const pic= &s->current_picture;
+    int last_qscale=0;
     
     for(i=0; i<s->mb_num; i++){
-        float temp_cplx= sqrt(pic->mc_mb_var[i]);
-        float spat_cplx= sqrt(pic->mb_var[i]);
-        const int lumi= pic->mb_mean[i];
+        const int mb_xy= s->mb_index2xy[i];
+        float temp_cplx= sqrt(pic->mc_mb_var[mb_xy]);
+        float spat_cplx= sqrt(pic->mb_var[mb_xy]);
+        const int lumi= pic->mb_mean[mb_xy];
         float bits, cplx, factor;
         
         if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune
         if(temp_cplx < q/3) temp_cplx= q/3; //FIXME finetune
         
-        if((s->mb_type[i]&MB_TYPE_INTRA)){//FIXME hq mode 
+        if((s->mb_type[mb_xy]&MB_TYPE_INTRA)){//FIXME hq mode 
             cplx= spat_cplx;
             factor= 1.0 + p_masking;
         }else{
@@ -527,6 +532,7 @@ static void adaptive_quantization(MpegEncContext *s, double q){
     }
    
     for(i=0; i<s->mb_num; i++){
+        const int mb_xy= s->mb_index2xy[i];
         float newq= q*cplx_tab[i]/bits_tab[i];
         int intq;
 
@@ -534,8 +540,8 @@ static void adaptive_quantization(MpegEncContext *s, double q){
             newq*= bits_sum/cplx_sum;
         }
 
-        if(i && ABS(pic->qscale_table[i-1] - newq)<0.75)
-            intq= pic->qscale_table[i-1];
+        if(i && ABS(last_qscale - newq)<0.75)
+            intq= last_qscale;
         else
             intq= (int)(newq + 0.5);
 
@@ -543,7 +549,8 @@ static void adaptive_quantization(MpegEncContext *s, double q){
         else if(intq < qmin) intq= qmin;
 //if(i%s->mb_width==0) printf("\n");
 //printf("%2d%3d ", intq, ff_sqrt(s->mc_mb_var[i]));
-        pic->qscale_table[i]= intq;
+        last_qscale=
+        pic->qscale_table[mb_xy]= intq;
     }
 }
 
@@ -568,7 +575,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s)
 
     get_qminmax(&qmin, &qmax, s, pict_type);
 
-    fps= (double)s->frame_rate / FRAME_RATE_BASE;
+    fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base;
 //printf("input_pic_num:%d pic_num:%d frame_rate:%d\n", s->input_picture_number, s->picture_number, s->frame_rate);
         /* update predictors */
     if(picture_number>2){
@@ -658,17 +665,16 @@ float ff_rate_estimate_qscale(MpegEncContext *s)
 
         assert(q>0.0);
     }
-//printf("qmin:%d, qmax:%d, q:%f\n", qmin, qmax, q);
-    
+
+    if(s->avctx->debug&FF_DEBUG_RC){
+        printf("%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f size:%d var:%d/%d br:%d fps:%d\n",
+        av_get_pict_type_char(pict_type), qmin, q, qmax, picture_number, (int)wanted_bits/1000, (int)s->total_bits/1000,
+        br_compensation, short_term_q, s->frame_bits, pic->mb_var_sum, pic->mc_mb_var_sum, s->bit_rate/1000, (int)fps
+        );
+    }
 
     if     (q<qmin) q=qmin; 
     else if(q>qmax) q=qmax;
-        
-//    printf("%f %d %d %d\n", q, picture_number, (int)wanted_bits, (int)s->total_bits);
-       
-//printf("diff:%d comp:%f st_q:%f last_size:%d type:%d\n", (int)diff, br_compensation, 
-//       short_term_q, s->frame_bits, pict_type);
-//printf("%d %d\n", s->bit_rate, (int)fps);
 
     if(s->adaptive_quant)
         adaptive_quantization(s, q);
@@ -696,7 +702,7 @@ static int init_pass2(MpegEncContext *s)
 {
     RateControlContext *rcc= &s->rc_context;
     int i;
-    double fps= (double)s->frame_rate / FRAME_RATE_BASE;
+    double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base;
     double complexity[5]={0,0,0,0,0};   // aproximate bits at quant=1
     double avg_quantizer[5];
     uint64_t const_bits[5]={0,0,0,0,0}; // quantizer idependant bits
@@ -705,7 +711,7 @@ static int init_pass2(MpegEncContext *s)
     uint64_t all_available_bits= (uint64_t)(s->bit_rate*(double)rcc->num_entries/fps);
     double rate_factor=0;
     double step;
-    int last_i_frame=-10000000;
+    //int last_i_frame=-10000000;
     const int filter_size= (int)(s->qblur*4) | 1;  
     double expected_bits;
     double *qscale, *blured_qscale;
@@ -755,8 +761,8 @@ static int init_pass2(MpegEncContext *s)
     }
 //printf("%lld %lld %lld %lld\n", available_bits[I_TYPE], available_bits[P_TYPE], available_bits[B_TYPE], all_available_bits);
         
-    qscale= malloc(sizeof(double)*rcc->num_entries);
-    blured_qscale= malloc(sizeof(double)*rcc->num_entries);
+    qscale= av_malloc(sizeof(double)*rcc->num_entries);
+    blured_qscale= av_malloc(sizeof(double)*rcc->num_entries);
 
     for(step=256*256; step>0.0000001; step*=0.5){
         expected_bits=0;
@@ -813,8 +819,8 @@ static int init_pass2(MpegEncContext *s)
 //        printf("%f %d %f\n", expected_bits, (int)all_available_bits, rate_factor);
         if(expected_bits > all_available_bits) rate_factor-= step;
     }
-    free(qscale);
-    free(blured_qscale);
+    av_free(qscale);
+    av_free(blured_qscale);
 
     if(abs(expected_bits/all_available_bits - 1.0) > 0.01 ){
         fprintf(stderr, "Error: 2pass curve failed to converge\n");