📄 rc.c
字号:
#include"rc.h"
static int CreatRateControl(Encoder* pEncoder, RCData* pRC)
{
int i;
pRC->BytesPerSecond = pEncoder->iBitsPerSecoder / 8;
pRC->TargetFrameSize = pRC->BytesPerSecond / pEncoder->iFrameRate;
pRC->DelayFactor = 16;
pRC->AverTime = 100;
pRC->buffer = 100;
pRC->time = 0;
pRC->TotalSize = 0;
pRC->quant = 4;
for (i = 0; i < 31; i++)
{
pRC->ErrorQuant[i] = 0.0;
}
pRC->AvrageFrameSize = pRC->TargetFrameSize;
pRC->VideoQuality = 2.0 / (double) pRC->quant;
pRC->fq_error = 0;
return (0);
}
static int DestroyRateControl(RCData* rc)
{
free(rc);
return (0);
}
static int BeforeRateControl(RCData* rc, DataStruct* pdata)
{
int q = rc->quant;
if (q > 31)
{
q = 31;
}
else if (q < 2)
{
q = 2;
}
pdata->quant = q;
return 0;
}
static int AfterRateControl(RCData* rc, DataStruct* pData)
{
long deviation;
int rtn_quant;
double overflow;
double averaging_period;
double reaction_delay_factor;
double quality_scale;
double base_quality;
double target_quality;
rc->time += (double) pData->fincr / pData->fbase;
rc->TotalSize += pData->length;
deviation = rc->TotalSize - rc->BytesPerSecond * rc->time;
averaging_period = (double) rc->AverTime;
rc->VideoQuality -= rc->VideoQuality / averaging_period;
rc->VideoQuality += 2.0 / (double) pData->quant / averaging_period;
if (rc->VideoQuality < 0.1)
{
rc->VideoQuality = 0.1;
}
else if (rc->VideoQuality > 1.0)
{
rc->VideoQuality = 1.0;
}
if (pData->type != I_VOP)
{
reaction_delay_factor = (double) rc->DelayFactor;
rc->AvrageFrameSize -= rc->AvrageFrameSize / reaction_delay_factor;
rc->AvrageFrameSize += pData->length / reaction_delay_factor;
}
if (pData->type == B_VOP)
{
return (0);
}
quality_scale = rc->TargetFrameSize / rc->AvrageFrameSize * rc->TargetFrameSize / rc->AvrageFrameSize;
base_quality = rc->VideoQuality;
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) rc->buffer);
if (overflow > rc->TargetFrameSize)
{
overflow = rc->TargetFrameSize;
}
else if (overflow < -rc->TargetFrameSize)
{
overflow = -rc->TargetFrameSize;
}
target_quality = base_quality + (base_quality - 0.06452) * overflow / rc->TargetFrameSize;
if (target_quality > 2.0)
{
target_quality = 2.0;
}
else if (target_quality < 0.06452)
{
target_quality = 0.06452;
}
rtn_quant = (int) (2.0 / target_quality);
if (rtn_quant > 0 && rtn_quant < 31)
{
rc->ErrorQuant[rtn_quant - 1] += 2.0 / target_quality - rtn_quant;
if (rc->ErrorQuant[rtn_quant - 1] >= 1.0)
{
rc->ErrorQuant[rtn_quant - 1] -= 1.0;
rtn_quant++;
rc->quant++;
}
}
if (rtn_quant > rc->quant + 1)
{
if (rtn_quant > rc->quant + 3)
{
if (rtn_quant > rc->quant + 5)
{
rtn_quant = rc->quant + 3;
}
else
{
rtn_quant = rc->quant + 2;
}
}
else
{
rtn_quant = rc->quant + 1;
}
}
else if (rtn_quant < rc->quant - 1)
{
if (rtn_quant < rc->quant - 3)
{
if (rtn_quant < rc->quant - 5)
{
rtn_quant = rc->quant - 3;
}
else
{
rtn_quant = rc->quant - 2;
}
}
else
{
rtn_quant = rc->quant - 1;
}
}
rc->quant = rtn_quant;
return (0);
}
static int RcCall(Encoder* pEncoder, RCData* pRC, int iFlag, void* param1, void* param2)
{
switch (iFlag)
{
case FRAME :
return 0;
case CREATE:
return CreatRateControl(pEncoder, pRC);
case DESTROY:
return DestroyRateControl(pRC);
case BEFORE:
return BeforeRateControl(pRC, (DataStruct*) param1);
case AFTER:
return AfterRateControl(pRC, (DataStruct*) param1);
}
return -1;
}
void Rcfunc(Encoder* pEncoder, FrameInfo* frame, RCData* pRC, int iFlag, short* iType, short* quant, EncoderState* pStatic)
{
unsigned int i, j;
DataStruct data;
memset(&data, 0, sizeof(DataStruct));
data.width = pEncoder->pVol->video_object_layer_width;
data.height = pEncoder->pVol->video_object_layer_height;
data.mb_width = pEncoder->pVol->video_object_layer_width/16;
data.mb_height = pEncoder->pVol->video_object_layer_height/16;
data.fincr = pEncoder->pVol->fixed_vop_time_increment;
data.fbase = pEncoder->iFrameRate;
for (i=0; i<3; i++)
{
data.MinQuant[i] = 2;
data.MaxQuant[i] = 31;
}
data.frame_num = pEncoder->iFrameNo;
if (pEncoder->iFrameNo == 0)
{
RcCall(pEncoder, pRC, CREATE, NULL, NULL);
}
if (iFlag == BEFORE)
{
data.type = *iType;
data.quant = *quant;
}
else if (iFlag == FRAME)
{
data.type = frame->vop_coding_type;
data.quant = frame->vop_quant;
}
else if (iFlag == AFTER)
{
data.type = frame->vop_coding_type;
data.quant = frame->vop_quant;
data.length = frame->length;
data.IntraMbNum = frame->IntraMbNum;
data.InterMbNum = frame->InterMbNum;
data.SkipMbNum = frame->SkipMbNum;
data.stats.type = frame->vop_coding_type;
data.stats.quant = frame->vop_quant;
data.stats.length = frame->length;
data.stats.hlength = frame->length - (frame->iTextBits / 8);
data.stats.IntraMbNum = frame->IntraMbNum;
data.stats.InterMbNum = frame->InterMbNum;
data.stats.SkipMbNum = frame->SkipMbNum;
data.stats.y = data.y;
data.stats.u = data.u;
data.stats.v = data.v;
if (pStatic)
{
*pStatic = data.stats;
}
}
RcCall(pEncoder, pRC, iFlag, &data, 0);
if (iFlag == BEFORE)
{
*iType = data.type;
*quant = data.quant > 0 ? data.quant : 2; /* default */
}
else if (iFlag == FRAME)
{
for (j = 0; j < (pEncoder->pVol->video_object_layer_height/16); j++)
{
for (i = 0; i < (pEncoder->pVol->video_object_layer_width/16); i++)
{
frame->pMB[j * (pEncoder->pVol->video_object_layer_width/16) + i].dquant = 0;
}
}
frame->pMB[0].quant = data.quant;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -