?? ratecontrol.c
字號:
#include <math.h>
#include "../user_macro.h"
#include "rc_data.h"
#include "ratecontrol.h"
/*!
*****************************************************************************
========== old quantize=====================================================
****************************************************************************
*/
/*!
****************************************************************************
* \brief
*
* init ratecontrol param
*
***************************************************************************
*/
void
RateControlInit(RateControl * rate_control, /*<--> 指向RateControl結構*/
uint32_t target_rate, /*<-- 目標位率*/
uint32_t reaction_delay_factor, /*<-- 位率控制反應因子*/
uint32_t averaging_period, /*<-- 平均反應因子*/
uint32_t buffer, /*<-- 緩沖區*/
int framerate, /*<-- 幀率*/
int max_quant, /*<-- 最大量化值*/
int min_quant /*<-- 最小量化值*/
)
{
int i=0;
rate_control->frames = 0;
rate_control->total_size = 0;
rate_control->framerate = framerate / 1000.0;
rate_control->target_rate = target_rate;
rate_control->rtn_quant = get_initial_quant(0);
rate_control->max_quant = max_quant;
rate_control->min_quant = min_quant;
for (i = 0; i < 32; ++i) {
rate_control->quant_error[i] = 0.0;
}
rate_control->target_framesize =
(double) target_rate / 8.0 / rate_control->framerate;
rate_control->sequence_quality = 2.0 / (double) rate_control->rtn_quant;
rate_control->avg_framesize = rate_control->target_framesize;
rate_control->reaction_delay_factor = reaction_delay_factor;
rate_control->averaging_period = averaging_period;
rate_control->buffer = buffer;
}
/*!
****************************************************************************
* \brief
*
* Returned value : - the current 'rate_control' quantizer value
*
***************************************************************************
*/
int /*==> 返回量化值*/
RateControlGetQ(RateControl * rate_control, /*<--指向RateControl結構 */
int keyframe /*<--是否關鍵幀,no use now */
)
{
return rate_control->rtn_quant;
}
/*!
**************************************************************************
* \brief
*
* This function is called once a coded frame to update all internal
* parameters of 'rate_control'.
*
* Returned value : None
*
***************************************************************************
*/
void
RateControlUpdate(RateControl * rate_control, /*<--> 指向RateControl結構*/
uint32_t quant, /*<-- 量化值*/
int frame_size, /*<-- 幀大小*/
int keyframe /*<-- 是否關鍵幀*/
)
{
int64_t deviation;
double overflow, averaging_period, reaction_delay_factor;
double quality_scale, base_quality, target_quality;
int32_t rtn_quant;
rate_control->frames++;
rate_control->total_size += frame_size;
deviation =
( int64_t ) ( (double) rate_control->total_size -
((double)
((double) rate_control->target_rate / 8.0 /
(double) rate_control->framerate) *
(double) rate_control->frames));
/*分配位數與實際位數的差別*/
DEBUGCBR((int32_t) (rate_control->frames - 1), rate_control->rtn_quant,
(int32_t) deviation);
if (rate_control->rtn_quant >= 2)
{
averaging_period = (double) rate_control->averaging_period;
rate_control->sequence_quality -=
rate_control->sequence_quality / averaging_period;
rate_control->sequence_quality +=
2.0 / (double) rate_control->rtn_quant / averaging_period;
if (rate_control->sequence_quality < 0.1)
rate_control->sequence_quality = 0.1;
if ( !keyframe )
{
reaction_delay_factor =
(double) rate_control->reaction_delay_factor;
rate_control->avg_framesize -=
rate_control->avg_framesize / reaction_delay_factor;
rate_control->avg_framesize += frame_size / reaction_delay_factor;
}
/*調整I,P幀,avg_framesize增大,則quality_scale減小,
base_quality減小,最后的量化值增大*/
}
quality_scale =
rate_control->target_framesize / rate_control->avg_framesize *
rate_control->target_framesize / rate_control->avg_framesize;
/*衡量質量*/
base_quality = rate_control->sequence_quality;
if (quality_scale >= 1.0) {
base_quality = 1.0 - (1.0 - base_quality) / quality_scale;
} else {
base_quality = 0.06452 + (base_quality - 0.06452) * quality_scale;
}
overflow = -((double) deviation / (double) rate_control->buffer);
/*偏差大小*/
target_quality =
base_quality + (base_quality -
0.06452) * overflow / rate_control->target_framesize;
/*偏差大,質量差*/
if (target_quality > 2.0)
target_quality = 2.0;
else if (target_quality < 0.06452)
target_quality = 0.06452;
rtn_quant = (int32_t) (2.0 / target_quality);
if (rtn_quant < 31) {
rate_control->quant_error[rtn_quant] +=
2.0 / target_quality - rtn_quant;
if (rate_control->quant_error[rtn_quant] >= 1.0) {
rate_control->quant_error[rtn_quant] -= 1.0;
rtn_quant++;
}
}
if (rtn_quant > rate_control->rtn_quant + 1)
rtn_quant = rate_control->rtn_quant + 1;
else if (rtn_quant < rate_control->rtn_quant - 1)
rtn_quant = rate_control->rtn_quant - 1;
if (rtn_quant > rate_control->max_quant)
rtn_quant = rate_control->max_quant;
else if (rtn_quant < rate_control->min_quant)
rtn_quant = rate_control->min_quant;
rate_control->rtn_quant = rtn_quant;
}
/*!
****************************************************************************
* \brief
* return the first frame quant
***************************************************************************
*/
__inline static int /*==> return init quant */
get_initial_quant(int bpp /*<-- the param no use now */
)
{
return 8;
}
/*!
****************************************************************************
======= new quantize,quadratic distortion model,only for I,P=============================
======= add by lxq 2002.5.22===============
***************************************************************************
*/
/*!
****************************************************************************
* \brief
* init rate control model param needed
* step 1: Initialization stage
***************************************************************************
*/
void RCInitialization(
RCQ2* rc, /*<--> rc struct */
int bitrate, /*<-- bits per second*/
int framerate, /*<-- frame number per second*/
int sequence_time /*<-- sequence duration time */
)
{
int i=0;
rch_init(rc->rc_queue);
rc->Rs=bitrate;
rc->Ts=sequence_time;
rc->max_key_interval=framerate*sequence_time;
rc->Nr=framerate*sequence_time;
rc->Ns=25/framerate;
rc->Rf=0;
rc->Rr =rc->Ts*rc->Rs;
rc->Rp = rc->Rs/framerate;
rc->Bs=rc->Rs*rc->Ts/2;
rc->B=rc->Bs/2;
rc->N_Total=0;
for(i=0;i<2;i++){
rc->data[i].IsFirst=TRUE;
rc->data[i].X1=rc->data[i].X2=rc->data[i].X11=0;
rc->data[i].Rc=0;
rc->data[i].Ql=rc->data[i].Qc=Get_Initial_Quant(rc,i);
}
}
/*!
****************************************************************************
* \brief
*
* Returned value : - first I or P quantizer value
*
***************************************************************************
*/
__inline int Get_Initial_Quant( /*--> current frame quant */
RCQ2* rc, /*<--> rc struct */
int frametype /*<-- I or P frame type */
)/*the first param is of no use */
{
int Q=15;
switch(frametype)
{
case 0:
Q=15;
break;
case 1:
Q=15;
break;
}
return Q;/*第一個I幀使用的量值*/
}
/*!
****************************************************************************
* \brief
*
* get quant before coding each frame
*
***************************************************************************
*/
int RC_GetQ( /*--> current frame quant */
FILE *pfile, /*<-- file pointer,output stat*/
RCQ2* rc, /*<--> rc struct */
int frametype, /*<-- I or P frame type */
int mad /*<-- frame mad */
)
/* the third param is of no use */
{
/* rc->data[frametype].Ec=mad; */
if(frametype==0&&rc->Nr<=0)
{
rc->Nr=rc->max_key_interval;
if(rc->Rr>0 ) /*下溢*/
rc->Rr = rc->Ts*rc->Rs; /* total number of bits available for this segment */
else
rc->Rr+= rc->Ts*rc->Rs;/*只對上溢進行處理*/
}
if(rc->data[frametype].IsFirst){
rc->data[frametype].IsFirst=FALSE;
return Get_Initial_Quant(rc,frametype);
}
else
{
Target_Bit_Calculation(rc,frametype);
Quantisation_Calculation(pfile,rc,frametype);
/* printf("rc->Ec=%d ,rc->T=%d ,rc->Qc=%d ,rc->Nr=%d\n",rc->data[frametype].Ec,rc->T,rc->data[frametype].Qc,rc->Nr);*/
#ifdef stat_output
fprintf(pfile,"frametype=%d,rc->Ec=%d ,rc->T=%d ,rc->Qc=%d ,rc->Nr=%d\n",frametype,rc->data[frametype].Ec,rc->T,rc->data[frametype].Qc,rc->Nr);
#endif
return rc->data[frametype].Qc;
}
}
/*!
****************************************************************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -