[XviD-devel] [PATCH] vbv_peakrate cleanups
Lasse Collin
lasse.collin at tukaani.org
Fri Nov 12 11:05:49 CET 2010
vbv_peakrate confused me until I understood that it is completely
useless at least with currently existing profiles. Even if it is
useless, maybe a few things could be cleaned up to make it less
confusing.
src/xvid.h says that vbv_peakrate is "max average bitrate over three
seconds (bits per second)". That is, the unit of vbv_peakrate is bits
per *one* second, not bits per three seconds.
src/plugins/plugin_2pass2.c seems to agree with xvid.h.
check_curve_for_vbv_compliancy() multiplies vbv_peakrate by 3 to
compare it against the number of bits used in a 3-second window:
const float peakrate = (float)rc->param.vbv_peakrate;
...
/* ignore peakrate constraint if peakrate is <= 0.f */
if (peakrate>0.f && 8.f*bytes3s > 3*peakrate)
return(VBV_PEAKRATE);
Earlier in plugin_2pass2.c, if VBV_FORCE is defined, vbv_peakrate is
forced to 8 Mbit/s:
/* Check curve for VBV compliancy and rescale if necessary */
#ifdef VBV_FORCE
if (rc->param.vbv_size==0) {
rc->param.vbv_size = 3145728;
rc->param.vbv_initial = 2359296;
rc->param.vbv_maxrate = 4854000;
rc->param.vbv_peakrate = 8000000;
}
#endif
8 Mbit/s is also used e.g. by Home profile defined in vfw/src/config.c.
vfw/src/codec.c multiplies the specified peakrate by 3:
// XXX: xvidcore current provides a "peak bits over 3secs" constraint.
// according to the latest dxn literature, a 1sec constraint is now used
pass2.vbv_peakrate = profiles[codec->config.profile].vbv_peakrate * 3;
As I understand it, one-second peakrate constraint is stricter than
three-second constraint. Multiplying the value (e.g. 8 Mbit/s)
by three just triples the peakrate (e.g. to 24 Mbit/s = 72 Mbit per
3 seconds). If one-second peakrate is wanted, the code that checks
the peakrate should be changed.
examples/xvid_encraw.c seems to multiply the argument given to
-vbvpeak by 9. When parsing the options, it is multiplied by 3:
} else if (strcmp("-vbvpeak", argv[i]) == 0 && i < argc -1) {
i++;
ARG_VBVPEAKRATE = atoi(argv[i])*3;
When it is assigned to rc2pass2 structure, it's multiplied again:
rc2pass2.vbv_peakrate = ARG_VBVPEAKRATE*3;
The following patch omits the multiplications from codec.c and
xvid_encraw.c:
diff -ruw xvid_20101108.orig/xvidcore/examples/xvid_encraw.c xvid_20101108/xvidcore/examples/xvid_encraw.c
--- xvid_20101108.orig/xvidcore/examples/xvid_encraw.c 2010-10-10 22:20:03.000000000 +0300
+++ xvid_20101108/xvidcore/examples/xvid_encraw.c 2010-11-08 11:26:59.490001564 +0200
@@ -700,7 +700,7 @@
ARG_VBVMAXRATE = atoi(argv[i]);
} else if (strcmp("-vbvpeak", argv[i]) == 0 && i < argc -1) {
i++;
- ARG_VBVPEAKRATE = atoi(argv[i])*3;
+ ARG_VBVPEAKRATE = atoi(argv[i]);
} else if (strcmp("-reaction", argv[i]) == 0 && i < argc -1) {
i++;
ARG_REACTION = atoi(argv[i]);
@@ -2178,7 +2178,7 @@
rc2pass2.vbv_size = ARG_VBVSIZE;
rc2pass2.vbv_initial = (ARG_VBVSIZE*3)/4;
rc2pass2.vbv_maxrate = ARG_VBVMAXRATE;
- rc2pass2.vbv_peakrate = ARG_VBVPEAKRATE*3;
+ rc2pass2.vbv_peakrate = ARG_VBVPEAKRATE;
plugins[xvid_enc_create.num_plugins].func = xvid_plugin_2pass2;
diff -ruw xvid_20101108.orig/xvidcore/vfw/src/codec.c xvid_20101108/xvidcore/vfw/src/codec.c
--- xvid_20101108.orig/xvidcore/vfw/src/codec.c 2010-08-10 17:17:33.000000000 +0300
+++ xvid_20101108/xvidcore/vfw/src/codec.c 2010-11-08 12:25:01.226668328 +0200
@@ -514,10 +514,7 @@
pass2.vbv_size = profiles[codec->config.profile].max_vbv_size;
pass2.vbv_initial = (profiles[codec->config.profile].max_vbv_size*3)/4; /* 75% */
pass2.vbv_maxrate = profiles[codec->config.profile].max_bitrate;
-
- // XXX: xvidcore current provides a "peak bits over 3secs" constraint.
- // according to the latest dxn literature, a 1sec constraint is now used
- pass2.vbv_peakrate = profiles[codec->config.profile].vbv_peakrate * 3;
+ pass2.vbv_peakrate = profiles[codec->config.profile].vbv_peakrate;
plugins[create.num_plugins].func = codec->xvid_plugin_2pass2_func;
plugins[create.num_plugins].param = &pass2;
I don't know if changing the peakrate to use one-second window
instead of three-second window is wanted, but below is a patch
just in case. It also adds some comments to xvid.h.
diff -ruw xvid_20101108.orig/xvidcore/src/plugins/plugin_2pass2.c xvid_20101108/xvidcore/src/plugins/plugin_2pass2.c
--- xvid_20101108.orig/xvidcore/src/plugins/plugin_2pass2.c 2010-03-09 12:00:14.000000000 +0200
+++ xvid_20101108/xvidcore/src/plugins/plugin_2pass2.c 2010-11-08 11:36:03.203334898 +0200
@@ -1446,7 +1446,7 @@
* aren't...)
*
* DivX profiles have 2 criteria: VBV as in MPEG standard
- * a limit on peak bitrate for any 3 seconds
+ * a limit on peak bitrate for any 1 second
*
* But if VBV is fulfilled, peakrate is automatically fulfilled in any profile
* define so far, so we check for it (for completeness) but correct only VBV
@@ -1456,7 +1456,7 @@
#define VBV_COMPLIANT 0
#define VBV_UNDERFLOW 1 /* video buffer runs empty */
#define VBV_OVERFLOW 2 /* doesn't exist for VBR encoding */
-#define VBV_PEAKRATE 4 /* peak bitrate (within 3s) violated */
+#define VBV_PEAKRATE 4 /* peak bitrate (within 1s) violated */
static int
check_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps)
@@ -1470,8 +1470,8 @@
* maxrate= 4854000 (4.854MBps)
* peakrate= 8000000 (8MBps)
*
- * PAL: offset3s = 75 (3 seconds of 25fps)
- * NTSC: offset3s = 90 (3 seconds of 29.97fps) or 72 (3 seconds of 23.976fps)
+ * PAL: offset1s = 25 (1 second of 25fps)
+ * NTSC: offset1s = 30 (1 second of 29.97fps) or 24 (1 second of 23.976fps)
*/
const float vbv_size = (float)rc->param.vbv_size/8.f;
@@ -1482,8 +1482,8 @@
const float peakrate = (float)rc->param.vbv_peakrate;
const float r0 = (int)(maxrate/fps+0.5)/8.f;
- int bytes3s = 0;
- int offset3s = (int)(3.f*fps+0.5);
+ int bytes1s = 0;
+ int offset1s = (int)(fps+0.5);
int i;
/* 1Gbit should be enough to inuitialize the vbvmin
@@ -1491,13 +1491,13 @@
vbvmin = 1000*1000*1000;
for (i=0; i<rc->num_frames; i++) {
- /* DivX 3s peak bitrate check */
- bytes3s += rc->stats[i].scaled_length;
- if (i>=offset3s)
- bytes3s -= rc->stats[i-offset3s].scaled_length;
+ /* DivX 1s peak bitrate check */
+ bytes1s += rc->stats[i].scaled_length;
+ if (i>=offset1s)
+ bytes1s -= rc->stats[i-offset1s].scaled_length;
/* ignore peakrate constraint if peakrate is <= 0.f */
- if (peakrate>0.f && 8.f*bytes3s > 3*peakrate)
+ if (peakrate>0.f && 8.f*bytes1s > peakrate)
return(VBV_PEAKRATE);
/* update vbv fill level */
diff -ruw xvid_20101108.orig/xvidcore/src/xvid.h xvid_20101108/xvidcore/src/xvid.h
--- xvid_20101108.orig/xvidcore/src/xvid.h 2010-10-10 22:19:55.000000000 +0300
+++ xvid_20101108/xvidcore/src/xvid.h 2010-11-08 12:19:38.743334953 +0200
@@ -541,10 +541,13 @@
int container_frame_overhead; /* [in] How many bytes the controller has to compensate per frame due to container format overhead */
/* ------- v1.1.x ------- */
- int vbv_size; /* [in] buffer size (bits) */
+ int vbv_size; /* [in] buffer size (bits). If this is zero, VBV check is disabled. */
int vbv_initial; /* [in] initial buffer occupancy (bits) */
int vbv_maxrate; /* [in] max processing bitrate (bits per second) */
- int vbv_peakrate; /* [in:opt] max average bitrate over 3 seconds (bits per second) */
+ int vbv_peakrate; /* [in:opt] max average bitrate over 1 second (bits per second).
+ * This is used for diagnostics only and won't affect the actual peak bitrate.
+ * This is not a problem as long as vbv_peakrate > vbv_size + vbv_maxrate which
+ * guarantees that vbv_peakrate won't be exceeded. */
}xvid_plugin_2pass2_t;
--
Lasse Collin | IRC: Larhzu @ IRCnet & Freenode
More information about the Xvid-devel
mailing list