summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--DOCS/man/en/mplayer.130
-rw-r--r--libmpcodecs/ve_xvid4.c68
3 files changed, 97 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index eabc40e7eb..e4796059c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -34,6 +34,7 @@ MPlayer (1.0)
* audio encoding modularized
* AAC (FAAC) audio encoding
* border processing adaptive quantization in libavcodec
+ * XviD's encoding zones
Ports:
* improved timer function on Mac OS X
diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1
index 9091f0299b..62d8384a56 100644
--- a/DOCS/man/en/mplayer.1
+++ b/DOCS/man/en/mplayer.1
@@ -7269,6 +7269,36 @@ If <value> is negative, XviD will use its absolute value as the target size
Switch to fixed quantizer mode and specify the quantizer to be used.
.
.TP
+.B zones=<zone0>[/\:<zone1>[/\:...]]
+User specified quality for specific parts (ending, credits, ...)
+(ABR or two pass).
+Each zone is <start-frame>,<mode>,<value> where <mode> may be
+.PD 0
+.RSs
+.IPs "q"
+constant quantizer override.
+In that case, value=<2.0\-31.0> represents the quantizer value.
+.IPs "w"
+ratecontrol weight override.
+In that case, value=<0.01\-2.00> represents the quality correction in %.
+.RE
+.PD 1
+.RS
+.I EXAMPLE:
+.RE
+.RSs
+.IPs zones=90000,q,20
+Encodes all frames starting with frame 90000 at constant quantizer 20.
+.IPs zones=0,w,0.1/10001,w,1.0/90000,q,20
+Encode frames 0\-10000 at 10% bitrate, encode frames 90000 and
+up to the end at constant quantizer 20.
+Note that the second zone is needed to delimit the first zone, as
+without it everything up until frame 89999 would be encoded at 10%
+bitrate.
+.RE
+.PD 1
+.
+.TP
.B me_quality=<0\-6>
This option controls the motion estimation subsystem.
The higher the value, the more precise the estimation should be (default: 6).
diff --git a/libmpcodecs/ve_xvid4.c b/libmpcodecs/ve_xvid4.c
index 07e350c3e8..3a60e2202a 100644
--- a/libmpcodecs/ve_xvid4.c
+++ b/libmpcodecs/ve_xvid4.c
@@ -61,6 +61,8 @@
#define FINE (!0)
#define BAD (!FINE)
+#define MAX_ZONES 64
+
// Code taken from Libavcodec and ve_lavc.c to handle Aspect Ratio calculation
typedef struct xvid_rational_s{
@@ -201,6 +203,8 @@ static int xvidenc_par_height = 0;
static float xvidenc_dar_aspect = 0.0f;
static int xvidenc_autoaspect = 0;
+static char *xvidenc_zones = NULL; // zones string
+
m_option_t xvidencopts_conf[] =
{
/* Standard things mencoder should be able to treat directly */
@@ -281,6 +285,9 @@ m_option_t xvidencopts_conf[] =
{"autoaspect", &xvidenc_autoaspect, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{"noautoaspect", &xvidenc_autoaspect, CONF_TYPE_FLAG, 0, 1, 0, NULL},
+ /* Section Zones */
+ {"zones", &xvidenc_zones, CONF_TYPE_STRING, 0, 0, 0, NULL},
+
/* End of the config array */
{NULL, 0, 0, 0, 0, 0, NULL}
};
@@ -302,7 +309,7 @@ typedef struct _xvid_mplayer_module_t
/* This data must survive local block scope, so here it is */
xvid_enc_plugin_t plugins[7];
- xvid_enc_zone_t zones[1];
+ xvid_enc_zone_t zones[MAX_ZONES];
/* MPEG4 stream buffer */
muxer_stream_t *mux;
@@ -873,6 +880,7 @@ static void dispatch_settings(xvid_mplayer_module_t *mod)
static int set_create_struct(xvid_mplayer_module_t *mod)
{
int pass;
+ int doZones = 0;
xvid_enc_create_t *create = &mod->create;
/* Most of the structure is initialized by dispatch settings, only a
@@ -988,6 +996,7 @@ static int set_create_struct(xvid_mplayer_module_t *mod)
mp_msg(MSGT_MENCODER, MSGL_INFO,
"xvid: CBR Rate Control -- bitrate=%dkbit/s\n",
xvidenc_bitrate>16000?xvidenc_bitrate/1000:xvidenc_bitrate);
+ doZones = 1;
}
create->plugins[create->num_plugins].func = xvid_plugin_single;
@@ -1038,8 +1047,63 @@ static int set_create_struct(xvid_mplayer_module_t *mod)
create->plugins[create->num_plugins].func = xvid_plugin_2pass2;
create->plugins[create->num_plugins].param = pass2;
create->num_plugins++;
+ doZones = 1;
+ }
+ // parse zones
+ if (xvidenc_zones != NULL && doZones > 0) // do not apply zones in CQ, and first pass mode (xvid vfw doesn't allow them in those modes either)
+ {
+ void *p;
+ int i;
+ p = xvidenc_zones;
+ create->num_zones = 0; // set the number of zones back to zero, this overwrites the zone defined for CQ - desired because each zone has to be specified on the commandline even in cq mode
+ for(i = 0; p; i++)
+ {
+ int start;
+ double value;
+ char mode;
+ int e = sscanf(p, "%d,%c,%lf", &start, &mode, &value); // start,mode(q = constant quant, w = weight),value
+ if(e != 3)
+ {
+ mp_msg(MSGT_MENCODER,MSGL_ERR, "error parsing zones\n");
+ return(BAD);
+ }
+ int q = (int)(value * 100);
+ if (mode == 'q')
+ {
+ if (q < 200 || q > 3100) // make sure that quantizer is in allowable range
+ {
+ mp_msg(MSGT_MENCODER, MSGL_ERR, "zone quantizer must be between 2 and 31\n");
+ return(BAD);
+ }
+ else
+ {
+ create->zones[create->num_zones].mode = XVID_ZONE_QUANT;
+ }
+ }
+ if (mode == 'w')
+ {
+ if (q < 1 || q > 200)
+ {
+ mp_msg(MSGT_MENCODER, MSGL_ERR, "zone weight must be between 1 and 200\n");
+ return(BAD);
+ }
+ else
+ {
+ create->zones[create->num_zones].mode = XVID_ZONE_WEIGHT;
+ }
+ }
+ create->zones[create->num_zones].frame = start;
+ create->zones[create->num_zones].increment = q;
+ create->zones[create->num_zones].base = 100; // increment is 100 times the actual value
+ create->num_zones++;
+ if (create->num_zones > MAX_ZONES) // show warning if we have too many zones
+ {
+ mp_msg(MSGT_MENCODER, MSGL_ERR, "too many zones, zones will be ignored\n");
+ }
+ p = strchr(p, '/');
+ if(p) p++;
+ }
}
-
return(FINE);
}