]> git.sesse.net Git - x264/commitdiff
Add "--stitchable" option for segmented encoding
authorFiona Glaser <fiona@x264.com>
Sat, 1 Jun 2013 00:01:29 +0000 (17:01 -0700)
committerFiona Glaser <fiona@x264.com>
Wed, 3 Jul 2013 00:13:08 +0000 (17:13 -0700)
Stops x264 from attempting to optimize global stream headers, ensuring that
different segments of a video will have identical headers when used with
identical encoding settings.

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

index d83956c92b9b718f2b67d2ccd1c3b919340a76b8..5001f8fc76dedf7e1a545246600d14dee30b2d8a 100644 (file)
@@ -1037,6 +1037,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )
         p->b_fake_interlaced = atobool(value);
     OPT("frame-packing")
         p->i_frame_packing = atoi(value);
+    OPT("stitchable")
+        p->b_stitchable = atobool(value);
     OPT("opencl")
         p->b_opencl = atobool( value );
     OPT("opencl-clbin")
@@ -1330,6 +1332,8 @@ char *x264_param2string( x264_param_t *p, int b_res )
     s += sprintf( s, " decimate=%d", p->analyse.b_dct_decimate );
     s += sprintf( s, " interlaced=%s", p->b_interlaced ? p->b_tff ? "tff" : "bff" : p->b_fake_interlaced ? "fake" : "0" );
     s += sprintf( s, " bluray_compat=%d", p->b_bluray_compat );
+    if( p->b_stitchable )
+        s += sprintf( s, " stitchable=%d", p->b_stitchable );
 
     s += sprintf( s, " constrained_intra=%d", p->b_constrained_intra );
 
index 094152ea97be9b7b387dccc74cdbefe2a9b53e32..729584237b881d68ca91017bd7494271251378fc 100644 (file)
@@ -1079,6 +1079,7 @@ static int x264_validate_parameters( x264_t *h, int b_open )
     BOOLIFY( b_fake_interlaced );
     BOOLIFY( b_open_gop );
     BOOLIFY( b_bluray_compat );
+    BOOLIFY( b_stitchable );
     BOOLIFY( b_full_recon );
     BOOLIFY( b_opencl );
     BOOLIFY( analyse.b_transform_8x8 );
index dcc1e28d1622a74260b3fafcf0aff19562d61690..c7dfd6d86a2b0ba3461e214a4c43b535a5cc83d9 100644 (file)
@@ -1118,7 +1118,8 @@ parse_error:
             total_qp_aq += qp_aq;
             p = next;
         }
-        h->pps->i_pic_init_qp = SPEC_QP( (int)(total_qp_aq / rc->num_entries + 0.5) );
+        if( !h->param.b_stitchable )
+            h->pps->i_pic_init_qp = SPEC_QP( (int)(total_qp_aq / rc->num_entries + 0.5) );
 
         x264_free( stats_buf );
 
index fdedf983b7cd2db5b383df5288509ed76cbf7db2..d514aa31e51cc62373d13cf4df9cc6bf4dcfe109 100644 (file)
@@ -430,7 +430,7 @@ void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *
     pps->b_weighted_pred = param->analyse.i_weighted_pred > 0;
     pps->b_weighted_bipred = param->analyse.b_weighted_bipred ? 2 : 0;
 
-    pps->i_pic_init_qp = param->rc.i_rc_method == X264_RC_ABR ? 26 + QP_BD_OFFSET : SPEC_QP( param->rc.i_qp_constant );
+    pps->i_pic_init_qp = param->rc.i_rc_method == X264_RC_ABR || param->b_stitchable ? 26 + QP_BD_OFFSET : SPEC_QP( param->rc.i_qp_constant );
     pps->i_pic_init_qs = 26 + QP_BD_OFFSET;
 
     pps->i_chroma_qp_index_offset = param->analyse.i_chroma_qp_offset;
diff --git a/x264.c b/x264.c
index 04e1e974fd359e7a79ea2d5bfc1d4bf375818dd3..7824a7f8f33265e930e2f31fab6112f78c448101 100644 (file)
--- a/x264.c
+++ b/x264.c
@@ -790,6 +790,8 @@ static void help( x264_param_t *defaults, int longhelp )
     H0( "      --frames <integer>      Maximum number of frames to encode\n" );
     H0( "      --level <string>        Specify level (as defined by Annex A)\n" );
     H1( "      --bluray-compat         Enable compatibility hacks for Blu-ray support\n" );
+    H1( "      --stitchable            Don't optimize headers based on video content\n"
+        "                              Ensures ability to recombine a segmented encode\n" );
     H1( "\n" );
     H1( "  -v, --verbose               Print stats for each frame\n" );
     H1( "      --no-progress           Don't show the progress indicator while encoding\n" );
@@ -1036,6 +1038,7 @@ static struct option long_options[] =
     { "dts-compress",      no_argument, NULL, OPT_DTS_COMPRESSION },
     { "output-csp",  required_argument, NULL, OPT_OUTPUT_CSP },
     { "input-range", required_argument, NULL, OPT_INPUT_RANGE },
+    { "stitchable",        no_argument, NULL, 0 },
     {0, 0, 0, 0}
 };
 
diff --git a/x264.h b/x264.h
index aab7121061098f4b73ec8575711f0ae28103bb36..19100e0f3cf223cbc40cc9d8398654e2e8e2eb5e 100644 (file)
--- a/x264.h
+++ b/x264.h
@@ -41,7 +41,7 @@
 
 #include "x264_config.h"
 
-#define X264_BUILD 133
+#define X264_BUILD 134
 
 /* Application developers planning to link against a shared library version of
  * libx264 from a Microsoft Visual Studio or similar development environment
@@ -474,6 +474,11 @@ typedef struct x264_param_t
 
     int b_fake_interlaced;
 
+    /* Don't optimize header parameters based on video content, e.g. ensure that splitting an input video, compressing
+     * each part, and stitching them back together will result in identical SPS/PPS. This is necessary for stitching
+     * with container formats that don't allow multiple SPS/PPS. */
+    int b_stitchable;
+
     int b_opencl;            /* use OpenCL when available */
     int i_opencl_device;     /* specify count of GPU devices to skip, for CLI users */
     void *opencl_device_id;  /* pass explicit cl_device_id as void*, for API users */