[XviD-devel] [PATCH] vbv_peakrate cleanups

Michael Militzer michael at xvid.org
Wed Nov 17 10:42:19 CET 2010


Hi,

your proposed clean-up makes sense. As said, a peak rate is already defined
from vbv_maxsize and vbv_maxrate. So the vbv_peakrate option serves a
purpose only when you want to check for a lower peak rate than derived from
vbv_maxsize and vbv_maxrate (which is not the case in any used profile).

Such a peakrate check could possibly be useful as an additional constraint
to limit the decoding complexity. And for this, checking against a 1s window
is more reasonable than 3s. So your proposal is fine and applied to CVS
(including the change to the 1s check). Thank you for your patch.

Best regards,
Michael


Quoting Lasse Collin <lasse.collin at tukaani.org>:

> 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
> _______________________________________________
> Xvid-devel mailing list
> Xvid-devel at xvid.org
> http://list.xvid.org/mailman/listinfo/xvid-devel
>
>




More information about the Xvid-devel mailing list