summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authorgpoirier <gpoirier@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-06-02 22:01:38 +0000
committergpoirier <gpoirier@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-06-02 22:01:38 +0000
commite6f5f5a1875f243fcad2ec94c668b4da8d1410f7 (patch)
tree58e814df506d1ebbfabd9cf4c5c02c2a5f6a4c93 /libmpcodecs
parentd4eed8f8d25ff5162652a10894af34183f777b37 (diff)
downloadmpv-e6f5f5a1875f243fcad2ec94c668b4da8d1410f7.tar.bz2
mpv-e6f5f5a1875f243fcad2ec94c668b4da8d1410f7.tar.xz
XviD zones support. Patch by Doom9: < feedback123 GROOVY doom9 STEADY org >
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@15620 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/ve_xvid4.c68
1 files changed, 66 insertions, 2 deletions
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);
}