api change: select ratecontrol method with an enum (param.rc.i_rc_method) instead...
authorLoren Merritt <pengvado@videolan.org>
Tue, 18 Jul 2006 01:10:54 +0000 (01:10 +0000)
committerLoren Merritt <pengvado@videolan.org>
Tue, 18 Jul 2006 01:10:54 +0000 (01:10 +0000)
git-svn-id: svn://svn.videolan.org/x264/trunk@537 df754926-b1dd-0310-bc7b-ec298dee348c

common/common.c
encoder/analyse.c
encoder/encoder.c
encoder/ratecontrol.c
encoder/set.c
vfw/codec.c
x264.c
x264.h

index f48c50a..d882484 100644 (file)
@@ -80,7 +80,7 @@ void    x264_param_default( x264_param_t *param )
     param->b_cabac = 1;
     param->i_cabac_init_idc = 0;
 
-    param->rc.b_cbr = 0;
+    param->rc.i_rc_method = X264_RC_CQP;
     param->rc.i_bitrate = 0;
     param->rc.f_rate_tolerance = 1.0;
     param->rc.i_vbv_max_bitrate = 0;
@@ -494,12 +494,12 @@ char *x264_param2string( x264_param_t *p, int b_res )
     s += sprintf( s, " keyint=%d keyint_min=%d scenecut=%d",
                   p->i_keyint_max, p->i_keyint_min, p->i_scenecut_threshold );
 
