ratectl.cc

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

CC
1,089
字号
/* ratectl.c, bitrate control routines (linear quantization only currently) *//* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. *//* * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose.  In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders.  Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * *//* Modifications and enhancements (C) 2000,2001,2002,2003 Andrew Stevens *//* These modifications are free software; you can redistribute it *  and/or modify it under the terms of the GNU General Public License *  as published by the Free Software Foundation; either version 2 of *  the License, or (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * */#include "config.h"#include <math.h>#include <limits.h>#include "mjpeg_types.h"#include "mjpeg_logging.h"#include "mpeg2syntaxcodes.h"#include "tables.h"#include "simd.h"#include "fastintfns.h"#include "mpeg2encoder.hh"#include "picture.hh"#include "ratectl.hh"#include "quantize.hh"/* private prototypes */double RateCtl::ScaleQuantf( int q_scale_type, double quant ){	double quantf;	if ( q_scale_type )	{		int iquantl, iquanth;		double wl, wh;		/* BUG TODO: This should interpolate the table... */		wh = quant-floor(quant);		wl = 1.0 - wh;		iquantl = (int) floor(quant);		iquanth = iquantl+1;		/* clip to legal (linear) range */		if (iquantl<1)		{			iquantl = 1;			iquanth = 1;		}				if (iquantl>111)		{			iquantl = 112;			iquanth = 112;		}				quantf = (double)		  wl * (double)non_linear_mquant_table[map_non_linear_mquant[iquantl]] 			+ 		  wh * (double)non_linear_mquant_table[map_non_linear_mquant[iquanth]]			;	}	else	{		/* clip mquant to legal (linear) range */		quantf = quant;		if (quantf<2.0)			quantf = 2;		if (quantf>62.0)			quantf = 62.0;	}	return quantf;}int RateCtl::ScaleQuant( int q_scale_type , double quant ){	int iquant;		if ( q_scale_type  )	{		iquant = (int) floor(quant+0.5);		/* clip mquant to legal (linear) range */		if (iquant<1)			iquant = 1;		if (iquant>112)			iquant = 112;		iquant =			non_linear_mquant_table[map_non_linear_mquant[iquant]];	}	else	{		/* clip mquant to legal (linear) range */		iquant = (int)floor(quant+0.5);		if (iquant<2)			iquant = 2;		if (iquant>62)			iquant = 62;		iquant = (iquant/2)*2; // Must be *even*	}	return iquant;}double RateCtl::InvScaleQuant( int q_scale_type, int raw_code ){	int i;	if( q_scale_type )	{		i = 112;		while( 1 < i && map_non_linear_mquant[i] != raw_code )			--i;		return ((double)i);	}	else		return ((double)raw_code);}RateCtl::RateCtl( EncoderParams &_encparams ) :	encparams( _encparams ){}/***************************** * * On-the-fly rate controller.  The constructor sets up the initial * control and estimator parameter values to values that experience * suggest make sense.  All the important ones are dynamically  * tuned anyway so these values are not too critical. * ****************************/OnTheFlyRateCtl::OnTheFlyRateCtl(EncoderParams &encparams ) :	RateCtl(encparams){	buffer_variation = 0;	bits_transported = 0;	bits_used = 0;	frame_overshoot_margin = 0;	sum_avg_act = 0.0;	sum_avg_var = 0.0;		/* TODO: These values should are really MPEG-1/2 and material type	   dependent.  The encoder should probably run over the first 100	   frames or so look-ahead to tune theses dynamically before doing	   real encoding... alternative a config file should  be written!	*/	sum_avg_quant = 0.0;}/********************* * * Initialise rate control parameters * params:  reinit - Rate control is being re-initialised during the middle *                   of a run.  Don't reset adaptive parameters. * ********************/void OnTheFlyRateCtl::InitSeq(bool reinit){	double init_quant;	/* If its stills with a size we have to hit then make the	   guesstimates of for initial quantisation pessimistic...	*/	bits_transported = bits_used = 0;	field_rate = 2*encparams.decode_frame_rate;	fields_per_pict = encparams.fieldpic ? 1 : 2;	if( encparams.still_size > 0 )	{		per_pict_bits = encparams.still_size * 8;	}	else	{		per_pict_bits = 			static_cast<int32_t>(encparams.fieldpic								 ? encparams.bit_rate / field_rate								 : encparams.bit_rate / encparams.decode_frame_rate				);	}	/* Everything else already set or adaptive */	if( reinit )		return;	first_gop = true;	K_AVG_WINDOW[I_TYPE] = 2.0;    switch( encparams.M )    {    case 1 : // P        K_AVG_WINDOW[P_TYPE] = 8.0;        K_AVG_WINDOW[B_TYPE] = 1.0; // dummy        break;    case 2 : // BP        K_AVG_WINDOW[P_TYPE] = 4.0;        K_AVG_WINDOW[B_TYPE] = 4.0;        break;    default: // BBP        K_AVG_WINDOW[P_TYPE] = 3.0;        K_AVG_WINDOW[B_TYPE] = 7.0;        break;    }        	/* Calculate reasonable margins for variation in the decoder	   buffer.  We assume that having less than 5 frame intervals	   worth buffered is cutting it fine for avoiding under-runs.	   The gain values represent the fraction of the under/over shoot	   to be recovered during one second.  Gain is decreased if the	   buffer margin is large, gain is higher for avoiding overshoot.	   Currently, for a 1-frame sized margin gain is set to recover	   an undershoot in half a second	*/	if( encparams.still_size > 0 )	{		undershoot_carry = 0;		overshoot_gain = 1.0;	}	else	{		int buffer_safe = 3 * per_pict_bits ;		undershoot_carry = (encparams.video_buffer_size - buffer_safe)/6;		if( undershoot_carry < 0 )			mjpeg_error_exit1("Rate control can't cope with a video buffer smaller 4 frame intervals");		overshoot_gain =  encparams.bit_rate / (encparams.video_buffer_size-buffer_safe);	}	bits_per_mb = (double)encparams.bit_rate / (encparams.mb_per_pict);	/*	  Reaction paramer - i.e. quantisation feedback gain relative	  to bit over/undershoot.	  For normal frames it is fairly modest as we can compensate	  over multiple frames and can average out variations in image	  complexity.	  For stills we set it a higher so corrections take place	  more rapidly *within* a single frame.	*/	if( encparams.still_size > 0 )		fb_gain = (int)floor(2.0*encparams.bit_rate/encparams.decode_frame_rate);	else		fb_gain = (int)floor(4.0*encparams.bit_rate/encparams.decode_frame_rate);	/* Set the virtual buffers for per-frame rate control feedback to	   values corresponding to the quantisation floor (if specified)	   or a "reasonable" quantisation (6.0) if not.	*/	init_quant = (encparams.quant_floor > 0.0 ? encparams.quant_floor : 6.0);    int i;    for( i = FIRST_PICT_TYPE; i <= LAST_PICT_TYPE; ++i )        ratectl_vbuf[i] = static_cast<int>(init_quant * fb_gain / 62.0);	next_ip_delay = 0.0;	decoding_time = 0.0;}void OnTheFlyRateCtl::InitGOP( int np, int nb){	N[P_TYPE] = encparams.fieldpic ? 2*np+1 : 2*np;	N[B_TYPE] = encparams.fieldpic ? 2*nb : 2*nb;	N[I_TYPE] = encparams.fieldpic ? 1 : 2;	fields_in_gop = N[I_TYPE] + N[P_TYPE] + N[B_TYPE];	/*	  At the start of a GOP before any frames have gone the	  actual buffer state represents a long term average. Any	  undershoot due to the I_frame of the previous GOP	  should by now have been caught up.	*/	gop_buffer_correction = 0;	/* Each still is encoded independently so we reset rate control	   for each one.  They're all I-frames so each stills is a GOP too.	*/    int i;	if( first_gop || encparams.still_size > 0)	{		mjpeg_debug( "FIRST GOP INIT");		fast_tune = true;		first_gop = false;        for( i = FIRST_PICT_TYPE; i <= LAST_PICT_TYPE; ++i )        {            first_encountered[i] = true;            pict_base_bits[i] = per_pict_bits;        }	}	else	{		mjpeg_debug( "REST GOP INIT" );		double recovery_fraction = field_rate/(overshoot_gain * fields_in_gop);		double recovery_gain = 			recovery_fraction > 1.0 ? 1.0 : overshoot_gain * recovery_fraction;		int available_bits = 			static_cast<int>( (encparams.bit_rate+buffer_variation*recovery_gain)							  * fields_in_gop/field_rate);        double Xsum = 0.0;        for( i = FIRST_PICT_TYPE; i <= LAST_PICT_TYPE; ++i )            Xsum += N[i]*Xhi[i];        for( i = FIRST_PICT_TYPE; i <= LAST_PICT_TYPE; ++i )            pict_base_bits[i] =                  static_cast<int32_t>(fields_per_pict*available_bits*Xhi[i]/Xsum);		fast_tune = false;	}}/* Step 1a: compute target bits for current picture being coded, based * on predicting from past frames */void OnTheFlyRateCtl::InitNewPict(Picture &picture){	double target_Q;

⌨️ 快捷键说明

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