changeset 11912:8eb96d751dcd

new options - aspect,autoaspect,turbo,chroma_opt. patch by Nico <nsabbi@tiscali.it> and Edouard Gomez
author iive
date Mon, 02 Feb 2004 19:51:39 +0000
parents bca87badd7ee
children 60a38618e6e4
files libmpcodecs/ve_xvid4.c
diffstat 1 files changed, 146 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/ve_xvid4.c	Mon Feb 02 14:28:08 2004 +0000
+++ b/libmpcodecs/ve_xvid4.c	Mon Feb 02 19:51:39 2004 +0000
@@ -52,6 +52,7 @@
 #include <stdio.h>
 #include <stdarg.h>
 #include <limits.h>
+#include <assert.h>
 
 #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
  ****************************************************************************/
@@ -76,14 +157,16 @@
 static int xvidenc_cartoon = 0;
 static int xvidenc_hqacpred = 1;
 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);
 
 	/*--------------------------------------------------------------------
@@ -518,6 +612,7 @@
 	xvid_enc_frame_t  *frame      = &mod->frame;
 	xvid_plugin_single_t *onepass = &mod->onepass;
 	xvid_plugin_2pass2_t *pass2   = &mod->pass2;
+	XVIDRational ar;
 
 	const int motion_presets[7] =
 		{
@@ -652,6 +747,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 +772,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 +790,46 @@
 
 	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) 
+	    ar = xvid_d2q(xvidenc_dar_aspect * mod->mux->bih->biHeight / mod->mux->bih->biWidth, 255);
+	else if(xvidenc_autoaspect)
+	    ar = xvid_d2q((float)mod->d_width / mod->d_height * mod->mux->bih->biHeight / mod->mux->bih->biWidth, 255);
+	else ar.num = ar.den = 0;
+	
+	if(ar.den != 0) {
+		if(ar.num == 12 && ar.den == 11)
+		    frame->par = XVID_PAR_43_PAL;
+		else if(ar.num == 10 && ar.den == 11)
+		    frame->par = XVID_PAR_43_NTSC;
+		else if(ar.num == 16 && ar.den == 11)
+		    frame->par = XVID_PAR_169_PAL;
+		else if(ar.num == 40 && ar.den == 33)
+		    frame->par = XVID_PAR_169_NTSC;
+		else
+		{    
+		    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 code %d, Display frame: (%d, %d), original frame: (%d, %d)\n", 
+	    	    ar.num, ar.den, frame->par,
+		    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 +841,7 @@
 		else
 			frame->par_height = 1;
 	}
-
+	}
 	return;
 }