1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-19 05:15:12 +00:00

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.


git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@20060 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
lorenm 2006-10-05 02:03:10 +00:00
parent 1240e6bde5
commit 0594cd07a0
4 changed files with 98 additions and 375 deletions

View File

@ -9014,7 +9014,7 @@ Constant bitrate can be achieved by combining this with vbv_maxrate,
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 @@ As it takes very little time compared to its quality gain, it is not
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 @@ Secondly, this parameter affects the threshold for difference across the
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 @@ maximum quantizer (default: 51)
.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 @@ to overflow compensation and qp_min/qp_max.
.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 @@ of the B-frame relative to the references.
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 @@ Also allows the i8x8 macroblock type.
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 @@ rate-distortion optimal quantization
.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 @@ Requires that libx264 was compiled with pthread support; if not, this
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.

View File

@ -43,7 +43,7 @@ extern m_option_t xvidencopts_conf[];
#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 @@ m_option_t mencoder_opts[]={
{"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},

2
configure vendored
View File

@ -6511,7 +6511,7 @@ if test "$_x264" = auto ; then
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; }

View File

@ -55,177 +55,8 @@ typedef struct _h264_module_t {
} 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 @@ static int config(struct vf_instance_s* vf, int width, int height, int d_width,
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");
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;
}
while(*x264encopts) {
char *name = x264encopts;
char *value;
int ret;
x264encopts += strcspn(x264encopts, ":");
if(*x264encopts) {
*x264encopts = 0;
x264encopts++;
}
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 @@ static int config(struct vf_instance_s* vf, int width, int height, int d_width,
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 @@ static int config(struct vf_instance_s* vf, int width, int height, int d_width,
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 config(struct vf_instance_s* vf, int width, int height, int d_width,
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 @@ static int encode_frame(struct vf_instance_s *vf, x264_picture_t *pic_in)
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