]> git.sesse.net Git - x264/commitdiff
Add --filler option
authorFiona Glaser <fiona@x264.com>
Mon, 9 Sep 2013 19:37:59 +0000 (12:37 -0700)
committerFiona Glaser <fiona@x264.com>
Wed, 30 Oct 2013 20:02:27 +0000 (13:02 -0700)
Allows generation of hard-CBR streams without using NAL HRD.
Useful if you want to be able to reconfigure the bitrate (which you can't do
with NAL HRD on).

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

index c736c95393a091fefc7be37f53cb9eb9e3f1dc42..467db3e472dbe70a475a55cc5dcf4c02e0f14035 100644 (file)
@@ -1036,6 +1036,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )
         p->b_vfr_input = !atobool(value);
     OPT("nal-hrd")
         b_error |= parse_enum( value, x264_nal_hrd_names, &p->i_nal_hrd );
+    OPT("filler")
+        p->rc.b_filler = atobool(value);
     OPT("pic-struct")
         p->b_pic_struct = atobool(value);
     OPT("fake-interlaced")
@@ -1406,7 +1408,7 @@ char *x264_param2string( x264_param_t *p, int b_res )
         s += sprintf( s, " qp=%d", p->rc.i_qp_constant );
 
     if( p->rc.i_vbv_buffer_size )
-        s += sprintf( s, " nal_hrd=%s", x264_nal_hrd_names[p->i_nal_hrd] );
+        s += sprintf( s, " nal_hrd=%s filler=%d", x264_nal_hrd_names[p->i_nal_hrd], p->rc.b_filler );
     if( p->crop_rect.i_left | p->crop_rect.i_top | p->crop_rect.i_right | p->crop_rect.i_bottom )
         s += sprintf( s, " crop_rect=%u,%u,%u,%u", p->crop_rect.i_left, p->crop_rect.i_top,
                                                    p->crop_rect.i_right, p->crop_rect.i_bottom );
index 90c8d78ec39af9af8171aecfa4af3878dddfdfb5..471ef544c732d20aae520c09d80d79a8fd9ae2a2 100644 (file)
@@ -734,6 +734,7 @@ static int x264_validate_parameters( x264_t *h, int b_open )
         h->param.rc.i_bitrate = h->param.rc.i_vbv_buffer_size * fps_num / fps_den;
         h->param.rc.i_rc_method = X264_RC_ABR;
         h->param.rc.f_vbv_buffer_init = 1.0;
+        h->param.rc.b_filler = 1;
         h->param.i_cqm_preset = X264_CQM_CUSTOM;
         memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof(h->param.cqm_4iy) );
         memcpy( h->param.cqm_4ic, avcintra_lut[type][res][i].cqm_4ic, sizeof(h->param.cqm_4ic) );
@@ -1208,6 +1209,9 @@ static int x264_validate_parameters( x264_t *h, int b_open )
         h->param.i_nal_hrd = X264_NAL_HRD_VBR;
     }
 
+    if( h->param.i_nal_hrd == X264_NAL_HRD_CBR )
+        h->param.rc.b_filler = 1;
+
     /* ensure the booleans are 0 or 1 so they can be used in math */
 #define BOOLIFY(x) h->param.x = !!h->param.x
     BOOLIFY( b_cabac );
@@ -1244,6 +1248,7 @@ static int x264_validate_parameters( x264_t *h, int b_open )
     BOOLIFY( rc.b_stat_write );
     BOOLIFY( rc.b_stat_read );
     BOOLIFY( rc.b_mb_tree );
+    BOOLIFY( rc.b_filler );
 #undef BOOLIFY
 
     return 0;
index fe087583030d2a53db948a885df2acb6e9c838b8..9529413f5ac3e0144a0b8dcb70251b54bce20698 100644 (file)
@@ -699,8 +699,6 @@ void x264_ratecontrol_init_reconfigurable( x264_t *h, int b_init )
             x264_log( h, X264_LOG_WARNING, "VBV parameters cannot be changed when NAL HRD is in use\n" );
             return;
         }
-        if( h->param.b_avcintra_compat )
-            h->sps->vui.hrd.b_cbr_hrd = 1;
         h->sps->vui.hrd.i_bit_rate_unscaled = vbv_max_bitrate;
         h->sps->vui.hrd.i_cpb_size_unscaled = vbv_buffer_size;
 
@@ -2122,7 +2120,7 @@ static int update_vbv( x264_t *h, int bits )
     else
         rct->buffer_fill_final += (uint64_t)bitrate * h->sps->vui.i_num_units_in_tick * h->fenc->i_cpb_duration;
 
-    if( h->sps->vui.hrd.b_cbr_hrd && rct->buffer_fill_final > buffer_size )
+    if( h->param.rc.b_filler && rct->buffer_fill_final > buffer_size )
     {
         int64_t scale = (int64_t)h->sps->vui.i_time_scale * 8;
         filler = (rct->buffer_fill_final - buffer_size + scale - 1) / scale;
diff --git a/x264.c b/x264.c
index 0aeec056924c7be7321b3bdfe9868557bac1b1fe..a0712f2abe4b21dd264743d351caa30ecec1d647 100644 (file)
--- a/x264.c
+++ b/x264.c
@@ -853,6 +853,8 @@ static void help( x264_param_t *defaults, int longhelp )
 
     H2( "      --nal-hrd <string>      Signal HRD information (requires vbv-bufsize)\n"
         "                                  - none, vbr, cbr (cbr not allowed in .mp4)\n" );
+    H2( "      --filler                Force hard-CBR and generate filler (implied by\n"
+        "                              --nal-hrd cbr)\n" );
     H2( "      --pic-struct            Force pic_struct in Picture Timing SEI\n" );
     H2( "      --crop-rect <string>    Add 'left,top,right,bottom' to the bitstream-level\n"
         "                              cropping rectangle\n" );
@@ -1132,6 +1134,7 @@ static struct option long_options[] =
     { "output-csp",  required_argument, NULL, OPT_OUTPUT_CSP },
     { "input-range", required_argument, NULL, OPT_INPUT_RANGE },
     { "stitchable",        no_argument, NULL, 0 },
+    { "filler",            no_argument, NULL, 0 },
     {0, 0, 0, 0}
 };
 
diff --git a/x264.h b/x264.h
index c3e2dba81e5f52689cd3319c7dcba9b03500f2f0..8b8f2649b09bfc54b47d570ee3b12a1dcff026fc 100644 (file)
--- a/x264.h
+++ b/x264.h
@@ -41,7 +41,7 @@
 
 #include "x264_config.h"
 
-#define X264_BUILD 138
+#define X264_BUILD 139
 
 /* Application developers planning to link against a shared library version of
  * libx264 from a Microsoft Visual Studio or similar development environment
@@ -409,6 +409,10 @@ typedef struct x264_param_t
         float       f_ip_factor;
         float       f_pb_factor;
 
+        /* VBV filler: force CBR VBV and use filler bytes to ensure hard-CBR.
+         * Implied by NAL-HRD CBR. */
+        int         b_filler;
+
         int         i_aq_mode;      /* psy adaptive QP. (X264_AQ_*) */
         float       f_aq_strength;
         int         b_mb_tree;      /* Macroblock-tree ratecontrol. */