My last change of IDR decision broke in 2pass mode. fixed by remembering which frames...
authorLoren Merritt <pengvado@videolan.org>
Thu, 13 Jan 2005 06:11:22 +0000 (06:11 +0000)
committerLoren Merritt <pengvado@videolan.org>
Thu, 13 Jan 2005 06:11:22 +0000 (06:11 +0000)
Disable benchmarking, as it was very slow for some people, and we already know that all the time is spent in macroblock analysis.

git-svn-id: svn://svn.videolan.org/x264/trunk@94 df754926-b1dd-0310-bc7b-ec298dee348c

common/common.h
encoder/encoder.c
encoder/ratecontrol.c

index c7e21cd..93ed97e 100644 (file)
@@ -215,7 +215,7 @@ struct x264_t
         /* frames used for reference +1 for decoding */
         x264_frame_t *reference[16+1];
 
-        int i_last_idr; /* How many frames since last IDR */
+        int i_last_idr; /* Frame number of the last IDR */
 
         int i_input;    /* Number of input frames already accepted */
     } frames;
index 9a0f53b..fe136e8 100644 (file)
 
 //#define DEBUG_MB_TYPE
 //#define DEBUG_DUMP_FRAME
+//#define DEBUG_BENCHMARK
 
+#ifdef DEBUG_BENCHMARK
 static int64_t i_mtime_encode_frame = 0;
-
 static int64_t i_mtime_analyse = 0;
 static int64_t i_mtime_encode = 0;
 static int64_t i_mtime_write = 0;
@@ -51,6 +52,10 @@ static int64_t i_mtime_filter = 0;
 #define TIMER_STOP( d ) \
         d += x264_mdate() - d##start;\
     }
+#else
+#define TIMER_START( d )
+#define TIMER_STOP( d )
+#endif
 
 
 /****************************************************************************
@@ -344,7 +349,7 @@ x264_t *x264_encoder_open   ( x264_param_t *param )
 
     h->param.analyse.i_subpel_refine = x264_clip3( h->param.analyse.i_subpel_refine, 1, 5 );
     if( h->param.analyse.inter & X264_ANALYSE_PSUB8x8 )
-        h->param.analyse.inter &= X264_ANALYSE_PSUB16x16;
+        h->param.analyse.inter |= X264_ANALYSE_PSUB16x16;
 
     if( h->param.rc.f_qblur < 0 )
         h->param.rc.f_qblur = 0;
@@ -427,7 +432,7 @@ x264_t *x264_encoder_open   ( x264_param_t *param )
         /* 2 = 1 backward ref  + 1 fdec */
         h->frames.reference[i] = x264_frame_new( h );
     }
-    h->frames.i_last_idr = h->param.i_keyint_max;
+    h->frames.i_last_idr = h->param.i_keyint_max;
     h->frames.i_input    = 0;
 
     h->i_ref0 = 0;
