[x264-devel] [PATCH] filler data
Limin Wang
lance.lmwang at gmail.com
Tue Apr 15 08:29:21 CEST 2008
Hi,
Before I had written the same code for vbv buffer overflow, but I did not add
i_filler_size field as I count the padding byte into i_frame_size direct.
Another difference is I haven't export x264_nal_start/end interface to public.
For real CBR, I think it's force to fill stuffing data, so I enable it directly.
Attached is my old patch.
Thanks,
Limin
* Gabriel Bouvigne <gabriel.bouvigne at joost.com> [2008-04-14 12:23:52 +0200]:
> Allows automatic insertion of filler data. Stream must be CBR, otherwise
> filler won't be inserted.
> Use --filler to enable filler data.
>
> --
> Gabriel
> diff --git a/common/common.c b/common/common.c
> old mode 100644
> new mode 100755
> index 2d00384..c1b45d9
> --- a/common/common.c
> +++ b/common/common.c
> @@ -140,6 +140,7 @@ void x264_param_default( x264_param_t *param )
>
> param->b_repeat_headers = 1;
> param->b_aud = 0;
> + param->b_filler = 0;
> }
>
> static int parse_enum( const char *arg, const char * const *names, int *dst )
> @@ -527,6 +528,8 @@ int x264_param_parse( x264_param_t *p, const char *name, const char *value )
> p->analyse.b_ssim = atobool(value);
> OPT("aud")
> p->b_aud = atobool(value);
> + OPT("filler")
> + p->b_filler = atobool(value);
> OPT("sps-id")
> p->i_sps_id = atoi(value);
> OPT("global-header")
> diff --git a/common/common.h b/common/common.h
> old mode 100644
> new mode 100755
> index b9f4869..329e609
> --- a/common/common.h
> +++ b/common/common.h
> @@ -249,6 +249,7 @@ struct x264_t
> uint8_t *p_bitstream; /* will hold data for all nal */
> bs_t bs;
> int i_frame_size;
> + int i_filler_size;
> } out;
>
> /* frame number/poc */
> @@ -555,6 +556,8 @@ struct x264_t
> int i_direct_score[2];
> int i_direct_frames[2];
>
> + int64_t i_filler_size;
> +
> } stat;
>
> /* CPU functions dependents */
> diff --git a/encoder/encoder.c b/encoder/encoder.c
> old mode 100644
> new mode 100755
> index 7637dc2..3934462
> --- a/encoder/encoder.c
> +++ b/encoder/encoder.c
> @@ -778,8 +778,8 @@ int x264_encoder_reconfig( x264_t *h, x264_param_t *param )
> return x264_validate_parameters( h );
> }
>
> -/* internal usage */
> -static void x264_nal_start( x264_t *h, int i_type, int i_ref_idc )
> +
> +void x264_nal_start( x264_t *h, int i_type, int i_ref_idc )
> {
> x264_nal_t *nal = &h->out.nal[h->out.i_nal];
>
> @@ -789,7 +789,8 @@ static void x264_nal_start( x264_t *h, int i_type, int i_ref_idc )
> nal->i_payload= 0;
> nal->p_payload= &h->out.p_bitstream[bs_pos( &h->out.bs ) / 8];
> }
> -static void x264_nal_end( x264_t *h )
> +
> +void x264_nal_end( x264_t *h )
> {
> x264_nal_t *nal = &h->out.nal[h->out.i_nal];
> nal->i_payload = &h->out.p_bitstream[bs_pos( &h->out.bs ) / 8] - nal->p_payload;
> @@ -1611,6 +1612,13 @@ static void x264_encoder_frame_end( x264_t *h, x264_t *thread_current,
> return;
> }
>
> + /* ---------------------- Update encoder state ------------------------- */
> +
> + /* update rc */
> + x264_cpu_restore( h->param.cpu );
> + x264_ratecontrol_end( h, h->out.i_frame_size * 8 );
> +
> +
> x264_frame_push_unused( thread_current, h->fenc );
>
> /* End bitstream, set output */
> @@ -1635,10 +1643,6 @@ static void x264_encoder_frame_end( x264_t *h, x264_t *thread_current,
>
> /* ---------------------- Update encoder state ------------------------- */
>
> - /* update rc */
> - x264_cpu_restore( h->param.cpu );
> - x264_ratecontrol_end( h, h->out.i_frame_size * 8 );
> -
> /* restore CPU state (before using float again) */
> x264_cpu_restore( h->param.cpu );
>
> @@ -1653,6 +1657,7 @@ static void x264_encoder_frame_end( x264_t *h, x264_t *thread_current,
> h->stat.i_slice_count[h->sh.i_type]++;
> h->stat.i_slice_size[h->sh.i_type] += h->out.i_frame_size + NALU_OVERHEAD;
> h->stat.f_slice_qp[h->sh.i_type] += h->fdec->f_qp_avg_aq;
> + h->stat.i_filler_size += h->out.i_filler_size;
>
> for( i = 0; i < X264_MBTYPE_MAX; i++ )
> h->stat.i_mb_count[h->sh.i_type][i] += h->stat.frame.i_mb_count[i];
> @@ -1878,7 +1883,7 @@ void x264_encoder_close ( x264_t *h )
> float fps = (float) h->param.i_fps_num / h->param.i_fps_den;
> #define SUM3(p) (p[SLICE_TYPE_I] + p[SLICE_TYPE_P] + p[SLICE_TYPE_B])
> #define SUM3b(p,o) (p[SLICE_TYPE_I][o] + p[SLICE_TYPE_P][o] + p[SLICE_TYPE_B][o])
> - float f_bitrate = fps * SUM3(h->stat.i_slice_size) / i_count / 125;
> + float f_bitrate = fps * (SUM3(h->stat.i_slice_size) + h->stat.i_filler_size) / i_count / 125;
>
> if( h->pps->b_transform_8x8_mode )
> {
> diff --git a/encoder/ratecontrol.c b/encoder/ratecontrol.c
> old mode 100644
> new mode 100755
> index bb10f5c..f844c0f
> --- a/encoder/ratecontrol.c
> +++ b/encoder/ratecontrol.c
> @@ -1240,6 +1240,8 @@ static void update_predictor( predictor_t *p, double q, double var, double bits
> p->coeff += bits*q / var;
> }
>
> +#define FILLER_OVERHEAD (5 + 1)
> +
> // update VBV after encoding a frame
> static void update_vbv( x264_t *h, int bits )
> {
> @@ -1253,6 +1255,17 @@ static void update_vbv( x264_t *h, int bits )
> return;
>
> rct->buffer_fill_final += rct->buffer_rate - bits;
> +
> + if (rct->buffer_fill_final >= rct->buffer_size &&
> + h->param.b_filler &&
> + h->thread[0]->param.rc.i_vbv_max_bitrate == h->param.rc.i_bitrate)
> + {
> + int padding = (rct->buffer_fill_final - rct->buffer_size) / 8;
> + x264_filler_write(h, padding);
> + h->out.i_filler_size = padding+FILLER_OVERHEAD;
> + rct->buffer_fill_final -= h->out.i_filler_size * 8;
> + }
> +
> if( rct->buffer_fill_final < 0 && !rct->b_2pass )
> x264_log( h, X264_LOG_WARNING, "VBV underflow (%.0f bits)\n", rct->buffer_fill_final );
> rct->buffer_fill_final = x264_clip3f( rct->buffer_fill_final, 0, rct->buffer_size );
> diff --git a/encoder/set.c b/encoder/set.c
> old mode 100644
> new mode 100755
> index 6cf8773..23c0724
> --- a/encoder/set.c
> +++ b/encoder/set.c
> @@ -28,6 +28,8 @@
> #include "config.h"
> #endif
>
> +#include "set.h"
> +
> static void transpose( uint8_t *buf, int w )
> {
> int i, j;
> @@ -503,6 +505,20 @@ void x264_sei_version_write( x264_t *h, bs_t *s )
> x264_free( version );
> }
>
> +
> +void x264_filler_write( x264_t *h, int filler_bytes )
> +{
> + int i;
> +
> + x264_nal_start( h, NAL_FILLER, NAL_PRIORITY_DISPOSABLE );
> + for (i=0; i< filler_bytes; i++)
> + {
> + bs_write( &h->out.bs, 8, 0xFF );
> + }
> + bs_rbsp_trailing(&h->out.bs);
> + x264_nal_end( h );
> +}
> +
> const x264_level_t x264_levels[] =
> {
> { 10, 1485, 99, 152064, 64, 175, 64, 64, 0, 0, 0, 1 },
> diff --git a/encoder/set.h b/encoder/set.h
> old mode 100644
> new mode 100755
> index dac2d2f..0cf4e82
> --- a/encoder/set.h
> +++ b/encoder/set.h
> @@ -24,11 +24,15 @@
> #ifndef _ENCODER_SET_H
> #define _ENCODER_SET_H 1
>
> +void x264_nal_start( x264_t *h, int i_type, int i_ref_idc );
> +void x264_nal_end( x264_t *h );
> +
> void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param );
> void x264_sps_write( bs_t *s, x264_sps_t *sps );
> void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *sps );
> void x264_pps_write( bs_t *s, x264_pps_t *pps );
> void x264_sei_version_write( x264_t *h, bs_t *s );
> +void x264_filler_write( x264_t *h, int filler_bytes );
> void x264_validate_levels( x264_t *h );
>
> #endif
> diff --git a/x264.c b/x264.c
> old mode 100644
> new mode 100755
> index 51bd0cd..f1622ca
> --- a/x264.c
> +++ b/x264.c
> @@ -320,6 +320,7 @@ static void Help( x264_param_t *defaults, int b_longhelp )
> H1( " --visualize Show MB types overlayed on the encoded video\n" );
> H1( " --sps-id <integer> Set SPS and PPS id numbers [%d]\n", defaults->i_sps_id );
> H1( " --aud Use access unit delimiters\n" );
> + H1( " --filler Use filler data access units\n" );
> H0( "\n" );
> }
>
> @@ -447,6 +448,7 @@ static int Parse( int argc, char **argv,
> { "visualize",no_argument, NULL, OPT_VISUALIZE },
> { "sps-id", required_argument, NULL, 0 },
> { "aud", no_argument, NULL, 0 },
> + { "filler", no_argument, NULL, 0 },
> { "nr", required_argument, NULL, 0 },
> { "cqm", required_argument, NULL, 0 },
> { "cqmfile", required_argument, NULL, 0 },
> diff --git a/x264.h b/x264.h
> old mode 100644
> new mode 100755
> index e49f1a4..9d0ca18
> --- a/x264.h
> +++ b/x264.h
> @@ -283,6 +283,7 @@ typedef struct x264_param_t
> } rc;
>
> /* Muxing parameters */
> + int b_filler; /* use filler data */
> int b_aud; /* generate access unit delimiters */
> int b_repeat_headers; /* put SPS/PPS before each keyframe */
> int i_sps_id; /* SPS and PPS id number */
> @@ -372,6 +373,7 @@ enum nal_unit_type_e
> NAL_SPS = 7,
> NAL_PPS = 8,
> NAL_AUD = 9,
> + NAL_FILLER = 12,
> /* ref_idc == 0 for 6,9,10,11,12 */
> };
> enum nal_priority_e
> _______________________________________________
> x264-devel mailing list
> x264-devel at videolan.org
> http://mailman.videolan.org/listinfo/x264-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: overflow.patch
Type: text/x-diff
Size: 6292 bytes
Desc: not available
Url : http://mailman.videolan.org/pipermail/x264-devel/attachments/20080415/8e5a91fe/attachment-0001.patch
More information about the x264-devel
mailing list