# HG changeset patch # User gpoirier # Date 1117749698 0 # Node ID ccf2c61afacd75c5f5476b153bd45af8c8f8d3d2 # Parent 1965072518bec3a5d652d8c34e14f695900e17f0 XviD zones support. Patch by Doom9: < feedback123 GROOVY doom9 STEADY org > diff -r 1965072518be -r ccf2c61afacd ChangeLog --- a/ChangeLog Thu Jun 02 21:16:21 2005 +0000 +++ b/ChangeLog Thu Jun 02 22:01:38 2005 +0000 @@ -34,6 +34,7 @@ * 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 -r 1965072518be -r ccf2c61afacd DOCS/man/en/mplayer.1 --- a/DOCS/man/en/mplayer.1 Thu Jun 02 21:16:21 2005 +0000 +++ b/DOCS/man/en/mplayer.1 Thu Jun 02 22:01:38 2005 +0000 @@ -7269,6 +7269,36 @@ Switch to fixed quantizer mode and specify the quantizer to be used. . .TP +.B zones=[/\:[/\:...]] +User specified quality for specific parts (ending, credits, ...) +(ABR or two pass). +Each zone is ,, where 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 -r 1965072518be -r ccf2c61afacd libmpcodecs/ve_xvid4.c --- a/libmpcodecs/ve_xvid4.c Thu Jun 02 21:16:21 2005 +0000 +++ b/libmpcodecs/ve_xvid4.c Thu Jun 02 22:01:38 2005 +0000 @@ -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 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 @@ {"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 @@ /* 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 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 @@ 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 @@ 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); }