changeset 20054:8760c8681eac

Remove the x264 option parser, and pass the options on to libx264 as a string instead. This provides automatic support for all current and future x264 options. A few options had to be reorganized: partitions, deblockalpha/beta, me, direct_pred.
author lorenm
date Thu, 05 Oct 2006 02:03:10 +0000
parents 63979c96cca5
children 64cbe416df38
files DOCS/man/en/mplayer.1 cfg-mencoder.h configure libmpcodecs/ve_x264.c
diffstat 4 files changed, 98 insertions(+), 375 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/man/en/mplayer.1	Thu Oct 05 00:57:48 2006 +0000
+++ b/DOCS/man/en/mplayer.1	Thu Oct 05 02:03:10 2006 +0000
@@ -9014,7 +9014,7 @@
 at significant reduction in quality.
 .
 .TP
-.B qp_constant=<0\-51>
+.B qp=<0\-51>
 This selects the quantizer to use for P-frames.
 I- and B-frames are offset from this value by ip_factor and pb_factor, respectively.
 20\-40 is a useful range (default: 26).
@@ -9175,8 +9175,8 @@
 recommended to disable it.
 .
 .TP
-.B deblockalpha=<-6\-6>
-AlphaC0 parameter of deblocking filter (default: 0).
+.B deblock=<-6\-6>,<-6\-6>
+The first parameter is AlphaC0 (default: 0).
 This adjusts thresholds for the H.264 in-loop deblocking filter.
 First, this parameter adjusts the maximum amount of change that the filter is
 allowed to cause on any one pixel.
@@ -9184,19 +9184,17 @@
 edge being filtered.
 A positive value reduces blocking artifacts more, but will also smear details.
 .br
+The second parameter is Beta (default: 0).
+This affects the detail threshold.
+Very detailed blocks are not filtered, since the smoothing caused by the
+filter would be more noticeable than the original blocking.
+.br
 The default behavior of the filter almost always achieves optimal quality,
 so it is best to either leave it alone, or make only small adjustments.
 However, if your source material already has some blocking or noise which
 you would like to remove, it may be a good idea to turn it up a little bit.
 .
 .TP
-.B deblockbeta=<-6\-6>
-Beta parameter of deblocking filter (default: 0).
-Affects the detail threshold.
-Very detailed blocks are not filtered, since the smoothing caused by the
-filter would be more noticeable than the original blocking.
-.
-.TP
 .B (no)cabac
 Use CABAC (Context-Adaptive Binary Arithmetic Coding) (default: on).
 Slightly slows down encoding and decoding, but should save 10-15% bitrate.
@@ -9213,7 +9211,7 @@
 .TP
 .B qp_step=<1\-50> (ABR or two pass)
 maximum value by which the quantizer may be incremented/decremented between
-frames (default: 2)
+frames (default: 4)
 .
 .TP
 .B ratetol=<0.1\-100.0> (ABR or two pass)
@@ -9284,27 +9282,28 @@
 .RE
 .
 .TP
-.B direct_pred=<0\-3>
+.B direct_pred=<name>
 Determines the type of motion prediction used for direct macroblocks
 in B-frames.
 .PD 0
 .RSs
-.IPs 0
-None: Direct macroblocks are not used.
-.IPs 1
-Spatial: Motion vectors are extrapolated from neighboring blocks.
+.IPs none
+Direct macroblocks are not used.
+.IPs spatial
+Motion vectors are extrapolated from neighboring blocks.
 (default)
-.IPs 2
-Temporal: Motion vectors are interpolated from the following P-frame.
-.IPs 3
-Auto: The codec selects between spatial and temporal for each frame.
+.IPs temporal
+Motion vectors are interpolated from the following P-frame.
+.IPs auto
+The codec selects between spatial and temporal for each frame.
 .RE
 .PD 1
 .RS
 Spatial and temporal are approximately the same speed and PSNR,
 the choice between them depends on the video content.
 Auto is slightly better, but slower.