-    s += sprintf( s, " rc=%s", p->rc.b_stat_read && p->rc.b_cbr ? "2pass" :
-                               p->rc.b_cbr ? p->rc.i_vbv_buffer_size ? "cbr" : "abr" :
-                               p->rc.i_rf_constant ? "crf" : "cqp" );
-    if( p->rc.b_cbr || p->rc.i_rf_constant )
+    s += sprintf( s, " rc=%s", p->rc.i_rc_method == X264_RC_ABR ?
+                               ( p->rc.b_stat_read ? "2pass" : p->rc.i_vbv_buffer_size ? "cbr" : "abr" )
+                               : p->rc.i_rc_method == X264_RC_CRF ? "crf" : "cqp" );
+    if( p->rc.i_rc_method == X264_RC_ABR || p->rc.i_rc_method == X264_RC_CRF )
     {
-        if( p->rc.i_rf_constant )
+        if( p->rc.i_rc_method == X264_RC_CRF )
             s += sprintf( s, " crf=%d", p->rc.i_rf_constant );
         else
             s += sprintf( s, " bitrate=%d ratetol=%.1f",
@@ -514,9 +514,9 @@ char *x264_param2string( x264_param_t *p, int b_res )
             s += sprintf( s, " vbv_maxrate=%d vbv_bufsize=%d",
                           p->rc.i_vbv_max_bitrate, p->rc.i_vbv_buffer_size );
     }
-    else
+    else if( p->rc.i_rc_method == X264_RC_CQP )
         s += sprintf( s, " qp=%d", p->rc.i_qp_constant );
-    if( p->rc.b_cbr || p->rc.i_qp_constant != 0 )
+    if( !(p->rc.i_rc_method == X264_RC_CQP && p->rc.i_qp_constant == 0) )
     {
         s += sprintf( s, " ip_ratio=%.2f", p->rc.f_ip_factor );
         if( p->i_bframe )
index 5b08571..424c5da 100644 (file)
@@ -422,7 +422,7 @@ static void x264_mb_analyse_intra_chroma( x264_t *h, x264_mb_analysis_t *a )
     int i;
 
     int i_max;
-    int predict_mode[9];
+    int predict_mode[4];
 
     uint8_t *p_dstc[2], *p_srcc[2];
 
index e8472c3..51af962 100644 (file)
@@ -341,20 +341,25 @@ static int x264_validate_parameters( x264_t *h )
     }
 #endif
 
-    if( h->param.rc.b_cbr )
-        h->param.rc.i_rf_constant = 0;
-    if( h->param.rc.i_rf_constant > 0 )
-        h->param.rc.i_qp_constant = h->param.rc.i_rf_constant;
+    if( h->param.rc.i_rc_method < 0 || h->param.rc.i_rc_method > 2 )
+    {
+        x264_log( h, X264_LOG_ERROR, "invalid RC method\n" );
+        return -1;
+    }
     h->param.rc.i_rf_constant = x264_clip3( h->param.rc.i_rf_constant, 0, 51 );
     h->param.rc.i_qp_constant = x264_clip3( h->param.rc.i_qp_constant, 0, 51 );
-    if( !h->param.rc.b_cbr && h->param.rc.i_qp_constant == 0 )
+    if( h->param.rc.i_rc_method == X264_RC_CRF )
+        h->param.rc.i_qp_constant = h->param.rc.i_rf_constant;
+    if( (h->param.rc.i_rc_method == X264_RC_CQP || h->param.rc.i_rc_method == X264_RC_CRF)
+        && h->param.rc.i_qp_constant == 0 )
     {
         h->mb.b_lossless = 1;
-        h->param.analyse.b_transform_8x8 = 0;
         h->param.i_cqm_preset = X264_CQM_FLAT;
         h->param.psz_cqm_file = NULL;
+        h->param.rc.i_rc_method = X264_RC_CQP;
         h->param.rc.f_ip_factor = 1;
         h->param.rc.f_pb_factor = 1;
+        h->param.analyse.b_transform_8x8 = 0;
         h->param.analyse.b_psnr = 0;
         h->param.analyse.i_chroma_qp_offset = 0;
         h->param.analyse.i_trellis = 0;
@@ -448,7 +453,6 @@ static int x264_validate_parameters( x264_t *h )
     BOOLIFY( analyse.b_bidir_me );
     BOOLIFY( analyse.b_chroma_me );
     BOOLIFY( analyse.b_fast_pskip );
-    BOOLIFY( rc.b_cbr );
     BOOLIFY( rc.b_stat_write );
     BOOLIFY( rc.b_stat_read );
 #undef BOOLIFY
@@ -522,7 +526,7 @@ x264_t *x264_encoder_open   ( x264_param_t *param )
     /* Init x264_t */
     h->out.i_nal = 0;
     h->out.i_bitstream = X264_MAX( 1000000, h->param.i_width * h->param.i_height * 1.7
-        * ( h->param.rc.b_cbr ? pow( 0.5, h->param.rc.i_qp_min )
+        * ( h->param.rc.i_rc_method == X264_RC_ABR ? pow( 0.5, h->param.rc.i_qp_min )
           : pow( 0.5, h->param.rc.i_qp_constant ) * X264_MAX( 1, h->param.rc.f_ip_factor )));
     h->out.p_bitstream = x264_malloc( h->out.i_bitstream );
 
@@ -548,7 +552,9 @@ x264_t *x264_encoder_open   ( x264_param_t *param )
     h->frames.i_max_ref1 = h->sps->vui.i_num_reorder_frames;
     h->frames.i_max_dpb  = h->sps->vui.i_max_dec_frame_buffering + 1;
     h->frames.b_have_lowres = !h->param.rc.b_stat_read
-        && ( h->param.rc.b_cbr || h->param.rc.i_rf_constant || h->param.b_bframe_adaptive );
+        && ( h->param.rc.i_rc_method == X264_RC_ABR
+          || h->param.rc.i_rc_method == X264_RC_CRF
+          || h->param.b_bframe_adaptive );
 
     for( i = 0; i < X264_BFRAME_MAX + 3; i++ )
     {
index 9a7e25d..7393261 100644 (file)
@@ -200,8 +200,8 @@ int x264_ratecontrol_new( x264_t *h )
     h->rc = rc = x264_malloc( h->param.i_threads * sizeof(x264_ratecontrol_t) );
     memset( rc, 0, h->param.i_threads * sizeof(x264_ratecontrol_t) );
 
-    rc->b_abr = ( h->param.rc.b_cbr || h->param.rc.i_rf_constant ) && !h->param.rc.b_stat_read;
-    rc->b_2pass = h->param.rc.b_cbr && h->param.rc.b_stat_read;
+    rc->b_abr = h->param.rc.i_rc_method != X264_RC_CQP && !h->param.rc.b_stat_read;
+    rc->b_2pass = h->param.rc.i_rc_method == X264_RC_ABR && h->param.rc.b_stat_read;
     
     /* FIXME: use integers */
     if(h->param.i_fps_num > 0 && h->param.i_fps_den > 0)
@@ -215,18 +215,20 @@ int x264_ratecontrol_new( x264_t *h )
     rc->last_non_b_pict_type = -1;
     rc->cbr_decay = 1.0;
 
-    if( h->param.rc.i_rf_constant && h->param.rc.b_stat_read )
+    if( h->param.rc.i_rc_method == X264_RC_CRF && h->param.rc.b_stat_read )
     {
         x264_log(h, X264_LOG_ERROR, "constant rate-factor is incompatible with 2pass.\n");
         return -1;
     }
-    if( h->param.rc.i_vbv_buffer_size && !h->param.rc.b_cbr && !h->param.rc.i_rf_constant )
-        x264_log(h, X264_LOG_WARNING, "VBV is incompatible with constant QP.\n");
-    if( h->param.rc.i_vbv_buffer_size && h->param.rc.b_cbr
-        && h->param.rc.i_vbv_max_bitrate == 0 )
+    if( h->param.rc.i_vbv_buffer_size )
     {
-        x264_log( h, X264_LOG_DEBUG, "VBV maxrate unspecified, assuming CBR\n" );
-        h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
+        if( h->param.rc.i_rc_method == X264_RC_CQP )
+            x264_log(h, X264_LOG_WARNING, "VBV is incompatible with constant QP, ignored.\n");
+        else if( h->param.rc.i_vbv_max_bitrate == 0 )
+        {
+            x264_log( h, X264_LOG_DEBUG, "VBV maxrate unspecified, assuming CBR\n" );
+            h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
+        }
     }
     if( h->param.rc.i_vbv_max_bitrate < h->param.rc.i_bitrate &&
         h->param.rc.i_vbv_max_bitrate > 0)
@@ -259,14 +261,14 @@ int x264_ratecontrol_new( x264_t *h )
     {
         /* FIXME shouldn't need to arbitrarily specify a QP,
          * but this is more robust than BPP measures */
-#define ABR_INIT_QP ( h->param.rc.i_rf_constant > 0 ? h->param.rc.i_rf_constant : 24 )
+#define ABR_INIT_QP ( h->param.rc.i_rc_method == X264_RC_CRF ? h->param.rc.i_rf_constant : 24 )
         rc->accum_p_norm = .01;
         rc->accum_p_qp = ABR_INIT_QP * rc->accum_p_norm;
         rc->cplxr_sum = .01;
         rc->wanted_bits_window = .01;
     }
 
-    if( h->param.rc.i_rf_constant )
+    if( h->param.rc.i_rc_method == X264_RC_CRF )
     {
         /* arbitrary rescaling to make CRF somewhat similar to QP */
         double base_cplx = h->mb.i_mb_count * (h->param.i_bframe ? 120 : 80);
@@ -342,7 +344,7 @@ int x264_ratecontrol_new( x264_t *h )
                 x264_log( h, X264_LOG_WARNING, "different keyint than 1st pass (%d vs %d)\n",
                           h->param.i_keyint_max, i );
 
-            if( strstr( opts, "qp=0" ) && h->param.rc.b_cbr )
+            if( strstr( opts, "qp=0" ) && h->param.rc.i_rc_method == X264_RC_ABR )
                 x264_log( h, X264_LOG_WARNING, "1st pass was lossless, bitrate prediction will be inaccurate\n" );
         }
 
@@ -432,7 +434,7 @@ int x264_ratecontrol_new( x264_t *h )
 
         x264_free(stats_buf);
 
-        if(h->param.rc.b_cbr)
+        if(h->param.rc.i_rc_method == X264_RC_ABR)
         {
             if(init_pass2(h) < 0) return -1;
         } /* else we're using constant quant, so no need to run the bitrate allocation */
@@ -524,7 +526,7 @@ static int parse_zones( x264_t *h )
 void x264_ratecontrol_summary( x264_t *h )
 {
     x264_ratecontrol_t *rc = h->rc;
-    if( rc->b_abr && !h->param.rc.i_rf_constant && !h->param.rc.i_vbv_max_bitrate )
+    if( rc->b_abr && h->param.rc.i_rc_method == X264_RC_ABR && !h->param.rc.i_vbv_max_bitrate )
     {
         double base_cplx = h->mb.i_mb_count * (h->param.i_bframe ? 120 : 80);
         x264_log( h, X264_LOG_INFO, "final ratefactor: %.2f\n", 
@@ -739,7 +741,7 @@ int x264_ratecontrol_slice_type( x264_t *h, int frame_num )
 
             rc->b_abr = 0;
             rc->b_2pass = 0;
-            h->param.rc.b_cbr = 0;
+            h->param.rc.i_rc_method = X264_RC_CQP;
             h->param.rc.b_stat_read = 0;
             h->param.b_bframe_adaptive = 0;
             if( h->param.i_bframe > 1 )
@@ -1235,7 +1237,7 @@ static float rate_estimate_qscale(x264_t *h, int pict_type)
             rce.qscale = 1;
             rce.pict_type = pict_type;
 
-            if( h->param.rc.i_rf_constant )
+            if( h->param.rc.i_rc_method == X264_RC_CRF )
             {
                 q = get_qscale( h, &rce, rcc->rate_factor_constant, h->fenc->i_frame );
                 overflow = 1;
index 7a67c5f..bf88670 100644 (file)
@@ -77,7 +77,7 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
 {
     sps->i_id = i_id;
 
-    sps->b_qpprime_y_zero_transform_bypass = !param->rc.b_cbr && param->rc.i_qp_constant == 0;
+    sps->b_qpprime_y_zero_transform_bypass = param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0;
     if( sps->b_qpprime_y_zero_transform_bypass )
         sps->i_profile_idc  = PROFILE_HIGH444;
     else if( param->analyse.b_transform_8x8 || param->i_cqm_preset != X264_CQM_FLAT )
@@ -376,7 +376,7 @@ void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *
     pps->b_weighted_pred = 0;
     pps->b_weighted_bipred = param->analyse.b_weighted_bipred ? 2 : 0;
 
-    pps->i_pic_init_qp = param->rc.b_cbr ? 26 : param->rc.i_qp_constant;
+    pps->i_pic_init_qp = param->rc.i_rc_method == X264_RC_ABR ? 26 : param->rc.i_qp_constant;
     pps->i_pic_init_qs = 26;
 
     pps->i_chroma_qp_index_offset = param->analyse.i_chroma_qp_offset;
index f9cd9c3..c9c3a61 100644 (file)
@@ -282,10 +282,11 @@ LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiO
     switch( config->i_encoding_type )
     {
         case 0: /* 1 PASS ABR */
-            param.rc.b_cbr = 1;
+            param.rc.i_rc_method = X264_RC_ABR;
             param.rc.i_bitrate = config->bitrate;
             break;
         case 1: /* 1 PASS CQ */
+            param.rc.i_rc_method = X264_RC_CQP;
             param.rc.i_qp_constant = config->i_qp;
             break;
         default:
@@ -312,8 +313,8 @@ LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiO
                 return ICERR_ERROR;
             }
 
+            param.rc.i_rc_method = X264_RC_ABR;
             param.rc.i_bitrate = config->i_2passbitrate;
-            param.rc.b_cbr = 1;
 
             if( config->i_pass == 1 )
             {
diff --git a/x264.c b/x264.c
index 4a75fcb..d7074bf 100644 (file)
--- a/x264.c
+++ b/x264.c
@@ -560,10 +560,11 @@ static int  Parse( int argc, char **argv,
                 break;
             case 'B':
                 param->rc.i_bitrate = atol( optarg );
-                param->rc.b_cbr = 1;
+                param->rc.i_rc_method = X264_RC_ABR;
                 break;
             case OPT_CRF:
                 param->rc.i_rf_constant = atol( optarg );
+                param->rc.i_rc_method = X264_RC_CRF;
                 break;
             case 'b':
                 param->i_bframe = atol( optarg );
@@ -603,6 +604,7 @@ static int  Parse( int argc, char **argv,
             }
             case 'q':
                 param->rc.i_qp_constant = atoi( optarg );
+                param->rc.i_rc_method = X264_RC_CQP;
                 break;
             case OPT_QPMIN:
                 param->rc.i_qp_min = atoi( optarg );
diff --git a/x264.h b/x264.h
index 07fa487..f2ff831 100644 (file)
--- a/x264.h
+++ b/x264.h
@@ -35,7 +35,7 @@
 
 #include <stdarg.h>
 
-#define X264_BUILD 47
+#define X264_BUILD 48
 
 /* x264_t:
  *      opaque handler for decoder and encoder */
@@ -73,6 +73,10 @@ typedef struct x264_t x264_t;
 #define X264_CQM_JVT                 1
 #define X264_CQM_CUSTOM              2
 
+#define X264_RC_CQP                  0
+#define X264_RC_CRF                  1
+#define X264_RC_ABR                  2
+
 static const char * const x264_direct_pred_names[] = { "none", "spatial", "temporal", "auto", 0 };
 static const char * const x264_motion_est_names[] = { "dia", "hex", "umh", "esa", 0 };
 
@@ -212,12 +216,13 @@ typedef struct
     /* Rate control parameters */
     struct
     {
+        int         i_rc_method;    /* X264_RC_* */
+
         int         i_qp_constant;  /* 0-51 */
         int         i_qp_min;       /* min allowed QP value */
         int         i_qp_max;       /* max allowed QP value */
         int         i_qp_step;      /* max QP step between frames */
 
-        int         b_cbr;          /* use bitrate instead of CQP */
         int         i_bitrate;
         int         i_rf_constant;  /* 1pass VBR, nominal QP */
         float       f_rate_tolerance;