--- ve_xvid4.c.orig 2004-01-25 13:17:10.000000000 +0100 +++ ve_xvid4.c 2004-01-25 15:02:20.000000000 +0100 @@ -52,6 +52,7 @@ #include #include #include +#include #include "m_option.h" @@ -59,6 +60,86 @@ #define FINE (!0) #define BAD (!FINE) +// Code taken from Libavcodec and ve_lavc.c to handle Aspect Ratio calculation + +typedef struct XVIDRational{ + int num; + int den; +} XVIDRational; + +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define ABS(a) ((a) >= 0 ? (a) : (-(a))) + + +static int64_t xvid_gcd(int64_t a, int64_t b){ + if(b) return xvid_gcd(b, a%b); + else return a; +} + +static int xvid_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ + int exact=1, sign=0; + int64_t gcd; + + assert(den != 0); + + if(den < 0){ + den= -den; + nom= -nom; + } + + if(nom < 0){ + nom= -nom; + sign= 1; + } + + gcd = xvid_gcd(nom, den); + nom /= gcd; + den /= gcd; + + if(nom > max || den > max){ + XVIDRational a0={0,1}, a1={1,0}; + exact=0; + + for(;;){ + int64_t x= nom / den; + int64_t a2n= x*a1.num + a0.num; + int64_t a2d= x*a1.den + a0.den; + + if(a2n > max || a2d > max) break; + + nom %= den; + + a0= a1; + a1= (XVIDRational){a2n, a2d}; + if(nom==0) break; + x= nom; nom=den; den=x; + } + nom= a1.num; + den= a1.den; + } + + assert(xvid_gcd(nom, den) == 1); + + if(sign) nom= -nom; + + *dst_nom = nom; + *dst_den = den; + + return exact; +} + + +static XVIDRational xvid_d2q(double d, int max){ + XVIDRational a; + int exponent= MAX( (int)(log(ABS(d) + 1e-20)/log(2)), 0); + int64_t den= 1LL << (61 - exponent); + xvid_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max); + + return a; +} + + + /***************************************************************************** * Configuration options ****************************************************************************/ @@ -74,16 +155,18 @@ static int xvidenc_gmc = 0; static int xvidenc_trellis = 0; static int xvidenc_cartoon = 0; -static int xvidenc_hqacpred = 1; +static int xvidenc_hqacpred = 0; static int xvidenc_chromame = 0; +static int xvidenc_chroma_opt = 0; static int xvidenc_vhq = 0; static int xvidenc_motion = 6; +static int xvidenc_turbo = 0; static int xvidenc_stats = 0; -static int xvidenc_max_key_interval = 0; +static int xvidenc_max_key_interval = 0; /* Let xvidcore set a 10s interval by default */ static int xvidenc_frame_drop_ratio = 0; static int xvidenc_greyscale = 0; -static int xvidenc_max_bframes = 0; +static int xvidenc_max_bframes = 2; static int xvidenc_bquant_ratio = 150; static int xvidenc_bquant_offset = 100; static int xvidenc_bframe_threshold = 0; @@ -99,18 +182,20 @@ static int xvidenc_cbr_buffer = 0; static int xvidenc_vbr_keyframe_boost = 0; -static int xvidenc_vbr_overflow_control_strength = 0; +static int xvidenc_vbr_overflow_control_strength = 5; static int xvidenc_vbr_curve_compression_high = 0; static int xvidenc_vbr_curve_compression_low = 0; -static int xvidenc_vbr_max_overflow_improvement = 0; -static int xvidenc_vbr_max_overflow_degradation = 0; +static int xvidenc_vbr_max_overflow_improvement = 5; +static int xvidenc_vbr_max_overflow_degradation = 5; static int xvidenc_vbr_kfreduction = 0; static int xvidenc_vbr_kfthreshold = 0; -static int xvidenc_vbr_container_frame_overhead = 0; +static int xvidenc_vbr_container_frame_overhead = 24; /* mencoder uses AVI container */ static char *xvidenc_par = NULL; static int xvidenc_par_width = 0; static int xvidenc_par_height = 0; +static float xvidenc_dar_aspect = 0.0f; +static int xvidenc_autoaspect = 0; m_option_t xvidencopts_conf[] = { @@ -123,6 +208,7 @@ {"quant_type", &xvidenc_quant_method, CONF_TYPE_STRING, 0, 0, 0, NULL}, {"me_quality", &xvidenc_motion, CONF_TYPE_INT, CONF_RANGE, 0, 6, NULL}, {"chroma_me", &xvidenc_chromame, CONF_TYPE_FLAG, 0, 0, 1, NULL}, + {"chroma_opt", &xvidenc_chroma_opt, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"vhq", &xvidenc_vhq, CONF_TYPE_INT, CONF_RANGE, 0, 4, NULL}, {"max_bframes", &xvidenc_max_bframes, CONF_TYPE_INT, CONF_RANGE, 0, 20, NULL}, {"bquant_ratio", &xvidenc_bquant_ratio, CONF_TYPE_INT, CONF_RANGE, 0, 200, NULL}, @@ -139,6 +225,7 @@ {"frame_drop_ratio", &xvidenc_frame_drop_ratio, CONF_TYPE_INT, CONF_RANGE, 0, 100, NULL}, {"max_key_interval", &xvidenc_max_key_interval, CONF_TYPE_INT, CONF_MIN, 0, 0, NULL}, {"greyscale", &xvidenc_greyscale, CONF_TYPE_FLAG, 0, 0, 1, NULL}, + {"turbo", &xvidenc_turbo, CONF_TYPE_FLAG, 0, 0, 1, NULL}, {"stats", &xvidenc_stats, CONF_TYPE_FLAG, 0, 0, 1, NULL}, @@ -172,6 +259,8 @@ {"par", &xvidenc_par, CONF_TYPE_STRING, 0, 0, 0, NULL}, {"par_width", &xvidenc_par_width, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL}, {"par_height", &xvidenc_par_height, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL}, + {"aspect", &xvidenc_dar_aspect, CONF_TYPE_FLOAT, CONF_RANGE, 0.1, 9.99, NULL}, + {"autoaspect", &xvidenc_autoaspect, CONF_TYPE_FLAG, 0, 0, 1, NULL}, /* End of the config array */ {NULL, 0, 0, 0, 0, 0, NULL} @@ -212,6 +301,8 @@ int max_sse_y; int max_sse_u; int max_sse_v; + + int d_width, d_height; } xvid_mplayer_module_t; static void dispatch_settings(xvid_mplayer_module_t *mod); @@ -251,6 +342,9 @@ * Dispatch all module settings to XviD structures *------------------------------------------------------------------*/ + mod->d_width = d_width; + mod->d_height = d_height; + dispatch_settings(mod); /*-------------------------------------------------------------------- @@ -652,6 +746,9 @@ if(xvidenc_hqacpred) { frame->vop_flags |= XVID_VOP_HQACPRED; } + if(xvidenc_chroma_opt) { + frame->vop_flags |= XVID_VOP_CHROMAOPT; + } if(xvidenc_motion > 4) { frame->vop_flags |= XVID_VOP_INTER4V; } @@ -674,6 +771,13 @@ if(xvidenc_vhq >= 4) { frame->motion |= XVID_ME_EXTSEARCH_RD; } + if(xvidenc_turbo) { + frame->motion |= XVID_ME_FASTREFINE16; + frame->motion |= XVID_ME_FASTREFINE8; + frame->motion |= XVID_ME_SKIP_DELTASEARCH; + frame->motion |= XVID_ME_FAST_MODEINTERPOLATE; + frame->motion |= XVID_ME_BFRAME_EARLYSTOP; + } /* motion level == 0 means no motion search which is equivalent to * intra coding only */ @@ -685,22 +789,43 @@ frame->bframe_threshold = xvidenc_bframe_threshold; - frame->par = 0; - if(xvidenc_par != NULL) { + /* PAR related initialization */ + frame->par = XVID_PAR_11_VGA; /* Default */ + + if(xvidenc_dar_aspect > 0) { + XVIDRational ar; + + ar = xvid_d2q(xvidenc_dar_aspect * mod->mux->bih->biHeight / mod->mux->bih->biWidth, 255); + frame->par = XVID_PAR_EXT; + frame->par_width = ar.num; + frame->par_height= ar.den; + + mp_msg(MSGT_MENCODER, MSGL_INFO, "XVID4_DAR: %d/%d, Original frame: (%d, %d), Display frame: (%d, %d)\n", + ar.num, ar.den, + mod->d_width, mod->d_height, mod->mux->bih->biWidth, mod->mux->bih->biHeight); + } else if(xvidenc_autoaspect) { + XVIDRational ar; + + ar = xvid_d2q((float)mod->d_width / mod->d_height * mod->mux->bih->biHeight / mod->mux->bih->biWidth, 255); + frame->par = XVID_PAR_EXT; + frame->par_width = ar.num; + frame->par_height= ar.den; + + mp_msg(MSGT_MENCODER, MSGL_INFO, "XVID4_DAR: %d/%d, Original frame: (%d, %d), Display frame: (%d, %d)\n", + ar.num, ar.den, + mod->d_width, mod->d_height, mod->mux->bih->biWidth, mod->mux->bih->biHeight); + } else if(xvidenc_par != NULL) { if(strcasecmp(xvidenc_par, "pal43") == 0) frame->par = XVID_PAR_43_PAL; - if(strcasecmp(xvidenc_par, "pal169") == 0) + else if(strcasecmp(xvidenc_par, "pal169") == 0) frame->par = XVID_PAR_169_PAL; - if(strcasecmp(xvidenc_par, "ntsc43") == 0) + else if(strcasecmp(xvidenc_par, "ntsc43") == 0) frame->par = XVID_PAR_43_NTSC; - if(strcasecmp(xvidenc_par, "ntsc169") == 0) + else if(strcasecmp(xvidenc_par, "ntsc169") == 0) frame->par = XVID_PAR_169_NTSC; - if(strcasecmp(xvidenc_par, "ext") == 0) + else if(strcasecmp(xvidenc_par, "ext") == 0) frame->par = XVID_PAR_EXT; - } - if(frame->par == 0) { - frame->par = XVID_PAR_11_VGA; - } + if(frame->par == XVID_PAR_EXT) { if(xvidenc_par_width) frame->par_width = xvidenc_par_width; @@ -712,7 +837,7 @@ else frame->par_height = 1; } - + } return; } @@ -1011,6 +1136,7 @@ return((const char *)error); } + /***************************************************************************** * Module structure definition ****************************************************************************/