-direct_pred=0 is both slower and lower quality.
+Auto is most effective when combined with multipass.
+direct_pred=none is both slower and lower quality.
 .RE
 .
 .TP
@@ -9317,44 +9316,37 @@
 Requires bframes > 1.
 .
 .TP
-.B (no)i4x4
-Use additional macroblock type i4x4 (default: enabled).
-Without this option, P- and B-frames will use only
-i16x16 and the inter types specified below.
-.
-.TP
-.B (no)i8x8
-Use additional macroblock type i8x8 (default: enabled).
-This option has no effect unless 8x8dct is enabled.
-.
-.TP
-.B (no)b8x8mv
-Use additional macroblock types b16x8, b8x16, b8x8 (default: enabled).
-Without this option, B-frames will use only types
-i16x16, i8x8, i4x4, b16x16, skip, direct.
-See 4x4mv for details.
-.
-.TP
-.B (no)8x8mv
-Use additional macroblock types p16x8, p8x16, p8x8 (default: enabled).
-Without this option, P-frames will use only types
-i16x16, i8x8, i4x4, p16x16, skip.
-This option is provided for experimentation only.
-It is not recommended to disable 8x8mv in a real encode.
-.
-.TP
-.B (no)4x4mv
-Use additional macroblock types p8x4, p4x8, p4x4 (default: disabled).
-Without this option, P-frames will use only types
-i16x16, i8x8, i4x4, p16x16, p16x8, p8x16, p8x8, skip.
-Requires 8x8mv.
+.B partitions=<list>
+Enable some optional macroblock types (default: p8x8,b8x8,i8x8,i4x4).
+.PD 0
+.RSs
+.IPs p8x8
+Enable types p16x8, p8x16, p8x8.
+.IPs p4x4
+Enable types p8x4, p4x8, p4x4.
+p4x4 is recommended only with subq >= 5, and only at low resolutions.
+.IPs b8x8
+Enable types b16x8, b8x16, b8x8.
+.IPs i8x8
+Enable type i8x8.
+i8x8 has no effect unless 8x8dct is enabled.
+.IPs i4x4
+Enable type i4x4.
+.IPs all
+Enable all of the above types.
+.IPs none
+Disable all of the above types.
+.RE
+.PD 1
+.RS
+Regardless of this option, macroblock types p16x16, b16x16, and i16x16
+are always enabled.
 .br
 The idea is to find the type and size that best describe a certain area
 of the picture.
 For example, a global pan is better represented by 16x16 blocks, while
 small moving objects are better represented by smaller blocks.
-.br
-4x4mv is recommended only with subq >= 3.
+.RE
 .
 .TP
 .B (no)8x8dct
@@ -9364,18 +9356,18 @@
 Without this option, only 4x4 DCT is used.
 .
 .TP
-.B me=<1\-4>
+.B me=<name>
 Select fullpixel motion estimation algorithm.
 .PD 0
 .RSs
-.IPs 1
+.IPs dia
 diamond search, radius 1 (fast)
-.IPs 2
+.IPs hex
 hexagon search, radius 2 (default)
-.IPs 3
+.IPs umh
 uneven multi-hexagon search (slow)
-.IPs 4
-exhaustive search (very slow, and no better than 3)
+.IPs esa
+exhaustive search (very slow, and no better than umh)
 .RE
 .PD 1
 .
@@ -9452,9 +9444,9 @@
 .PD 0
 .RSs
 .IPs 0
-disabled
+disabled (default)
 .IPs 1
-enabled only for the final encode (default)
+enabled only for the final encode
 .IPs 2
 enabled during all mode decisions (slow, requires subq>=6)
 .RE
@@ -9558,7 +9550,7 @@
 option will produce a warning and enables slices but not multithreading.
 .
 .TP
-.B (no)globalheader
+.B (no)global_header
 Causes SPS and PPS to appear only once, at the beginning of the bitstream
 (default: disabled).
 Some players, such as the Sony PSP, require the use of this option.
