[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