@@ -955,15 +960,15 @@ int     x264_encoder_encode( x264_t *h,
             frm = h->frames.next[bframes];
 
             /* Limit GOP size */
-            if( ( h->frames.i_last_idr + bframes + 1 >= h->param.i_keyint_min
-                  && frm->i_type == X264_TYPE_I )
-               || h->frames.i_last_idr + bframes + 1 >= h->param.i_keyint_max )
+            if( frm->i_frame - h->frames.i_last_idr >= h->param.i_keyint_max )
+            {
+                if( frm->i_type == X264_TYPE_AUTO )
+                    frm->i_type = X264_TYPE_IDR;
+                if( frm->i_type != X264_TYPE_IDR )
+                    x264_log( h, X264_LOG_ERROR, "specified frame type (%d) is not compatible with keyframe interval\n", frm->i_type );
+            }
+            if( frm->i_type == X264_TYPE_IDR )
             {
-                if(    frm->i_type == X264_TYPE_P
-                    || frm->i_type == X264_TYPE_B )
-                    x264_log( h, X264_LOG_ERROR, "specified frame type is not compatible with keyframe interval\n" );
-
-                frm->i_type = X264_TYPE_IDR;
                 h->i_poc = 0;
                 h->i_frame_num = 0;
 
@@ -1017,11 +1022,7 @@ do_encode:
 
     if( h->fenc->i_type == X264_TYPE_IDR )
     {
-        h->frames.i_last_idr = 0;
-    }
-    else
-    {
-        h->frames.i_last_idr++;
+        h->frames.i_last_idr = h->fenc->i_frame;
     }
 
     /* ------------------- Setup frame context ----------------------------- */
@@ -1126,21 +1127,22 @@ do_encode:
         if( h->param.i_keyint_min == h->param.i_keyint_max )
              f_thresh_min= f_thresh_max;
         float f_bias;
+        int i_gop_size = h->fenc->i_frame - h->frames.i_last_idr;
 
         /* macroblock_analyse() doesn't further analyse skipped mbs,
          * so we have to guess their cost */
         if( i_mb_s < i_mb )
             i_intra_cost = i_intra_cost * i_mb / (i_mb - i_mb_s);
 
-        if( h->frames.i_last_idr < h->param.i_keyint_min / 4 )
+        if( i_gop_size < h->param.i_keyint_min / 4 )
             f_bias = f_thresh_min / 4;
-        else if( h->frames.i_last_idr <= h->param.i_keyint_min )
-            f_bias = f_thresh_min * h->frames.i_last_idr / h->param.i_keyint_min;
+        else if( i_gop_size <= h->param.i_keyint_min )
+            f_bias = f_thresh_min * i_gop_size / h->param.i_keyint_min;
         else
         {
             f_bias = f_thresh_min
                      + ( f_thresh_max - f_thresh_min )
-                       * ( h->frames.i_last_idr - h->param.i_keyint_min )
+                       * ( i_gop_size - h->param.i_keyint_min )
                        / ( h->param.i_keyint_max - h->param.i_keyint_min );
         }
         f_bias = X264_MIN( f_bias, 1.0 );
@@ -1157,12 +1159,12 @@ do_encode:
             h->frames.i_last_i > 4)*/
         {
 
-            x264_log( h, X264_LOG_DEBUG, "scene cut at %d size=%d I_cost:%lld P_cost:%lld ratio:%.3f bias=%.3f last_IDR:%d (I:%d P:%d Skip:%d)\n",
+            x264_log( h, X264_LOG_DEBUG, "scene cut at %d size=%d Icost:%lld Pcost:%lld ratio:%.3f bias=%.3f lastIDR:%d (I:%d P:%d Skip:%d)\n",
                       h->fenc->i_frame,
                       h->out.nal[h->out.i_nal-1].i_payload,
                       i_intra_cost, i_inter_cost,
                       (float)i_inter_cost / i_intra_cost,
-                      f_bias, h->frames.i_last_idr,
+                      f_bias, i_gop_size,
                       i_mb_i, i_mb_p, i_mb_s );
 
             /* Restore frame num */
@@ -1185,7 +1187,7 @@ do_encode:
                 h->fenc->i_type = X264_TYPE_P;
             }
             /* Do IDR if needed */
-            else if( h->frames.i_last_idr + 1 >= h->param.i_keyint_min )
+            else if( i_gop_size >= h->param.i_keyint_min )
             {
                 x264_frame_t *tmp;
 
@@ -1351,16 +1353,20 @@ do_encode:
  ****************************************************************************/
 void    x264_encoder_close  ( x264_t *h )
 {
+#ifdef DEBUG_BENCHMARK
     int64_t i_mtime_total = i_mtime_analyse + i_mtime_encode + i_mtime_write + i_mtime_filter + 1;
+#endif
     int64_t i_yuv_size = 3 * h->param.i_width * h->param.i_height / 2;
     int i;
 
+#ifdef DEBUG_BENCHMARK
     x264_log( h, X264_LOG_INFO,
               "analyse=%d(%lldms) encode=%d(%lldms) write=%d(%lldms) filter=%d(%lldms)\n",
               (int)(100*i_mtime_analyse/i_mtime_total), i_mtime_analyse/1000,
               (int)(100*i_mtime_encode/i_mtime_total), i_mtime_encode/1000,
               (int)(100*i_mtime_write/i_mtime_total), i_mtime_write/1000,
               (int)(100*i_mtime_filter/i_mtime_total), i_mtime_filter/1000 );
+#endif
 
     /* Slices used and PSNR */
     for( i=0; i<5; i++ )
@@ -1443,7 +1449,7 @@ void    x264_encoder_close  ( x264_t *h )
 
         if( h->param.analyse.b_psnr )
             x264_log( h, X264_LOG_INFO,
-                      "PSNR Mean Y:%5.2f U:%5.2f V:%5.2f Avg:%5.2f Global:%5.2f kb/s:%.1f fps:%.3f\n",
+                      "PSNR Mean Y:%5.2f U:%5.2f V:%5.2f Avg:%5.2f Global:%5.2f kb/s:%.1f\n",
                       (h->stat.f_psnr_mean_y[SLICE_TYPE_I] + h->stat.f_psnr_mean_y[SLICE_TYPE_P] + h->stat.f_psnr_mean_y[SLICE_TYPE_B]) / i_count,
                       (h->stat.f_psnr_mean_u[SLICE_TYPE_I] + h->stat.f_psnr_mean_u[SLICE_TYPE_P] + h->stat.f_psnr_mean_u[SLICE_TYPE_B]) / i_count,
                       (h->stat.f_psnr_mean_v[SLICE_TYPE_I] + h->stat.f_psnr_mean_v[SLICE_TYPE_P] + h->stat.f_psnr_mean_v[SLICE_TYPE_B]) / i_count,
@@ -1452,13 +1458,11 @@ void    x264_encoder_close  ( x264_t *h )
 
                       x264_psnr( h->stat.i_sqe_global[SLICE_TYPE_I] + h->stat.i_sqe_global[SLICE_TYPE_P]+ h->stat.i_sqe_global[SLICE_TYPE_B],
                                  i_count * i_yuv_size ),
-                      fps * 8*(h->stat.i_slice_size[SLICE_TYPE_I]+h->stat.i_slice_size[SLICE_TYPE_P]+h->stat.i_slice_size[SLICE_TYPE_B]) / i_count / 1000,
-                      (double)1000000.0 * (double)i_count / (double)i_mtime_encode_frame );
+                      fps * 8*(h->stat.i_slice_size[SLICE_TYPE_I]+h->stat.i_slice_size[SLICE_TYPE_P]+h->stat.i_slice_size[SLICE_TYPE_B]) / i_count / 1000 );
         else
             x264_log( h, X264_LOG_INFO,
-                      "kb/s:%.1f fps:%.3f\n",
-                      fps * 8*(h->stat.i_slice_size[SLICE_TYPE_I]+h->stat.i_slice_size[SLICE_TYPE_P]+h->stat.i_slice_size[SLICE_TYPE_B]) / i_count / 1000,
-                      (double)1000000.0 * (double)i_count / (double)i_mtime_encode_frame );
+                      "kb/s:%.1f\n",
+                      fps * 8*(h->stat.i_slice_size[SLICE_TYPE_I]+h->stat.i_slice_size[SLICE_TYPE_P]+h->stat.i_slice_size[SLICE_TYPE_B]) / i_count / 1000 );
     }
 
     /* frames */
index 8f810f4..838e152 100644 (file)
 typedef struct
 {
     int pict_type;
+    int idr;
     float qscale;
     int mv_bits;
     int i_tex_bits;
     int p_tex_bits;
     int misc_bits;
     uint64_t expected_bits;
-    int new_pict_type;
     float new_qscale;
     int new_qp;
     int i_count;
@@ -268,7 +268,7 @@ int x264_ratecontrol_new( x264_t *h )
         /* init all to skipped p frames */
         for(i=0; i<rc->num_entries; i++){
             ratecontrol_entry_t *rce = &rc->entry[i];
-            rce->pict_type = rce->new_pict_type = SLICE_TYPE_P;
+            rce->pict_type = SLICE_TYPE_P;
             rce->qscale = rce->new_qscale = qp2qscale(20);
             rce->misc_bits = rc->nmb + 10;
             rce->new_qp = 0;
@@ -278,7 +278,8 @@ int x264_ratecontrol_new( x264_t *h )
         p = stats_in;
         for(i=0; i < rc->num_entries - h->param.i_bframe; i++){
             ratecontrol_entry_t *rce;
-            int picture_number;
+            int frame_number;
+            char pict_type;
             int e;
             char *next;
             float qp;
@@ -288,15 +289,23 @@ int x264_ratecontrol_new( x264_t *h )
                 (*next)=0; //sscanf is unbelievably slow on looong strings
                 next++;
             }
-            e = sscanf(p, " in:%d ", &picture_number);
+            e = sscanf(p, " in:%d ", &frame_number);
 
-            assert(picture_number >= 0);
-            assert(picture_number < rc->num_entries);
-            rce = &rc->entry[picture_number];
+            assert(frame_number >= 0);
+            assert(frame_number < rc->num_entries);
+            rce = &rc->entry[frame_number];
 
-            e += sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d imb:%d pmb:%d smb:%d",
-                   &rce->pict_type, &qp, &rce->i_tex_bits, &rce->p_tex_bits,
+            e += sscanf(p, " in:%*d out:%*d type:%c q:%f itex:%d ptex:%d mv:%d misc:%d imb:%d pmb:%d smb:%d",
+                   &pict_type, &qp, &rce->i_tex_bits, &rce->p_tex_bits,
                    &rce->mv_bits, &rce->misc_bits, &rce->i_count, &rce->p_count, &rce->s_count);
+
+            switch(pict_type){
+                case 'I': rce->idr = 1;
+                case 'i': rce->pict_type = SLICE_TYPE_I; break;
+                case 'P': rce->pict_type = SLICE_TYPE_P; break;
+                case 'B': rce->pict_type = SLICE_TYPE_B; break;
+                default:  e = -1; break;
+            }
             if(e != 10){
                 x264_log(h, X264_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e);
                 return -1;
@@ -358,9 +367,9 @@ void x264_ratecontrol_start( x264_t *h, int i_slice_type )
     else if( h->param.rc.b_stat_read )
     {
         int frame = h->fenc->i_frame;
-        ratecontrol_entry_t *rce = &h->rc->entry[frame];
-
+        ratecontrol_entry_t *rce;
         assert( frame >= 0 && frame < rc->num_entries );
+        rce = &h->rc->entry[frame];
 
         rce->new_qscale = rate_estimate_qscale( h, i_slice_type );
         rc->qpm = rc->qpa = rc->qp = rce->new_qp =
@@ -538,10 +547,10 @@ int x264_ratecontrol_slice_type( x264_t *h, int frame_num )
             x264_log(h, X264_LOG_ERROR, "More input frames than in the 1st pass\n");
             return X264_TYPE_P;
         }
-        switch( h->rc->entry[frame_num].new_pict_type )
+        switch( h->rc->entry[frame_num].pict_type )
         {
             case SLICE_TYPE_I:
-                return X264_TYPE_I;
+                return h->rc->entry[frame_num].idr ? X264_TYPE_IDR : X264_TYPE_I;
 
             case SLICE_TYPE_B:
                 return X264_TYPE_B;
@@ -571,10 +580,12 @@ void x264_ratecontrol_end( x264_t *h, int bits )
 
     if( h->param.rc.b_stat_write )
     {
+        char c_type = rc->slice_type==SLICE_TYPE_I ? (h->fenc->i_poc==0 ? 'I' : 'i')
+                    : rc->slice_type==SLICE_TYPE_P ? 'P' : 'B';
         fprintf( rc->p_stat_file_out,
-                 "in:%d out:%d type:%d q:%.3f itex:%d ptex:%d mv:%d misc:%d imb:%d pmb:%d smb:%d;\n",
+                 "in:%d out:%d type:%c q:%.3f itex:%d ptex:%d mv:%d misc:%d imb:%d pmb:%d smb:%d;\n",
                  h->fenc->i_frame, h->i_frame-1,
-                 rc->slice_type, rc->qpa,
+                 c_type, rc->qpa,
                  h->stat.frame.i_itex_bits, h->stat.frame.i_ptex_bits,
                  h->stat.frame.i_hdr_bits, h->stat.frame.i_misc_bits,
                  h->stat.frame.i_mb_count[I_4x4] + h->stat.frame.i_mb_count[I_16x16],
@@ -631,7 +642,7 @@ static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor
 {
     x264_ratecontrol_t *rcc= h->rc;
     double bits;
-    const int pict_type = rce->new_pict_type;
+    const int pict_type = rce->pict_type;
 
     double const_values[]={
         rce->i_tex_bits * rce->qscale,
@@ -700,7 +711,7 @@ static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor
 static double get_diff_limited_q(x264_t *h, ratecontrol_entry_t *rce, double q)
 {
     x264_ratecontrol_t *rcc = h->rc;
-    const int pict_type = rce->new_pict_type;
+    const int pict_type = rce->pict_type;
 
     // force I/B quants as a function of P quants
     const double last_p_q    = rcc->last_qscale_for[SLICE_TYPE_P];
@@ -755,8 +766,8 @@ static double get_diff_limited_q(x264_t *h, ratecontrol_entry_t *rce, double q)
 // clip a qscale to between lmin and lmax
 static double clip_qscale( x264_t *h, ratecontrol_entry_t *rce, double q )
 {
-    double lmin = h->rc->lmin[rce->new_pict_type];
-    double lmax = h->rc->lmax[rce->new_pict_type];
+    double lmin = h->rc->lmin[rce->pict_type];
+    double lmax = h->rc->lmax[rce->pict_type];
 
     if(lmin==lmax){
         return lmin;
@@ -789,7 +800,7 @@ static float rate_estimate_qscale(x264_t *h, int pict_type)
 
     rce = &rcc->entry[picture_number];
 
-    assert(pict_type == rce->new_pict_type);
+    assert(pict_type == rce->pict_type);
 
     if(rce->pict_type == SLICE_TYPE_B)
     {
@@ -824,12 +835,11 @@ static int init_pass2( x264_t *h )
     /* find total/average complexity & const_bits */
     for(i=0; i<rcc->num_entries; i++){
         ratecontrol_entry_t *rce = &rcc->entry[i];
-        rce->new_pict_type = rce->pict_type;
         all_const_bits += rce->mv_bits + rce->misc_bits;
-        rcc->i_cplx_sum[rce->new_pict_type] += rce->i_tex_bits * rce->qscale;
-        rcc->p_cplx_sum[rce->new_pict_type] += rce->p_tex_bits * rce->qscale;
-        rcc->mv_bits_sum[rce->new_pict_type] += rce->mv_bits;
-        rcc->frame_count[rce->new_pict_type] ++;
+        rcc->i_cplx_sum[rce->pict_type] += rce->i_tex_bits * rce->qscale;
+        rcc->p_cplx_sum[rce->pict_type] += rce->p_tex_bits * rce->qscale;
+        rcc->mv_bits_sum[rce->pict_type] += rce->mv_bits;
+        rcc->frame_count[rce->pict_type] ++;
     }
 
     if( all_available_bits < all_const_bits)
@@ -899,7 +909,6 @@ static int init_pass2( x264_t *h )
             assert(filter_size%2==1);
             for(i=0; i<rcc->num_entries; i++){
                 ratecontrol_entry_t *rce = &rcc->entry[i];
-                const int pict_type = rce->new_pict_type;
                 int j;
                 double q=0.0, sum=0.0;
 
@@ -908,7 +917,7 @@ static int init_pass2( x264_t *h )
                     double d = index-i;
                     double coeff = qblur==0 ? 1.0 : exp(-d*d/(qblur*qblur));
                     if(index < 0 || index >= rcc->num_entries) continue;
-                    if(pict_type != rcc->entry[index].new_pict_type) continue;
+                    if(rce->pict_type != rcc->entry[index].pict_type) continue;
                     q += qscale[index] * coeff;
                     sum += coeff;
                 }