--- a/cfg-mencoder.h	Thu Oct 05 00:57:48 2006 +0000
+++ b/cfg-mencoder.h	Thu Oct 05 02:03:10 2006 +0000
@@ -43,7 +43,7 @@
 #endif
 
 #if defined(HAVE_X264)
-extern m_option_t x264encopts_conf[];
+extern char *x264encopts;
 #endif
 
 extern m_option_t nuvopts_conf[];
@@ -271,7 +271,7 @@
 	{"xvidencopts", xvidencopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
 #endif
 #if defined(HAVE_X264)
-	{"x264encopts", x264encopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
+	{"x264encopts", &x264encopts, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL},
 #endif
 
 	{"nuvopts",  nuvopts_conf, CONF_TYPE_SUBCONFIG, CONF_GLOBAL, 0, 0, NULL},
--- a/configure	Thu Oct 05 00:57:48 2006 +0000
+++ b/configure	Thu Oct 05 02:03:10 2006 +0000
@@ -6511,7 +6511,7 @@
   cat > $TMPC << EOF
 #include <inttypes.h>
 #include <x264.h>
-#if X264_BUILD < 48
+#if X264_BUILD < 53
 #error We do not support old versions of x264. Get the latest from SVN.
 #endif
 int main(void) { x264_encoder_open((void*)0); return 0; }
--- a/libmpcodecs/ve_x264.c	Thu Oct 05 00:57:48 2006 +0000
+++ b/libmpcodecs/ve_x264.c	Thu Oct 05 02:03:10 2006 +0000
@@ -55,177 +55,8 @@
 } h264_module_t;
 
 extern char* passtmpfile;
-
-static int bitrate = -1;
-static int qp_constant = 26;
-static int rf_constant = 0;
-static int frame_ref = 1;
-static int keyint_max = 250;
-static int keyint_min = 25;
-static int scenecut_threshold = 40;
-static int bframe = 0;
-static int bframe_adaptive = 1;
-static int bframe_bias = 0;
-static int bframe_pyramid = 0;
-static int deblock = 1;
-static int deblockalpha = 0;
-static int deblockbeta = 0;
-static int cabac = 1;
-static int p4x4mv = 0;
-static int p8x8mv = 1;
-static int b8x8mv = 1;
-static int i8x8 = 1;
-static int i4x4 = 1;
-static int dct8 = 0;
-static int direct_pred = X264_DIRECT_PRED_SPATIAL;
-static int weight_b = 0;
-static int chroma_me = 1;
-static int mixed_references = 0;
-static int chroma_qp_offset = 0;
-static float ip_factor = 1.4;
-static float pb_factor = 1.3;
-static float ratetol = 1.0;
-static int vbv_maxrate = 0;
-static int vbv_bufsize = 0;
-static float vbv_init = 0.9;
-static int qp_min = 10;
-static int qp_max = 51;
-static int qp_step = 2;
-static int pass = 0;
-static float qcomp = 0.6;
-static float qblur = 0.5;
-static float complexity_blur = 20;
-static char *rc_eq = "blurCplx^(1-qComp)";
-static char *zones = NULL;
-static int subq = 5;
-static int bframe_rdo = 0;
-static int bidir_me = 0;
-static int me_method = 2;
-static int me_range = 16;
-static int trellis = 1;
-static int fast_pskip = 1;
-static int dct_decimate = 1;
-static int noise_reduction = 0;
-static int threads = 1;
-static int level_idc = 51;
-static int psnr = 0;
-static int log_level = 2;
 static int turbo = 0;
-static int visualize = 0;
-static char *cqm = NULL;
-static char *cqm4iy = NULL;
-static char *cqm4ic = NULL;
-static char *cqm4py = NULL;
-static char *cqm4pc = NULL;
-static char *cqm8iy = NULL;
-static char *cqm8py = NULL;
-static int globalheader=0;
-
-m_option_t x264encopts_conf[] = {
-    {"bitrate", &bitrate, CONF_TYPE_INT, CONF_RANGE, 0, 24000000, NULL},
-    {"qp_constant", &qp_constant, CONF_TYPE_INT, CONF_RANGE, 0, 51, NULL},
-    {"qp", &qp_constant, CONF_TYPE_INT, CONF_RANGE, 0, 51, NULL},
-    {"crf", &rf_constant, CONF_TYPE_INT, CONF_RANGE, 1, 50, NULL},
-    {"frameref", &frame_ref, CONF_TYPE_INT, CONF_RANGE, 1, 16, NULL},
-    {"keyint", &keyint_max, CONF_TYPE_INT, CONF_RANGE, 1, 24000000, NULL},
-    {"keyint_min", &keyint_min, CONF_TYPE_INT, CONF_RANGE, 1, 24000000, NULL},
-    {"scenecut", &scenecut_threshold, CONF_TYPE_INT, CONF_RANGE, -1, 100, NULL},
-    {"bframes", &bframe, CONF_TYPE_INT, CONF_RANGE, 0, 16, NULL},
-    {"b_adapt", &bframe_adaptive, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nob_adapt", &bframe_adaptive, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"b_bias", &bframe_bias, CONF_TYPE_INT, CONF_RANGE, -100, 100, NULL},
-    {"b_pyramid", &bframe_pyramid, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nob_pyramid", &bframe_pyramid, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"deblock", &deblock, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nodeblock", &deblock, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"deblockalpha", &deblockalpha, CONF_TYPE_INT, CONF_RANGE, -6, 6, NULL},
-    {"deblockbeta", &deblockbeta, CONF_TYPE_INT, CONF_RANGE, -6, 6, NULL},
-    {"cabac", &cabac, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nocabac", &cabac, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"4x4mv", &p4x4mv, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"no4x4mv", &p4x4mv, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"8x8mv", &p8x8mv, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"no8x8mv", &p8x8mv, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"b8x8mv", &b8x8mv, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nob8x8mv", &b8x8mv, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"i4x4", &i4x4, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"noi4x4", &i4x4, CONF_TYPE_FLAG, 0, 0, 0, NULL},
-    {"i8x8", &i8x8, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"noi8x8", &i8x8, CONF_TYPE_FLAG, 0, 0, 0, NULL},
-    {"8x8dct", &dct8, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"no8x8dct", &dct8, CONF_TYPE_FLAG, 0, 0, 0, NULL},
-    {"direct_pred", &direct_pred, CONF_TYPE_INT, CONF_RANGE, 0, 3, NULL},
-    {"weight_b", &weight_b, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"noweight_b", &weight_b, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"bime", &bidir_me, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nobime", &bidir_me, CONF_TYPE_FLAG, 0, 0, 0, NULL},
-    {"chroma_me", &chroma_me, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nochroma_me", &chroma_me, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"mixed_refs", &mixed_references, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nomixed_refs", &mixed_references, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"chroma_qp_offset", &chroma_qp_offset, CONF_TYPE_INT, CONF_RANGE, -12, 12, NULL},
-    {"ip_factor", &ip_factor, CONF_TYPE_FLOAT, CONF_RANGE, -10.0, 10.0, NULL},
-    {"pb_factor", &pb_factor, CONF_TYPE_FLOAT, CONF_RANGE, -10.0, 10.0, NULL},
-    {"ratetol", &ratetol, CONF_TYPE_FLOAT, CONF_RANGE, 0.1, 100.0, NULL},
-    {"vbv_maxrate", &vbv_maxrate, CONF_TYPE_INT, CONF_RANGE, 0, 24000000, NULL},
-    {"vbv_bufsize", &vbv_bufsize, CONF_TYPE_INT, CONF_RANGE, 0, 24000000, NULL},
-    {"vbv_init", &vbv_init, CONF_TYPE_FLOAT, CONF_RANGE, 0.0, 1.0, NULL},
-    {"qp_min", &qp_min, CONF_TYPE_INT, CONF_RANGE, 1, 51, NULL},
-    {"qp_max", &qp_max, CONF_TYPE_INT, CONF_RANGE, 1, 51, NULL},
-    {"qp_step", &qp_step, CONF_TYPE_INT, CONF_RANGE, 1, 50, NULL},
-    {"pass", &pass, CONF_TYPE_INT, CONF_RANGE, 1, 3, NULL},
-    {"rc_eq", &rc_eq, CONF_TYPE_STRING, 0, 0, 0, NULL},
-    {"cqm", &cqm, CONF_TYPE_STRING, 0, 0, 0, NULL},
-    {"cqm4iy", &cqm4iy, CONF_TYPE_STRING, 0, 0, 0, NULL},
-    {"cqm4ic", &cqm4ic, CONF_TYPE_STRING, 0, 0, 0, NULL},
-    {"cqm4py", &cqm4py, CONF_TYPE_STRING, 0, 0, 0, NULL},
-    {"cqm4pc", &cqm4pc, CONF_TYPE_STRING, 0, 0, 0, NULL},
-    {"cqm8iy", &cqm8iy, CONF_TYPE_STRING, 0, 0, 0, NULL},
-    {"cqm8py", &cqm8py, CONF_TYPE_STRING, 0, 0, 0, NULL},
-    {"qcomp", &qcomp, CONF_TYPE_FLOAT, CONF_RANGE, 0, 1, NULL},
-    {"qblur", &qblur, CONF_TYPE_FLOAT, CONF_RANGE, 0, 99, NULL},
-    {"cplx_blur", &complexity_blur, CONF_TYPE_FLOAT, CONF_RANGE, 0, 999, NULL},
-    {"zones", &zones, CONF_TYPE_STRING, 0, 0, 0, NULL},
-    {"subq", &subq, CONF_TYPE_INT, CONF_RANGE, 1, 7, NULL},
-    {"brdo", &bframe_rdo, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nobrdo", &bframe_rdo, CONF_TYPE_FLAG, 0, 0, 0, NULL},
-    {"me", &me_method, CONF_TYPE_INT, CONF_RANGE, 1, 4, NULL},
-    {"me_range", &me_range, CONF_TYPE_INT, CONF_RANGE, 4, 64, NULL},
-    {"trellis", &trellis, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL},
-    {"fast_pskip", &fast_pskip, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nofast_pskip", &fast_pskip, CONF_TYPE_FLAG, 0, 0, 0, NULL},
-    {"dct_decimate", &dct_decimate, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nodct_decimate", &dct_decimate, CONF_TYPE_FLAG, 0, 0, 0, NULL},
-    {"nr", &noise_reduction, CONF_TYPE_INT, CONF_RANGE, 0, 100000, NULL},
-    {"level_idc", &level_idc, CONF_TYPE_INT, CONF_RANGE, 10, 51, NULL},
-    {"threads", &threads, CONF_TYPE_INT, CONF_RANGE, 1, 4, NULL},
-    {"psnr", &psnr, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"nopsnr", &psnr, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"log", &log_level, CONF_TYPE_INT, CONF_RANGE, -1, 3, NULL},
-    {"turbo", &turbo, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL},
-    {"visualize", &visualize, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"novisualize", &visualize, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {"global", &globalheader, CONF_TYPE_FLAG, 0, 0, 1, NULL},
-    {"noglobal", &globalheader, CONF_TYPE_FLAG, 0, 1, 0, NULL},
-    {NULL, NULL, 0, 0, 0, 0, NULL}
-};
-
-static int parse_cqm(const char *str, uint8_t *cqm, int length,
-                     h264_module_t *mod, const char *matrix_name) {
-    int i;
-    if (!str) return 0;
-    for (i = 0; i < length; i++) {
-        long coef = strtol(str, &str, 0);
-        if (coef < 1 || coef > 255 || str[0] != ((i + 1 == length)?0:',')) {
-            mp_msg( MSGT_MENCODER, MSGL_ERR, "x264: Invalid entry in cqm%s at position %d.\n", matrix_name, i+1 );
-            return -1;
-        }
-        cqm[i] = coef;
-        str = &str[1];
-    }
-    mod->param.i_cqm_preset = X264_CQM_CUSTOM;
-    return 0;
-}
+char *x264encopts = "";
 
 static int encode_nals(uint8_t *buf, int size, x264_nal_t *nals, int nnal){
     uint8_t *p = buf;
@@ -251,146 +82,58 @@
     mod->mux->aspect = (float)d_width/d_height;
     
     x264_param_default(&mod->param);
-    mod->param.i_frame_reference = frame_ref;
-    mod->param.i_keyint_max = keyint_max;
-    mod->param.i_keyint_min = keyint_min;
-    mod->param.i_scenecut_threshold = scenecut_threshold;
-    mod->param.i_bframe = bframe;
-    mod->param.b_bframe_adaptive = bframe_adaptive;
-    mod->param.i_bframe_bias = bframe_bias;
-    mod->param.b_bframe_pyramid = bframe_pyramid;
-    mod->param.b_deblocking_filter = deblock;
-    mod->param.i_deblocking_filter_alphac0 = deblockalpha;
-    mod->param.i_deblocking_filter_beta = deblockbeta;
-    mod->param.b_cabac = cabac;
-
-    mod->param.rc.i_rc_method = X264_RC_CQP;
-    mod->param.rc.i_qp_constant = qp_constant;
-    if(rf_constant > 0)
-        mod->param.rc.i_rc_method = X264_RC_CRF;
-    mod->param.rc.i_rf_constant = rf_constant;
-    if(qp_min > qp_constant)
-        qp_min = qp_constant;
-    if(qp_max < qp_constant)
-        qp_max = qp_constant;
-    mod->param.rc.i_qp_min = qp_min;
-    mod->param.rc.i_qp_max = qp_max;
-    mod->param.rc.i_qp_step = qp_step;
-    mod->param.rc.psz_rc_eq = rc_eq;
-    mod->param.rc.f_qcompress = qcomp;
-    mod->param.rc.f_qblur = qblur;
-    mod->param.rc.f_complexity_blur = complexity_blur;
-    mod->param.analyse.i_subpel_refine = subq;
-    mod->param.rc.psz_stat_out = passtmpfile;
-    mod->param.rc.psz_stat_in = passtmpfile;
-    if((pass & 2) && bitrate <= 0)
-    {
-        mp_msg(MSGT_MENCODER, MSGL_ERR,
-               "2 pass encoding enabled, but no bitrate specified.\n");
-        return 0;
-    }
-    if(bitrate > 0) {
-        if((vbv_maxrate > 0) != (vbv_bufsize > 0)) {
-            mp_msg(MSGT_MENCODER, MSGL_ERR,
-                   "VBV requires both vbv_maxrate and vbv_bufsize.\n");
-            return 0;
-        }
-        mod->param.rc.i_rc_method = X264_RC_ABR;
-        mod->param.rc.i_bitrate = bitrate;
-        mod->param.rc.f_rate_tolerance = ratetol;
-        mod->param.rc.i_vbv_max_bitrate = vbv_maxrate;
-        mod->param.rc.i_vbv_buffer_size = vbv_bufsize;
-        mod->param.rc.f_vbv_buffer_init = vbv_init;
-    }
-    mod->param.rc.f_ip_factor = ip_factor;
-    mod->param.rc.f_pb_factor = pb_factor;
-    mod->param.rc.psz_zones = zones;
-    switch(me_method) {
-        case 1: mod->param.analyse.i_me_method = X264_ME_DIA; break;
-        case 2: mod->param.analyse.i_me_method = X264_ME_HEX; break;
-        case 3: mod->param.analyse.i_me_method = X264_ME_UMH; break;
-        case 4: mod->param.analyse.i_me_method = X264_ME_ESA; break;
-    }
-    mod->param.analyse.inter = 0;
-    if(p4x4mv) mod->param.analyse.inter |= X264_ANALYSE_PSUB8x8;
-    if(p8x8mv) mod->param.analyse.inter |= X264_ANALYSE_PSUB16x16;
-    if(b8x8mv) mod->param.analyse.inter |= X264_ANALYSE_BSUB16x16;
-    if(i4x4)   mod->param.analyse.inter |= X264_ANALYSE_I4x4;
-    if(i8x8)   mod->param.analyse.inter |= X264_ANALYSE_I8x8;
-    mod->param.analyse.b_transform_8x8 = dct8;
-    mod->param.analyse.i_direct_mv_pred = direct_pred;
-    mod->param.analyse.b_weighted_bipred = weight_b;
-    mod->param.analyse.i_chroma_qp_offset = chroma_qp_offset;
-    mod->param.analyse.b_bidir_me = bidir_me;
-    mod->param.analyse.b_chroma_me = chroma_me;
-    mod->param.analyse.b_mixed_references = mixed_references;
-    mod->param.analyse.i_trellis = trellis;
-    mod->param.analyse.b_fast_pskip = fast_pskip;
-    mod->param.analyse.b_dct_decimate = dct_decimate;
-    mod->param.analyse.i_noise_reduction = noise_reduction;
-    mod->param.analyse.b_bframe_rdo = bframe_rdo;
 
     mod->param.i_width = width;
     mod->param.i_height = height;
     mod->param.i_fps_num = mod->mux->h.dwRate;
     mod->param.i_fps_den = mod->mux->h.dwScale;
-    mod->param.i_level_idc = level_idc;
-    mod->param.analyse.b_psnr = psnr;
-    mod->param.i_log_level = log_level;
-    mod->param.b_visualize = visualize;
     mod->param.vui.i_sar_width = d_width*height;
     mod->param.vui.i_sar_height = d_height*width;
-    mod->param.i_threads = threads;
-    if(globalheader) mod->param.b_repeat_headers = 0;
+    x264_param_parse(&mod->param, "psnr", "no");
+    x264_param_parse(&mod->param, "ssim", "no");
+
+    while(*x264encopts) {
+        char *name = x264encopts;
+        char *value;
+        int ret;
+
+        x264encopts += strcspn(x264encopts, ":");
+        if(*x264encopts) {
+            *x264encopts = 0;
+            x264encopts++;
+        }
 
-    if(cqm != NULL)
-    {
-        if( !strcmp(cqm, "flat") )
-            mod->param.i_cqm_preset = X264_CQM_FLAT;
-        else if( !strcmp(cqm, "jvt") )
-            mod->param.i_cqm_preset = X264_CQM_JVT;
-        else
-        {
-            FILE *cqm_test;
-            cqm_test = fopen( cqm, "rb" );
-            if( cqm_test )
-            {
-                mod->param.i_cqm_preset = X264_CQM_CUSTOM;
-                mod->param.psz_cqm_file = cqm;
-                fclose( cqm_test );
-            }
-            else
-            {
-                mp_msg( MSGT_MENCODER, MSGL_ERR, "x264: CQM file failed to open.\n" );
-                return 0;
-            }
+        value = strchr( name, '=' );
+        if(value) {
+            *value = 0;
+            value++;
         }
+
+        if(!strcmp(name, "turbo")) {
+            turbo = value ? atoi(value) : 1;
+            continue;
+        }
+
+        ret = x264_param_parse(&mod->param, name, value);
+        if(ret == X264_PARAM_BAD_NAME)
+	    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: Unknown suboption %s\n", name);
+        if(ret == X264_PARAM_BAD_VALUE)
+	    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option x264encopts: Bad argument %s=%s\n", name, value ? value : "(null)");
+        if(ret)
+            return 0;
     }
 
-    if( (parse_cqm(cqm4iy, mod->param.cqm_4iy, 16, mod, "4iy") < 0) ||
-        (parse_cqm(cqm4ic, mod->param.cqm_4ic, 16, mod, "4ic") < 0) ||
-        (parse_cqm(cqm4py, mod->param.cqm_4py, 16, mod, "4py") < 0) ||
-        (parse_cqm(cqm4pc, mod->param.cqm_4pc, 16, mod, "4pc") < 0) ||
-        (parse_cqm(cqm8iy, mod->param.cqm_8iy, 64, mod, "8iy") < 0) ||
-        (parse_cqm(cqm8py, mod->param.cqm_8py, 64, mod, "8py") < 0) )
-        return 0;
-
-    switch(pass) {
-    case 0:
-        mod->param.rc.b_stat_write = 0;
-        mod->param.rc.b_stat_read = 0;
-        break;
-    case 1:
+    if(mod->param.rc.b_stat_write) {
         /* Adjust or disable some flags to gain speed in the first pass */
         if(turbo == 1)
         {
-            mod->param.i_frame_reference = ( frame_ref + 1 ) >> 1;
-            mod->param.analyse.i_subpel_refine = max( min( 3, subq - 1 ), 1 );
+            mod->param.i_frame_reference = ( mod->param.i_frame_reference + 1 ) >> 1;
+            mod->param.analyse.i_subpel_refine = max( min( 3, mod->param.analyse.i_subpel_refine - 1 ), 1 );
             mod->param.analyse.inter &= ( ~X264_ANALYSE_PSUB8x8 );
             mod->param.analyse.inter &= ( ~X264_ANALYSE_BSUB16x16 );
             mod->param.analyse.i_trellis = 0;
         }
-        else if(turbo == 2)
+        else if(turbo >= 2)
         {
             mod->param.i_frame_reference = 1;
             mod->param.analyse.i_subpel_refine = 1;
@@ -400,22 +143,8 @@
             mod->param.analyse.b_weighted_bipred = 0;
             mod->param.analyse.i_trellis = 0;
         }
-        mod->param.rc.b_stat_write = 1;
-        mod->param.rc.b_stat_read = 0;
-        break;
-    case 2:
-        mod->param.rc.b_stat_write = 0;
-        mod->param.rc.b_stat_read = 1;
-        break;
-    case 3:
-        mod->param.rc.b_stat_write = 1;
-        mod->param.rc.b_stat_read = 1;
-        break;
     }
 
-    if(me_method >= 3)
-        mod->param.analyse.i_me_range = me_range;
-
     switch(outfmt) {
     case IMGFMT_I420:
         mod->param.i_csp = X264_CSP_I420;
@@ -460,7 +189,7 @@
         return 0;
     }
 
-    if(globalheader){
+    if(!mod->param.b_repeat_headers){
         uint8_t *extradata;
         x264_nal_t *nal;
         int extradata_size, nnal, i, s = 0;
@@ -489,9 +218,10 @@
 
 static int control(struct vf_instance_s* vf, int request, void *data)
 {
+    h264_module_t *mod=(h264_module_t*)vf->priv;
     switch(request){
         case VFCTRL_FLUSH_FRAMES:
-            if(bframe)
+            if(mod->param.i_bframe)
                 while(encode_frame(vf, NULL) > 0);
             return CONTROL_TRUE;
         default:
@@ -557,7 +287,8 @@
     if(i_size>0) {
         int keyframe = (pic_out.i_type == X264_TYPE_IDR) ||
                        (pic_out.i_type == X264_TYPE_I
-                        && frame_ref == 1 && !bframe);
+                        && mod->param.i_frame_reference == 1
+                        && !mod->param.i_bframe);
         muxer_write_chunk(mod->mux, i_size, keyframe?0x10:0, MP_NOPTS_VALUE, MP_NOPTS_VALUE);
     }
     else