From e71314fcc9b9e885c1a6c84902d2719457467c7b Mon Sep 17 00:00:00 2001 From: lorenm Date: Wed, 12 Jan 2005 09:54:56 +0000 Subject: [PATCH] sync to x264 r93: Change the mechanics of option "keyint": Now controls the GOP size directly and allows variable numbers of non-IDR I-frames within a GOP. Remove option "idrint" and replace it with "keyint_min". Add option "8x8mv" for the sake of completeness. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@14469 b3059339-0415-0410-9bf9-f77b7e298cf2 --- DOCS/man/en/mplayer.1 | 25 +++++++++++++++++++------ libmpcodecs/ve_x264.c | 24 +++++++++++++++--------- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1 index 7eeb6b656a..7336162d19 100644 --- a/DOCS/man/en/mplayer.1 +++ b/DOCS/man/en/mplayer.1 @@ -7062,11 +7062,11 @@ 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). Lower values result in better fidelity, but higher bitrates. -Note that quantization in H.264 works differently from MPEG-[124]. +Note that quantization in H.264 works differently from MPEG-1/2/4. H.264's quantization parameter (QP) is on a logarithmic scale. As an example, the bitrate difference between QP=20 and QP=40 is about a factor of 10. -Useful quantizers in H.264 tend to be very large compared to MPEG-[124]. +Useful quantizers in H.264 tend to be very large compared to MPEG-1/2/4. . .TP .B pass=<1\-3> @@ -7118,13 +7118,17 @@ both fast and provide good quality. . .TP .B keyint= -Sets maximum interval between I-frames. +Sets maximum interval between IDR-frames (default: 250). Larger values save bits, thus improve quality, at the cost of seeking -precision (default: 250). +precision. +Unlike MPEG-1/2/4, H.264 does not suffer from DCT drift with large +values of keyint. . .TP -.B idrint= -Make each I-frame an IDR-frame (default: 2). +.B keyint_min=<1\-keyint/2> +Sets minimum interval between IDR-frames (default: keyint * 0.4). +If scenecuts appear within this interval, they are still encoded as +I-frames, but do not start a new GOP. In H.264, I-frames do not necessarily bound a closed GOP because it is allowable for a P-frame to be predicted from more frames than just the one frame before it (also see frameref). @@ -7290,10 +7294,19 @@ i16x16, 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, 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, i4x4, p16x16, p16x8, p8x16, p8x8, skip. +Requires 8x8mv. .br The idea is to find the type and size that best describe a certain area of the picture. diff --git a/libmpcodecs/ve_x264.c b/libmpcodecs/ve_x264.c index d4623d9613..c48bb71955 100644 --- a/libmpcodecs/ve_x264.c +++ b/libmpcodecs/ve_x264.c @@ -49,7 +49,7 @@ #include -#if X264_BUILD < 0x000d +#if X264_BUILD < 0x000e #error We do not support old versions of x264. Get the latest from SVN. #endif @@ -65,8 +65,8 @@ extern char* passtmpfile; static int bitrate = -1; static int qp_constant = 26; static int frame_ref = 1; -static int iframe = 250; -static int idrframe = 2; +static int keyint_max = 250; +static int keyint_min = -1; static int scenecut_threshold = 40; static int bframe = 0; static int deblock = 1; @@ -75,6 +75,7 @@ static int deblockbeta = 0; static int cabac = 1; static int cabacidc = -1; static int p4x4mv = 0; +static int p8x8mv = 1; static int b8x8mv = 1; static int direct_pred = X264_DIRECT_PRED_TEMPORAL; static float ip_factor = 1.4; @@ -98,8 +99,8 @@ m_option_t x264encopts_conf[] = { {"bitrate", &bitrate, CONF_TYPE_INT, CONF_RANGE, 0, 24000000, NULL}, {"qp_constant", &qp_constant, CONF_TYPE_INT, CONF_RANGE, 1, 51, NULL}, {"frameref", &frame_ref, CONF_TYPE_INT, CONF_RANGE, 1, 15, NULL}, - {"keyint", &iframe, CONF_TYPE_INT, CONF_RANGE, 1, 24000000, NULL}, - {"idrint", &idrframe, CONF_TYPE_INT, CONF_RANGE, 1, 24000000, 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}, {"deblock", &deblock, CONF_TYPE_FLAG, 0, 0, 1, NULL}, @@ -111,6 +112,8 @@ m_option_t x264encopts_conf[] = { {"cabacidc", &cabacidc, CONF_TYPE_INT, CONF_RANGE, -1, 2, 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}, {"direct_pred", &direct_pred, CONF_TYPE_INT, CONF_RANGE, 0, 2, NULL}, @@ -143,8 +146,8 @@ static int config(struct vf_instance_s* vf, int width, int height, int d_width, x264_param_default(&mod->param); mod->param.i_frame_reference = frame_ref; - mod->param.i_idrframe = idrframe; - mod->param.i_iframe = iframe; + mod->param.i_keyint_max = keyint_max; + mod->param.i_keyint_min = keyint_min > 0 ? keyint_min : keyint_max * 2 / 5; mod->param.i_scenecut_threshold = scenecut_threshold; mod->param.i_bframe = bframe; mod->param.b_deblocking_filter = deblock; @@ -206,9 +209,11 @@ static int config(struct vf_instance_s* vf, int width, int height, int d_width, } mod->param.rc.f_ip_factor = ip_factor; mod->param.rc.f_pb_factor = pb_factor; - mod->param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16; + mod->param.analyse.inter = X264_ANALYSE_I4x4; 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; mod->param.analyse.i_direct_mv_pred = direct_pred; @@ -324,7 +329,8 @@ static int put_image(struct vf_instance_s *vf, mp_image_t *mpi) } if(i_size>0) { int keyframe = (mod->pic.i_type == X264_TYPE_IDR) || - (mod->pic.i_type == X264_TYPE_I && frame_ref == 1); + (mod->pic.i_type == X264_TYPE_I + && frame_ref == 1 && !bframe); muxer_write_chunk(mod->mux, i_size, keyframe?0x10:0); } return 1;