]> git.sesse.net Git - x264/blobdiff - encoder/ratecontrol.c
Fix crash with VBV + forced QP
[x264] / encoder / ratecontrol.c
index 2faee25f2ab751d49067ecad15291023e6ca4ae3..43763c3db9554e2fcde283a1f68bf055158bdcde 100644 (file)
@@ -257,8 +257,8 @@ static NOINLINE uint32_t x264_ac_energy_mb( x264_t *h, int mb_x, int mb_y, x264_
     }
     else
     {
-        var  = ac_energy_plane( h, mb_x, mb_y, frame, 0, h->param.b_interlaced, 1 );
-        var += ac_energy_plane( h, mb_x, mb_y, frame, 1, h->param.b_interlaced, 1 );
+        var  = ac_energy_plane( h, mb_x, mb_y, frame, 0, PARAM_INTERLACED, 1 );
+        var += ac_energy_plane( h, mb_x, mb_y, frame, 1, PARAM_INTERLACED, 1 );
     }
     x264_emms();
     return var;
@@ -1256,11 +1256,7 @@ void x264_ratecontrol_start( x264_t *h, int i_force_qp, int overhead )
     if( h->sh.i_type != SLICE_TYPE_B )
         rc->bframes = h->fenc->i_bframes;
 
-    if( i_force_qp != X264_QP_AUTO )
-    {
-        q = i_force_qp - 1;
-    }
-    else if( rc->b_abr )
+    if( rc->b_abr )
     {
         q = qscale2qp( rate_estimate_qscale( h ) );
     }
@@ -1284,6 +1280,8 @@ void x264_ratecontrol_start( x264_t *h, int i_force_qp, int overhead )
                 q -= 6*log2f( zone->f_bitrate_factor );
         }
     }
+    if( i_force_qp != X264_QP_AUTO )
+        q = i_force_qp - 1;
 
     q = x264_clip3f( q, h->param.rc.i_qp_min, h->param.rc.i_qp_max );
 
@@ -1335,7 +1333,7 @@ static double predict_row_size( x264_t *h, int y, double qp )
 static double row_bits_so_far( x264_t *h, int y )
 {
     double bits = 0;
-    for( int i = h->i_threadslice_start; i <= y; i++ )
+    for( int i = h->i_threadslice_start+SLICE_MBAFF; i <= y; i+=(SLICE_MBAFF+1) )
         bits += h->fdec->i_row_bits[i];
     return bits;
 }
@@ -1343,7 +1341,7 @@ static double row_bits_so_far( x264_t *h, int y )
 static double predict_row_size_sum( x264_t *h, int y, double qp )
 {
     double bits = row_bits_so_far(h, y);
-    for( int i = y+1; i < h->i_threadslice_end; i++ )
+    for( int i = y+1+SLICE_MBAFF; i < h->i_threadslice_end; i+=(1+SLICE_MBAFF) )
         bits += predict_row_size( h, i, qp );
     return bits;
 }
@@ -1357,8 +1355,16 @@ void x264_ratecontrol_mb( x264_t *h, int bits )
     x264_emms();
 
     h->fdec->i_row_bits[y] += bits;
-    rc->qpa_rc += rc->qpm;
-    rc->qpa_aq += h->mb.i_qp;
+    if( SLICE_MBAFF )
+    {
+        rc->qpa_rc += rc->qpm*2.0f;
+        rc->qpa_aq += h->mb.i_qp + h->mb.i_last_qp;
+    }
+    else
+    {
+        rc->qpa_rc += rc->qpm;
+        rc->qpa_aq += h->mb.i_qp;
+    }
 
     if( h->mb.i_mb_x != h->mb.i_mb_width - 1 || !rc->b_vbv )
         return;
@@ -1383,7 +1389,7 @@ void x264_ratecontrol_mb( x264_t *h, int bits )
         /* B-frames shouldn't use lower QP than their reference frames. */
         if( h->sh.i_type == SLICE_TYPE_B )
         {
-            qp_min = X264_MAX( qp_min, X264_MAX( h->fref[0][0]->f_row_qp[y+1], h->fref[1][0]->f_row_qp[y+1] ) );
+            qp_min = X264_MAX( qp_min, X264_MAX( h->fref[0][0]->f_row_qp[y+1+SLICE_MBAFF], h->fref[1][0]->f_row_qp[y+1+SLICE_MBAFF] ) );
             rc->qpm = X264_MAX( rc->qpm, qp_min );
         }
 
@@ -1577,7 +1583,7 @@ int x264_ratecontrol_end( x264_t *h, int bits, int *filler )
         for( int i = 0; i < (use_old_stats ? rc->rce->refs : h->i_ref[0]); i++ )
         {
             int refcount = use_old_stats         ? rc->rce->refcount[i]
-                         : h->param.b_interlaced ? h->stat.frame.i_mb_count_ref[0][i*2]
+                         : PARAM_INTERLACED      ? h->stat.frame.i_mb_count_ref[0][i*2]
                                                  + h->stat.frame.i_mb_count_ref[0][i*2+1]
                          :                         h->stat.frame.i_mb_count_ref[0][i];
             if( fprintf( rc->p_stat_file_out, "%d ", refcount ) < 0 )
@@ -2121,6 +2127,9 @@ static float rate_estimate_qscale( x264_t *h )
             rcc->frame_size_planned = qscale2bits( &rce, qp2qscale( q ) );
         else
             rcc->frame_size_planned = predict_size( rcc->pred_b_from_p, qp2qscale( q ), h->fref[1][h->i_ref[1]-1]->i_satd );
+        /* Limit planned size by MinCR */
+        if( rcc->b_vbv )
+            rcc->frame_size_planned = X264_MIN( rcc->frame_size_planned, rcc->frame_size_maximum );
         h->rc->frame_size_estimated = rcc->frame_size_planned;
 
         /* For row SATDs */
@@ -2312,6 +2321,9 @@ static float rate_estimate_qscale( x264_t *h )
         /* Always use up the whole VBV in this case. */
         if( rcc->single_frame_vbv )
             rcc->frame_size_planned = rcc->buffer_rate;
+        /* Limit planned size by MinCR */
+        if( rcc->b_vbv )
+            rcc->frame_size_planned = X264_MIN( rcc->frame_size_planned, rcc->frame_size_maximum );
         h->rc->frame_size_estimated = rcc->frame_size_planned;
         return q;
     }