ratectl.cc

来自「Motion JPEG编解码器源代码」· CC 代码 · 共 1,089 行 · 第 1/3 页

CC
1,089
字号
	K is a running estimate of how bit-demand relates to frame	activity - bits demand per activity it is used to allow	prediction of quantisation needed to hit a bit-allocation.	*/	actual_Xhi = actual_bits * actual_avg_Q;    /* To handle longer sequences with little picture content       where I, B and P frames are of unusually similar size we       insist I frames assumed to be at least one and a half times       as complex as typical P frames    */    if( picture.pict_type == I_TYPE )        actual_Xhi = fmax(actual_Xhi, 1.5*Xhi[P_TYPE]);	picture.AQ = actual_avg_Q;	picture.SQ = sum_avg_quant;	//mjpeg_debug( "D=%d R=%d GC=%d", buffer_variation/8, (int)R/8,     //gop_buffer_correction/8  );	/* Xi are used as a guesstimate of *typical* frame activities	   based on the past.  Thus we don't want anomalous outliers due	   to scene changes swinging things too much (this is handled by	   the predictive complexity measure stuff) so we use moving	   averages.  The weightings are intended so all 3 averages have	   similar real-time decay periods based on an assumption of	   20-30Hz frame rates.	*/        ratectl_vbuf[picture.pict_type] = vbuf_fullness;    sum_size[picture.pict_type] += actual_bits/8.0;    pict_count[picture.pict_type] += 1;    if( first_encountered[picture.pict_type] )    {        Xhi[picture.pict_type] = actual_Xhi;        first_encountered[picture.pict_type] = false;    }    else    {        double win = fast_tune             ? K_AVG_WINDOW[picture.pict_type] / 1.7            : K_AVG_WINDOW[picture.pict_type];        Xhi[picture.pict_type] =             (actual_Xhi + win*Xhi[picture.pict_type])/(win+1.0);    }    mjpeg_debug( "Frame %c A=%6.0f %.2f: I = %6.0f P = %5.0f B = %5.0f",                 pict_type_char[picture.pict_type],                 actual_bits/8.0,                 actual_Xhi,                 sum_size[I_TYPE]/pict_count[I_TYPE],                 sum_size[P_TYPE]/pict_count[P_TYPE],                 sum_size[B_TYPE]/pict_count[B_TYPE]        );                    	VbvEndOfPict(picture);    padding_needed = padding_bits/8;}/* compute initial quantization stepsize (at the beginning of picture)    encparams.quant_floor != 0 is the VBR case where we set a bitrate as a (high)   maximum and then put a floor on quantisation to achieve a reasonable   overall size. */int OnTheFlyRateCtl::InitialMacroBlockQuant(Picture &picture){    return cur_mquant;}/************* * * SelectQuantization - select a quantisation for the current * macroblock based on the fullness of the virtual decoder buffer. * * NOTE: *Must* be called for all Macroblocks as content-based quantisation tuning is * supported. ************/int OnTheFlyRateCtl::MacroBlockQuant( const MacroBlock &mb ){    --mquant_change_ctr;    if( mquant_change_ctr < 0)        mquant_change_ctr =  encparams.mb_width/2;    int lum_variance = mb.BaseLumVariance();    int mquant;    if( mquant_change_ctr == 0 || lum_variance < encparams.boost_var_ceil )    {        const Picture &picture = mb.ParentPicture();        /* A.Stevens 2000 : we measure how much *information* (total activity)           has been covered and aim to release bits in proportion.           We keep track of a virtual buffer that catches the difference           between the bits allocated and the bits we actually used.  The           fullness of this buffer controls quantisation.        */        /* Guesstimate a virtual buffer fullness based on           bits used vs. bits in proportion to activity encoded        */        double dj = static_cast<double>(vbuf_fullness)             + static_cast<double>(picture.SizeCodedMacroBlocks())             - actcovered * target_bits / actsum;        /* scale against dynamic range of mquant and the bits/picture           count.  encparams.quant_floor != 0.0 is the VBR case where we set a           bitrate as a (high) maximum and then put a floor on           quantisation to achieve a reasonable overall size.  Not that           this *is* baseline quantisation.  Not adjust for local           activity.  Otherwise we end up blurring active           macroblocks. Silly in a VBR context.        */        double Qj = dj*62.0/fb_gain;        Qj =  fmax(Qj,encparams.quant_floor);        /*  Heuristic: We decrease quantisation for macroblocks            with markedly low luminace variance.  This helps make            gentle gradients (e.g. smooth backgrounds) look better at            (hopefully) small additonal cost  in coding bits        */        double act_boost;        if( lum_variance < encparams.boost_var_ceil )        {            if( lum_variance < encparams.boost_var_ceil/2)                act_boost = encparams.act_boost;            else            {                double max_boost_var = encparams.boost_var_ceil/2;                double above_max_boost =                     (static_cast<double>(lum_variance)-max_boost_var)                    / max_boost_var;                act_boost = 1.0 + (encparams.act_boost-1.0) * (1.0-above_max_boost);            }        }        else            act_boost = 1.0;        sum_vbuf_Q += ScaleQuantf(picture.q_scale_type,Qj/act_boost);        cur_mquant = ScaleQuant(picture.q_scale_type,Qj/act_boost) ;    }	/* Update activity covered */	double act  = mb.Activity();	actcovered += act;	 	return cur_mquant;}/* VBV calculations * * generates warnings if underflow or overflow occurs *//* vbv_end_of_picture * * - has to be called directly after writing picture_data() * - needed for accurate VBV buffer overflow calculation * - assumes there is no byte stuffing prior to the next start code * * Note correction for bytes that will be stuffed away in the eventual CBR * bit-stream. */void OnTheFlyRateCtl::VbvEndOfPict(Picture &picture){}/* calc_vbv_delay * * has to be called directly after writing the picture start code, the * reference point for vbv_delay * * A.Stevens 2000:  * Actually we call it just before the start code is written, but anyone * who thinks 32 bits +/- in all these other approximations matters is fooling * themselves. */void OnTheFlyRateCtl::CalcVbvDelay(Picture &picture){		/* number of 1/90000 s ticks until next picture is to be decoded */	if (picture.pict_type == B_TYPE)	{		if (encparams.prog_seq)		{			if (!picture.repeatfirst)				picture_delay = 90000.0/encparams.frame_rate; /* 1 frame */			else			{				if (!picture.topfirst)					picture_delay = 90000.0*2.0/encparams.frame_rate; /* 2 frames */				else					picture_delay = 90000.0*3.0/encparams.frame_rate; /* 3 frames */			}		}		else		{			/* interlaced */			if (encparams.fieldpic)				picture_delay = 90000.0/(2.0*encparams.frame_rate); /* 1 field */			else			{				if (!picture.repeatfirst)					picture_delay = 90000.0*2.0/(2.0*encparams.frame_rate); /* 2 flds */				else					picture_delay = 90000.0*3.0/(2.0*encparams.frame_rate); /* 3 flds */			}		}	}	else	{		/* I or P picture */		if (encparams.fieldpic)		{			if(picture.topfirst && (picture.pict_struct==TOP_FIELD))			{				/* first field */				picture_delay = 90000.0/(2.0*encparams.frame_rate);			}			else			{				/* second field */				/* take frame reordering delay into account */				picture_delay = next_ip_delay - 90000.0/(2.0*encparams.frame_rate);			}		}		else		{			/* frame picture */			/* take frame reordering delay into account*/			picture_delay = next_ip_delay;		}		if (!encparams.fieldpic || 			picture.topfirst!=(picture.pict_struct==TOP_FIELD))		{			/* frame picture or second field */			if (encparams.prog_seq)			{				if (!picture.repeatfirst)					next_ip_delay = 90000.0/encparams.frame_rate;				else				{					if (!picture.topfirst)						next_ip_delay = 90000.0*2.0/encparams.frame_rate;					else						next_ip_delay = 90000.0*3.0/encparams.frame_rate;				}			}			else			{				if (encparams.fieldpic)					next_ip_delay = 90000.0/(2.0*encparams.frame_rate);				else				{					if (!picture.repeatfirst)						next_ip_delay = 90000.0*2.0/(2.0*encparams.frame_rate);					else						next_ip_delay = 90000.0*3.0/(2.0*encparams.frame_rate);				}			}		}	}	if (decoding_time==0.0)	{		/* first call of calc_vbv_delay */		/* we start with a 7/8 filled VBV buffer (12.5% back-off) */		picture_delay = ((encparams.vbv_buffer_size*7)/8)*90000.0/encparams.bit_rate;		if (encparams.fieldpic)			next_ip_delay = (int)(90000.0/encparams.frame_rate+0.5);	}	/* VBV checks */	/*	   TODO: This is currently disabled because it is hopeless wrong	   most of the time. It generates 20 warnings for frames with small	   predecessors (small bitcnt_EOP) that in reality would be padded	   away by the multiplexer for every realistic warning for an	   oversize packet.	*/#ifdef CRIES_WOLF	/* check for underflow (previous picture).	*/	if (!encparams.low_delay && (decoding_time < (double)bitcnt_EOP*90000.0/encparams.bit_rate))	{		/* picture not completely in buffer at intended decoding time */		mjpeg_warn("vbv_delay underflow frame %d (target=%.1f, actual=%.1f)",				   frame_num-1, decoding_time, bitcnt_EOP*90000.0/encparams.bit_rate);	}	/* when to decode current frame */	decoding_time += picture_delay;	/* check for overflow (current picture).  Unless verbose warn	   only if overflow must be at least in part due to an oversize	   frame (rather than undersize predecessor).	   	*/	picture.vbv_delay = (int)(decoding_time - ((double)bitcnt_EOP)*90000.0/bit_rate);	if ( decoding_time * ((double)bit_rate  / 90000.0) - ((double)bitcnt_EOP)		> vbv_buffer_size )	{		double oversize = encparams.vbv_buffer_size -			(decoding_time / 90000.0 * bit_rate - (double)(bitcnt_EOP+frame_undershoot));		if(!quiet || oversize > 0.0  )			mjpeg_warn("vbv_delay overflow frame %d - %f.0 bytes!", 					   frame_num,					   oversize / 8.0				);	}	if (picture.vbv_delay<0)	{		mjpeg_warn("vbv_delay underflow: %d",picture.vbv_delay);		picture.vbv_delay = 0;	}	if (picture.vbv_delay>65535)	{		mjpeg_warn("vbv_delay frame %d exceeds permissible range: %d",				   frame_num, picture.vbv_delay);		picture.vbv_delay = 65535;	}#else	if( !encparams.mpeg1 || encparams.quant_floor != 0 || encparams.still_size > 0)		picture.vbv_delay =  0xffff;	else if( encparams.still_size > 0 )		picture.vbv_delay =  static_cast<int>(90000.0/encparams.frame_rate/4);#endif}/*  * Local variables: *  c-file-style: "stroustrup" *  tab-width: 4 *  indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?