159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ------------------------------------------------------------------ 259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Copyright (C) 1998-2009 PacketVideo 359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * 459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * you may not use this file except in compliance with the License. 659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * You may obtain a copy of the License at 759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * 859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * http://www.apache.org/licenses/LICENSE-2.0 959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * 1059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Unless required by applicable law or agreed to in writing, software 1159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * distributed under the License is distributed on an "AS IS" BASIS, 1259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 1359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * express or implied. 1459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * See the License for the specific language governing permissions 1559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * and limitations under the License. 1659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * ------------------------------------------------------------------- 1759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong */ 1859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4def.h" 1959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4lib_int.h" 2059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "rate_control.h" 2159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4enc_lib.h" 2259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "bitstream_io.h" 2359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "m4venc_oscl.h" 2459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 2559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid targetBitCalculation(void *input); 2659f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid calculateQuantizer_Multipass(void *video); 2759f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid updateRateControl(rateControl *rc, VideoEncData *video); 2859f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid updateRC_PostProc(rateControl *rc, VideoEncData *video); 2959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 3059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*************************************************************************** 3159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong************** RC APIs to core encoding modules ******************* 3259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 3359f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_Initialize(void *video); 3459f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_Cleanup(rateControl *rc[],Int numLayers); 3559f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_VopQPSetting(VideoEncData *video,rateControl *rc[]); 3659f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_VopUpdateStat(VideoEncData *video,rateControl *rc[]); 3759f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_UpdateBuffer(VideoEncData *video, Int currLayer, Int num_skip); 3859f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt RC_GetSkipNextFrame(VideoEncData *video,Int currLayer); 3959f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid RC_ResetSkipNextFrame(void *video,Int currLayer); 4059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 4159f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_UpdateBXRCParams(void *input); Parameters update for target bitrate or framerate change 4259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 4359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong****************************************************************************/ 4459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 4559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 4659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/************************************************************************/ 4759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/************ API part **************************************************/ 4859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* must be called before each sequence*/ 4959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 5059f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_Initialize(void *input) 5159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 5259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong VideoEncData *video = (VideoEncData *) input; 5359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong VideoEncParams *encParams = video->encParams; 5459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rateControl **rc = video->rc; 5559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int numLayers = encParams->nLayers; 5659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int *LayerBitRate = encParams->LayerBitRate; 5759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong float *LayerFrameRate = encParams->LayerFrameRate; 5859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong MultiPass **pMP = video->pMP; 5959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 6059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int n; 6159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 6259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong for (n = 0; n < numLayers; n++) 6359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 6459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* rate control */ 6559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->fine_frame_skip = encParams->FineFrameSkip_Enabled; 6659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->no_frame_skip = encParams->NoFrameSkip_Enabled; 6759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->no_pre_skip = encParams->NoPreSkip_Enabled; 6859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->skip_next_frame = 0; /* must be initialized */ 6959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 7059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //rc[n]->TMN_TH = (Int)((float)LayerBitRate[n]/LayerFrameRate[n]); 7159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->Bs = video->encParams->BufferSize[n]; 7259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->TMN_W = 0; 7359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->VBV_fullness = (Int)(rc[n]->Bs * 0.5); /* rc[n]->Bs */ 7459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->encoded_frames = 0; 7559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->framerate = LayerFrameRate[n]; 7659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (n == 0) 7759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 7859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->TMN_TH = (Int)((float)LayerBitRate[n] / LayerFrameRate[n]); 7959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->bitrate = LayerBitRate[n]; 8059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->framerate = LayerFrameRate[n]; 8159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 8259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // For h263 or short header mode, the bit variation is within (-2*Rmax*1001/3000, 2*Rmax*1001/3000) 8359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (video->encParams->H263_Enabled) 8459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 8559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->max_BitVariance_num = (Int)((rc[n]->Bs - video->encParams->maxFrameSize) / 2 / (rc[n]->bitrate / rc[n]->framerate / 10.0)) - 5; 8659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc[n]->max_BitVariance_num < 0) rc[n]->max_BitVariance_num += 5; 8759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 8859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else // MPEG-4 normal modes 8959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 9059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->max_BitVariance_num = (Int)((float)(rc[n]->Bs - rc[n]->VBV_fullness) / ((float)LayerBitRate[n] / LayerFrameRate[n] / 10.0)) - 5; 9159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc[n]->max_BitVariance_num < 0) rc[n]->max_BitVariance_num += 5; 9259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 9359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 9459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 9559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 9659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (LayerFrameRate[n] - LayerFrameRate[n-1] > 0) /* 7/31/03 */ 9759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 9859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->TMN_TH = (Int)((float)(LayerBitRate[n] - LayerBitRate[n-1]) / (LayerFrameRate[n] - LayerFrameRate[n-1])); 9959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->max_BitVariance_num = (Int)((float)(rc[n]->Bs - rc[n]->VBV_fullness) * 10 / ((float)rc[n]->TMN_TH)) - 5; 10059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc[n]->max_BitVariance_num < 0) rc[n]->max_BitVariance_num += 5; 10159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 10259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else /* 7/31/03 */ 10359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 10459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->TMN_TH = 1 << 30; 10559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->max_BitVariance_num = 0; 10659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 10759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->bitrate = LayerBitRate[n] - LayerBitRate[n-1]; 10859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->framerate = LayerFrameRate[n] - LayerFrameRate[n-1]; 10959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 11059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 11159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // Set the initial buffer fullness 11259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (1) //!video->encParams->H263_Enabled) { // MPEG-4 11359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 11459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* According to the spec, the initial buffer fullness needs to be set to 1/3 */ 11559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->VBV_fullness = (Int)(rc[n]->Bs / 3.0 - rc[n]->Bs / 2.0); /* the buffer range is [-Bs/2, Bs/2] */ 11659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->counter_BTsrc = (Int)((rc[n]->Bs / 2.0 - rc[n]->Bs / 3.0) / (rc[n]->bitrate / rc[n]->framerate / 10.0)); 11759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->TMN_W = (Int)(rc[n]->VBV_fullness + pMP[n]->counter_BTsrc * (rc[n]->bitrate / rc[n]->framerate / 10.0)); 11859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 11959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->low_bound = -rc[n]->Bs / 2; 12059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]-> VBV_fullness_offset = 0; 12159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 12259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else /* this part doesn't work in some cases, the low_bound is too high, Jan 4,2006 */ 12359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 12459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->VBV_fullness = rc[n]->Bs - (Int)(video->encParams->VBV_delay * rc[n]->bitrate); 12559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc[n]->VBV_fullness < 0) rc[n]->VBV_fullness = 0; 12659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //rc[n]->VBV_fullness = (rc[n]->Bs-video->encParams->maxFrameSize)/2 + video->encParams->maxFrameSize; 12759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 12859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->VBV_fullness -= rc[n]->Bs / 2; /* the buffer range is [-Bs/2, Bs/2] */ 12959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->low_bound = -rc[n]->Bs / 2 + video->encParams->maxFrameSize; /* too high */ 13059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->VBV_fullness_offset = video->encParams->maxFrameSize / 2; /* don't understand the meaning of this */ 13159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->counter_BTdst = pMP[n]->counter_BTsrc = 0; 13259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 13359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 13459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 13559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Setting the bitrate and framerate */ 13659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->bitrate = rc[n]->bitrate; 13759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->framerate = rc[n]->framerate; 13859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->target_bits_per_frame = pMP[n]->bitrate / pMP[n]->framerate; 13959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 14059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 14159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 14259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 14359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 14459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 14559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 14659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 14759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : RC_Cleanup */ 14859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 12/20/2000 */ 14959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : free Rate Control memory */ 15059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 15159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 15259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 15359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 15459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 15559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 15659f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_Cleanup(rateControl *rc[], Int numLayers) 15759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 15859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong OSCL_UNUSED_ARG(rc); 15959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong OSCL_UNUSED_ARG(numLayers); 16059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 16159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 16259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 16359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 16459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 16559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 16659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 16759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : RC_VopQPSetting */ 16859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 4/11/2001 */ 16959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Reset rate control before coding VOP, moved from vop.c */ 17059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Compute QP for the whole VOP and initialize MB-based RC 17159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong reset QPMB[], currVop->quantizer, rc->Ec, video->header_bits */ 17259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* to In order to work RC_VopQPSetting has to do the followings 17359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 1. Set video->QPMB of all macroblocks. 17459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 2. Set currVop->quantizer 17559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 3. Reset video->header_bits to zero. 17659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 4. Initialize internal RC parameters for Vop cooding */ 17759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 17859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : PV_STATUS */ 17959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 18059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 18159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* To be moved to rate_control.c and separate between BX_RC and ANNEX_L */ 18259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 18359f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_VopQPSetting(VideoEncData *video, rateControl *prc[]) 18459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 18559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int currLayer = video->currLayer; 18659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Vol *currVol = video->vol[currLayer]; 18759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Vop *currVop = video->currVop; 18859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef TEST_MBBASED_QP 18959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong int i; 19059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif 19159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 19259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rateControl *rc = video->rc[currLayer]; 19359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong MultiPass *pMP = video->pMP[currLayer]; 19459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 19559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong OSCL_UNUSED_ARG(prc); 19659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 19759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (video->encParams->RC_Type == CONSTANT_Q) 19859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 19959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_MEMSET(video->QPMB, currVop->quantizer, sizeof(UChar)*currVol->nTotalMB); 20059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 20159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 20259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 20359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 20459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 20559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (video->rc[currLayer]->encoded_frames == 0) /* rc[currLayer]->totalFrameNumber*/ 20659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 20759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_MEMSET(video->QPMB, currVop->quantizer, sizeof(UChar)*currVol->nTotalMB); 20859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong video->rc[currLayer]->Qc = video->encParams->InitQuantIvop[currLayer]; 20959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 21059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 21159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 21259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong calculateQuantizer_Multipass((void*) video); 21359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong currVop->quantizer = video->rc[currLayer]->Qc; 21459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef TEST_MBBASED_QP 21559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong i = currVol->nTotalMB; /* testing changing QP at MB level */ 21659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong while (i) 21759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 21859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong i--; 21959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong video->QPMB[i] = (i & 1) ? currVop->quantizer - 1 : currVop->quantizer + 1; 22059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 22159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else 22259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong M4VENC_MEMSET(video->QPMB, currVop->quantizer, sizeof(UChar)*currVol->nTotalMB); 22359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif 22459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 22559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 22659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong video->header_bits = 0; 22759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 22859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 22959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* update pMP->framePos */ 23059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (++pMP->framePos == pMP->frameRange) pMP->framePos = 0; 23159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 23259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc->T == 0) 23359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 23459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTdst = (Int)(video->encParams->LayerFrameRate[video->currLayer] * 7.5 + 0.5); /* 0.75s time frame */ 23559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTdst = PV_MIN(pMP->counter_BTdst, (Int)(rc->max_BitVariance_num / 2 * 0.40)); /* 0.75s time frame may go beyond VBV buffer if we set the buffer size smaller than 0.75s */ 23659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTdst = PV_MAX(pMP->counter_BTdst, (Int)((rc->Bs / 2 - rc->VBV_fullness) * 0.30 / (rc->TMN_TH / 10.0) + 0.5)); /* At least 30% of VBV buffer size/2 */ 23759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTdst = PV_MIN(pMP->counter_BTdst, 20); /* Limit the target to be smaller than 3C */ 23859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 23959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->target_bits = rc->T = rc->TMN_TH = (Int)(rc->TMN_TH * (1.0 + pMP->counter_BTdst * 0.1)); 24059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->diff_counter = pMP->counter_BTdst; 24159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 24259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 24359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* collect the necessary data: target bits, actual bits, mad and QP */ 24459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->target_bits = rc->T; 24559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->QP = currVop->quantizer; 24659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 24759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->mad = video->sumMAD / (float)currVol->nTotalMB; 24859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (pMP->mad < MAD_MIN) pMP->mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ 24959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 25059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->bitrate = rc->bitrate; /* calculated in RCVopQPSetting */ 25159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->framerate = rc->framerate; 25259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 25359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* first pass encoding */ 25459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->nRe_Quantized = 0; 25559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 25659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 25759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 25859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 25959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 26059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 26159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : SaveRDSamples() */ 26259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 08/29/2001 */ 26359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* History : */ 26459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Save QP, actual_bits, mad and R_D of the current iteration */ 26559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 26659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 26759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 26859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* */ 26959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 27059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 27159f566c4ec3dfc097ad8163523e522280b27e5c3James DongVoid SaveRDSamples(MultiPass *pMP, Int counter_samples) 27259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 27359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* for pMP->pRDSamples */ 27459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->pRDSamples[pMP->framePos][counter_samples].QP = pMP->QP; 27559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->pRDSamples[pMP->framePos][counter_samples].actual_bits = pMP->actual_bits; 27659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->pRDSamples[pMP->framePos][counter_samples].mad = pMP->mad; 27759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->pRDSamples[pMP->framePos][counter_samples].R_D = (float)(pMP->actual_bits / (pMP->mad + 0.0001)); 27859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 27959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return ; 28059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 28159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 28259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : RC_VopUpdateStat */ 28359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 12/20/2000 */ 28459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Update statistics for rate control after encoding each VOP. */ 28559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* No need to change anything in VideoEncData structure. */ 28659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 28759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 28859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 28959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 29059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 29159f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_VopUpdateStat(VideoEncData *video, rateControl *rc) 29259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 29359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int currLayer = video->currLayer; 29459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Vol *currVol = video->vol[currLayer]; 29559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong MultiPass *pMP = video->pMP[currLayer]; 29659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int diff_BTCounter; 29759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 29859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong switch (video->encParams->RC_Type) 29959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 30059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong case CONSTANT_Q: 30159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong break; 30259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 30359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong case CBR_1: 30459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong case CBR_2: 30559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong case VBR_1: 30659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong case VBR_2: 30759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong case CBR_LOWDELAY: 30859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 30959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->actual_bits = currVol->stream->byteCount << 3; 31059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 31159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong SaveRDSamples(pMP, 0); 31259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 31359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->encoded_frames++; 31459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 31559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* for pMP->samplesPerFrame */ 31659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->samplesPerFrame[pMP->framePos] = 0; 31759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 31859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->sum_QP += pMP->QP; 31959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 32059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 32159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* update pMP->counter_BTsrc, pMP->counter_BTdst */ 32259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* re-allocate the target bit again and then stop encoding */ 32359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_BTCounter = (Int)((float)(rc->TMN_TH - rc->TMN_W - pMP->actual_bits) / 32459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong (pMP->bitrate / (pMP->framerate + 0.0001) + 0.0001) / 0.1); 32559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (diff_BTCounter >= 0) 32659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTsrc += diff_BTCounter; /* pMP->actual_bits is smaller */ 32759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 32859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTdst -= diff_BTCounter; /* pMP->actual_bits is bigger */ 32959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 33059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->TMN_TH -= (Int)((float)pMP->bitrate / (pMP->framerate + 0.0001) * (diff_BTCounter * 0.1)); 33159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->T = pMP->target_bits = rc->TMN_TH - rc->TMN_W; 33259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->diff_counter -= diff_BTCounter; 33359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 33459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->Rc = currVol->stream->byteCount << 3; /* Total Bits for current frame */ 33559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->Hc = video->header_bits; /* Total Bits in Header and Motion Vector */ 33659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 33759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* BX_RC */ 33859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong updateRateControl(rc, video); 33959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 34059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong break; 34159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 34259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong default: /* for case CBR_1/2, VBR_1/2 */ 34359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 34459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_FAIL; 34559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 34659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 34759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 34859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 34959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 35059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 35159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 35259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : RC_GetSkipNextFrame, RC_GetRemainingVops */ 35359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 2/20/2001 */ 35459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : To access RC parameters from other parts of the code. */ 35559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 35659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 35759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 35859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 35959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 36059f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt RC_GetSkipNextFrame(VideoEncData *video, Int currLayer) 36159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 36259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return video->rc[currLayer]->skip_next_frame; 36359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 36459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 36559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid RC_ResetSkipNextFrame(VideoEncData *video, Int currLayer) 36659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 36759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 36859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong video->rc[currLayer]->skip_next_frame = 0; 36959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return ; 37059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 37159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 37259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 37359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : RC_UpdateBuffer */ 37459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 2/20/2001 */ 37559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Update RC in case of there are frames skipped (camera freeze)*/ 37659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* from the application level in addition to what RC requested */ 37759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : Nr, B, Rr */ 37859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : Void */ 37959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 38059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 38159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 38259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 38359f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_UpdateBuffer(VideoEncData *video, Int currLayer, Int num_skip) 38459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 38559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rateControl *rc = video->rc[currLayer]; 38659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong MultiPass *pMP = video->pMP[currLayer]; 38759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 38859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (video == NULL || rc == NULL || pMP == NULL) 38959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_FAIL; 39059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 39159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->VBV_fullness -= (Int)(rc->bitrate / rc->framerate * num_skip); //rc[currLayer]->Rp; 39259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTsrc += 10 * num_skip; 39359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 39459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Check buffer underflow */ 39559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc->VBV_fullness < rc->low_bound) 39659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 39759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->VBV_fullness = rc->low_bound; // -rc->Bs/2; 39859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->TMN_W = rc->VBV_fullness - rc->low_bound; 39959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTsrc = pMP->counter_BTdst + (Int)((float)(rc->Bs / 2 - rc->low_bound) / 2.0 / (pMP->target_bits_per_frame / 10)); 40059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 40159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 40259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 40359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 40459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 40559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 40659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 40759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : RC_UpdateBXRCParams */ 40859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 4/08/2002 */ 40959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Update RC parameters specifically for target bitrate or */ 41059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* framerate update during an encoding session */ 41159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 41259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : PV_TRUE if successed, PV_FALSE if failed. */ 41359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 41459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 41559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 41659f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS RC_UpdateBXRCParams(void *input) 41759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 41859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong VideoEncData *video = (VideoEncData *) input; 41959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong VideoEncParams *encParams = video->encParams; 42059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rateControl **rc = video->rc; 42159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int numLayers = encParams->nLayers; 42259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int *LayerBitRate = encParams->LayerBitRate; 42359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong float *LayerFrameRate = encParams->LayerFrameRate; 42459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong MultiPass **pMP = video->pMP; 42559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 42659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int n, VBV_fullness; 42759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int diff_counter; 42859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 42959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong extern Bool SetProfile_BufferSize(VideoEncData *video, float delay, Int bInitialized); 43059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 43159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 43259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Reset video buffer size due to target bitrate change */ 43359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong SetProfile_BufferSize(video, video->encParams->VBV_delay, 0); /* output: video->encParams->BufferSize[] */ 43459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 43559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong for (n = 0; n < numLayers; n++) 43659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 43759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Remaining stuff about frame dropping and underflow check in update RC */ 43859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong updateRC_PostProc(rc[n], video); 43959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->skip_next_frame = 0; /* must be initialized */ 44059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 44159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* New changes: bitrate and framerate, Bs, max_BitVariance_num, TMN_TH(optional), encoded_frames(optional) */ 44259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->Bs = video->encParams->BufferSize[n]; 44359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong VBV_fullness = (Int)(rc[n]->Bs * 0.5); 44459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 44559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (n == 0) 44659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 44759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->TMN_TH = (Int)((float)LayerBitRate[n] / LayerFrameRate[n]); 44859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->bitrate = pMP[n]->bitrate = LayerBitRate[n]; 44959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->framerate = pMP[n]->framerate = LayerFrameRate[n]; 45059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 45159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // For h263 or short header mode, the bit variation is within (-2*Rmax*1001/3000, 2*Rmax*1001/3000) 45259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (video->encParams->H263_Enabled) 45359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 45459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->max_BitVariance_num = (Int)((rc[n]->Bs - video->encParams->maxFrameSize) / 2 / (rc[n]->bitrate / rc[n]->framerate / 10.0)) - 5; 45559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //rc[n]->max_BitVariance_num = (Int)((float)(rc[n]->Bs - rc[n]->VBV_fullness)/((float)LayerBitRate[n]/LayerFrameRate[n]/10.0))-5; 45659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 45759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else // MPEG-4 normal modes 45859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 45959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->max_BitVariance_num = (Int)((float)(rc[n]->Bs - VBV_fullness) * 10 / ((float)LayerBitRate[n] / LayerFrameRate[n])) - 5; 46059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 46159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 46259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 46359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 46459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (LayerFrameRate[n] - LayerFrameRate[n-1] > 0) /* 7/31/03 */ 46559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 46659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->TMN_TH = (Int)((float)(LayerBitRate[n] - LayerBitRate[n-1]) / (LayerFrameRate[n] - LayerFrameRate[n-1])); 46759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->max_BitVariance_num = (Int)((float)(rc[n]->Bs - VBV_fullness) * 10 / ((float)rc[n]->TMN_TH)) - 5; 46859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc[n]->max_BitVariance_num < 0) rc[n]->max_BitVariance_num += 5; 46959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 47059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else /* 7/31/03 */ 47159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 47259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->TMN_TH = 1 << 30; 47359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->max_BitVariance_num = 0; 47459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 47559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->bitrate = pMP[n]->bitrate = LayerBitRate[n] - LayerBitRate[n-1]; 47659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->framerate = pMP[n]->framerate = LayerFrameRate[n] - LayerFrameRate[n-1]; 47759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 47859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 47959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->target_bits_per_frame_prev = pMP[n]->target_bits_per_frame; 48059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->target_bits_per_frame = pMP[n]->bitrate / (float)(pMP[n]->framerate + 0.0001); /* 7/31/03 */ 48159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 48259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* rc[n]->VBV_fullness and rc[n]->TMN_W should be kept same */ 48359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* update pMP[n]->counter_BTdst and pMP[n]->counter_BTsrc */ 48459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter = (Int)((float)(rc[n]->VBV_fullness - rc[n]->TMN_W) / 48559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong (pMP[n]->target_bits_per_frame / 10 + 0.0001)); /* 7/31/03 */ 48659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 48759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->counter_BTdst = pMP[n]->counter_BTsrc = 0; 48859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (diff_counter > 0) 48959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->counter_BTdst = diff_counter; 49059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 49159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (diff_counter < 0) 49259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->counter_BTsrc = -diff_counter; 49359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 49459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc[n]->TMN_W = (Int)(rc[n]->VBV_fullness - /* re-calculate rc[n]->TMN_W in order for higher accuracy */ 49559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong (pMP[n]->target_bits_per_frame / 10) * (pMP[n]->counter_BTdst - pMP[n]->counter_BTsrc)); 49659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 49759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Keep the current average mad */ 49859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (pMP[n]->aver_mad != 0) 49959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 50059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->aver_mad_prev = pMP[n]->aver_mad; 50159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->encoded_frames_prev = pMP[n]->encoded_frames; 50259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 50359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 50459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->aver_mad = 0; 50559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->overlapped_win_size = 4; 50659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 50759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Misc */ 50859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->sum_mad = pMP[n]->sum_QP = 0; 50959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //pMP[n]->encoded_frames_prev = pMP[n]->encoded_frames; 51059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP[n]->encoded_frames = pMP[n]->re_encoded_frames = pMP[n]->re_encoded_times = 0; 51159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } /* end of: for(n=0; n<numLayers; n++) */ 51359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return PV_SUCCESS; 51559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 51759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 51959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ================================================================================ */ 52059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : targetBitCalculation */ 52159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 10/01/2001 */ 52259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : quadratic bit allocation model: T(n) = C*sqrt(mad(n)/aver_mad(n-1)) */ 52359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* */ 52459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : rc->T */ 52559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : Void */ 52659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 52759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ================================================================================ */ 52859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 52959f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid targetBitCalculation(void *input) 53059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 53159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong VideoEncData *video = (VideoEncData *) input; 53259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong MultiPass *pMP = video->pMP[video->currLayer]; 53359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Vol *currVol = video->vol[video->currLayer]; 53459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rateControl *rc = video->rc[video->currLayer]; 53559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 53659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong float curr_mad;//, average_mad; 53759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int diff_counter_BTsrc, diff_counter_BTdst, prev_counter_diff, curr_counter_diff, bound; 53859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* BT = Bit Transfer, for pMP->counter_BTsrc, pMP->counter_BTdst */ 53959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 54059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (video == NULL || currVol == NULL || pMP == NULL || rc == NULL) 54159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return; 54259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 54359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* some stuff about frame dropping remained here to be done because pMP cannot be inserted into updateRateControl()*/ 54459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong updateRC_PostProc(rc, video); 54559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 54659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* update pMP->counter_BTsrc and pMP->counter_BTdst to avoid interger overflow */ 54759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (pMP->counter_BTsrc > 1000 && pMP->counter_BTdst > 1000) 54859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 54959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTsrc -= 1000; 55059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTdst -= 1000; 55159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 55259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 55359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* ---------------------------------------------------------------------------------------------------*/ 55459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* target calculation */ 55559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong curr_mad = video->sumMAD / (float)currVol->nTotalMB; 55659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (curr_mad < MAD_MIN) curr_mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ 55759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTsrc = diff_counter_BTdst = 0; 55859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->diff_counter = 0; 55959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 56059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 56159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*1.calculate average mad */ 56259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->sum_mad += curr_mad; 56359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //average_mad = (pMP->encoded_frames < 1 ? curr_mad : pMP->sum_mad/(float)(pMP->encoded_frames+1)); /* this function is called from the scond encoded frame*/ 56459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //pMP->aver_mad = average_mad; 56559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (pMP->encoded_frames >= 0) /* pMP->encoded_frames is set to -1 initially, so forget about the very first I frame */ 56659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->aver_mad = (pMP->aver_mad * pMP->encoded_frames + curr_mad) / (pMP->encoded_frames + 1); 56759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 56859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (pMP->overlapped_win_size > 0 && pMP->encoded_frames_prev >= 0) /* 7/31/03 */ 56959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->aver_mad_prev = (pMP->aver_mad_prev * pMP->encoded_frames_prev + curr_mad) / (pMP->encoded_frames_prev + 1); 57059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 57159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*2.average_mad, mad ==> diff_counter_BTsrc, diff_counter_BTdst */ 57259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (pMP->overlapped_win_size == 0) 57359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 57459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* original verison */ 57559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (curr_mad > pMP->aver_mad*1.1) 57659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 57759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (curr_mad / (pMP->aver_mad + 0.0001) > 2) 57859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTdst = (Int)(M4VENC_SQRT(curr_mad / (pMP->aver_mad + 0.0001)) * 10 + 0.4) - 10; 57959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //diff_counter_BTdst = (Int)((sqrt(curr_mad/pMP->aver_mad)*2+curr_mad/pMP->aver_mad)/(3*0.1) + 0.4) - 10; 58059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 58159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTdst = (Int)(curr_mad / (pMP->aver_mad + 0.0001) * 10 + 0.4) - 10; 58259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 58359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else /* curr_mad <= average_mad*1.1 */ 58459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //diff_counter_BTsrc = 10 - (Int)((sqrt(curr_mad/pMP->aver_mad) + pow(curr_mad/pMP->aver_mad, 1.0/3.0))/(2.0*0.1) + 0.4); 58559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTsrc = 10 - (Int)(M4VENC_SQRT(curr_mad / (pMP->aver_mad + 0.0001)) * 10 + 0.5); 58659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //diff_counter_BTsrc = 10 - (Int)(curr_mad/pMP->aver_mad/0.1 + 0.5) 58759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 58859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* actively fill in the possible gap */ 58959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (diff_counter_BTsrc == 0 && diff_counter_BTdst == 0 && 59059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong curr_mad <= pMP->aver_mad*1.1 && pMP->counter_BTsrc < pMP->counter_BTdst) 59159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTsrc = 1; 59259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 59359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 59459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (pMP->overlapped_win_size > 0) 59559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 59659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* transition time: use previous average mad "pMP->aver_mad_prev" instead of the current average mad "pMP->aver_mad" */ 59759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (curr_mad > pMP->aver_mad_prev*1.1) 59859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 59959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (curr_mad / pMP->aver_mad_prev > 2) 60059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTdst = (Int)(M4VENC_SQRT(curr_mad / (pMP->aver_mad_prev + 0.0001)) * 10 + 0.4) - 10; 60159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //diff_counter_BTdst = (Int)((M4VENC_SQRT(curr_mad/pMP->aver_mad_prev)*2+curr_mad/pMP->aver_mad_prev)/(3*0.1) + 0.4) - 10; 60259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 60359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTdst = (Int)(curr_mad / (pMP->aver_mad_prev + 0.0001) * 10 + 0.4) - 10; 60459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 60559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else /* curr_mad <= average_mad*1.1 */ 60659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //diff_counter_BTsrc = 10 - (Int)((sqrt(curr_mad/pMP->aver_mad_prev) + pow(curr_mad/pMP->aver_mad_prev, 1.0/3.0))/(2.0*0.1) + 0.4); 60759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTsrc = 10 - (Int)(M4VENC_SQRT(curr_mad / (pMP->aver_mad_prev + 0.0001)) * 10 + 0.5); 60859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //diff_counter_BTsrc = 10 - (Int)(curr_mad/pMP->aver_mad_prev/0.1 + 0.5) 60959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 61059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* actively fill in the possible gap */ 61159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (diff_counter_BTsrc == 0 && diff_counter_BTdst == 0 && 61259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong curr_mad <= pMP->aver_mad_prev*1.1 && pMP->counter_BTsrc < pMP->counter_BTdst) 61359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTsrc = 1; 61459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 61559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (--pMP->overlapped_win_size <= 0) pMP->overlapped_win_size = 0; 61659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 61759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 61859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 61959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* if difference is too much, do clipping */ 62059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* First, set the upper bound for current bit allocation variance: 80% of available buffer */ 62159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bound = (Int)((rc->Bs / 2 - rc->VBV_fullness) * 0.6 / (pMP->target_bits_per_frame / 10)); /* rc->Bs */ 62259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTsrc = PV_MIN(diff_counter_BTsrc, bound); 62359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTdst = PV_MIN(diff_counter_BTdst, bound); 62459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 62559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Second, set another upper bound for current bit allocation: 4-5*bitrate/framerate */ 62659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong bound = 50; 62759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong// if(video->encParams->RC_Type == CBR_LOWDELAY) 62859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong// not necessary bound = 10; /* 1/17/02 -- For Low delay */ 62959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 63059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTsrc = PV_MIN(diff_counter_BTsrc, bound); 63159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTdst = PV_MIN(diff_counter_BTdst, bound); 63259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 63359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 63459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Third, check the buffer */ 63559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev_counter_diff = pMP->counter_BTdst - pMP->counter_BTsrc; 63659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong curr_counter_diff = prev_counter_diff + (diff_counter_BTdst - diff_counter_BTsrc); 63759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 63859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (PV_ABS(prev_counter_diff) >= rc->max_BitVariance_num || PV_ABS(curr_counter_diff) >= rc->max_BitVariance_num) // PV_ABS(curr_counter_diff) >= PV_ABS(prev_counter_diff) ) 63959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { //diff_counter_BTsrc = diff_counter_BTdst = 0; 64059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 64159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (curr_counter_diff > rc->max_BitVariance_num && diff_counter_BTdst) 64259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 64359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTdst = (rc->max_BitVariance_num - prev_counter_diff) + diff_counter_BTsrc; 64459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (diff_counter_BTdst < 0) diff_counter_BTdst = 0; 64559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 64659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 64759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (curr_counter_diff < -rc->max_BitVariance_num && diff_counter_BTsrc) 64859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 64959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong diff_counter_BTsrc = diff_counter_BTdst - (-rc->max_BitVariance_num - prev_counter_diff); 65059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (diff_counter_BTsrc < 0) diff_counter_BTsrc = 0; 65159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 65259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 65359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 65459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 65559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*3.diff_counter_BTsrc, diff_counter_BTdst ==> TMN_TH */ 65659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //rc->TMN_TH = (Int)((float)pMP->bitrate/pMP->framerate); 65759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->TMN_TH = (Int)(pMP->target_bits_per_frame); 65859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->diff_counter = 0; 65959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 66059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (diff_counter_BTsrc) 66159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 66259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->TMN_TH -= (Int)(pMP->target_bits_per_frame * diff_counter_BTsrc * 0.1); 66359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->diff_counter = -diff_counter_BTsrc; 66459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 66559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (diff_counter_BTdst) 66659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 66759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->TMN_TH += (Int)(pMP->target_bits_per_frame * diff_counter_BTdst * 0.1); 66859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->diff_counter = diff_counter_BTdst; 66959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 67059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 67159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 67259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*4.update pMP->counter_BTsrc, pMP->counter_BTdst */ 67359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTsrc += diff_counter_BTsrc; 67459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTdst += diff_counter_BTdst; 67559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 67659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 67759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /*5.target bit calculation */ 67859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->T = rc->TMN_TH - rc->TMN_W; 67959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //rc->T = rc->TMN_TH - (Int)((float)rc->TMN_W/rc->frameRate); 68059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 68159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (video->encParams->H263_Enabled && rc->T > video->encParams->maxFrameSize) 68259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 68359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->T = video->encParams->maxFrameSize; // added this 11/07/05 68459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 68559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 68659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 68759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 68859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ================================================================================ */ 68959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : calculateQuantizer_Multipass */ 69059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 10/01/2001 */ 69159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : variable rate bit allocation + new QP determination scheme */ 69259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* */ 69359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : rc->T and rc->Qc */ 69459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : Void */ 69559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 69659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ================================================================================ */ 69759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 69859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Mad based variable bit allocation + QP calculation with a new quadratic method */ 69959f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid calculateQuantizer_Multipass(void *input) 70059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 70159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong VideoEncData *video = (VideoEncData *) input; 70259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong MultiPass *pMP = video->pMP[video->currLayer]; 70359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Vol *currVol = video->vol[video->currLayer]; 70459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rateControl *rc = video->rc[video->currLayer]; 70559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 70659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int prev_QP, prev_actual_bits, curr_target, i, j; 70759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 70859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong float curr_mad, prev_mad, curr_RD, prev_RD, average_mad, aver_QP; 70959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 71059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 71159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (video == NULL || currVol == NULL || pMP == NULL || rc == NULL) 71259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return; 71359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 71459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Mad based variable bit allocation */ 71559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong targetBitCalculation((void*) video); 71659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 71759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc->T <= 0 || video->sumMAD == 0) 71859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 71959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc->T < 0) rc->Qc = 31; 72059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong return; 72159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 72259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 72359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* ---------------------------------------------------------------------------------------------------*/ 72459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* current frame QP estimation */ 72559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong curr_target = rc->T; 72659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong curr_mad = video->sumMAD / (float)currVol->nTotalMB; 72759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (curr_mad < MAD_MIN) curr_mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ 72859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong curr_RD = (float)curr_target / curr_mad; 72959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 73059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* Another version of search the optimal point */ 73159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev_actual_bits = pMP->pRDSamples[0][0].actual_bits; 73259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev_mad = pMP->pRDSamples[0][0].mad; 73359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 73459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong for (i = 0, j = 0; i < pMP->frameRange; i++) 73559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 73659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (pMP->pRDSamples[i][0].mad != 0 && prev_mad != 0 && 73759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong PV_ABS(prev_mad - curr_mad) > PV_ABS(pMP->pRDSamples[i][0].mad - curr_mad)) 73859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 73959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev_mad = pMP->pRDSamples[i][0].mad; 74059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev_actual_bits = pMP->pRDSamples[i][0].actual_bits; 74159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong j = i; 74259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 74359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 74459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev_QP = pMP->pRDSamples[j][0].QP; 74559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong for (i = 1; i < pMP->samplesPerFrame[j]; i++) 74659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 74759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (PV_ABS(prev_actual_bits - curr_target) > PV_ABS(pMP->pRDSamples[j][i].actual_bits - curr_target)) 74859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 74959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev_actual_bits = pMP->pRDSamples[j][i].actual_bits; 75059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev_QP = pMP->pRDSamples[j][i].QP; 75159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 75259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 75359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 75459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // quadratic approximation 75559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong prev_RD = (float)prev_actual_bits / prev_mad; 75659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //rc->Qc = (Int)(prev_QP * sqrt(prev_actual_bits/curr_target) + 0.4); 75759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (prev_QP == 1) // 11/14/05, added this to allow getting out of QP = 1 easily 75859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 75959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->Qc = (Int)(prev_RD / curr_RD + 0.5); 76059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 76159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 76259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 76359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->Qc = (Int)(prev_QP * M4VENC_SQRT(prev_RD / curr_RD) + 0.9); 76459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 76559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (prev_RD / curr_RD > 0.5 && prev_RD / curr_RD < 2.0) 76659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->Qc = (Int)(prev_QP * (M4VENC_SQRT(prev_RD / curr_RD) + prev_RD / curr_RD) / 2.0 + 0.9); /* Quadratic and linear approximation */ 76759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else 76859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->Qc = (Int)(prev_QP * (M4VENC_SQRT(prev_RD / curr_RD) + M4VENC_POW(prev_RD / curr_RD, 1.0 / 3.0)) / 2.0 + 0.9); 76959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 77059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //rc->Qc =(Int)(prev_QP * sqrt(prev_RD/curr_RD) + 0.4); 77159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // 11/08/05 77259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // lower bound on Qc should be a function of curr_mad 77359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // When mad is already low, lower bound on Qc doesn't have to be small. 77459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // Note, this doesn't work well for low complexity clip encoded at high bit rate 77559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong // it doesn't hit the target bit rate due to this QP lower bound. 77659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/// if((curr_mad < 8) && (rc->Qc < 12)) rc->Qc = 12; 77759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong// else if((curr_mad < 128) && (rc->Qc < 3)) rc->Qc = 3; 77859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 77959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc->Qc < 1) rc->Qc = 1; 78059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc->Qc > 31) rc->Qc = 31; 78159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 78259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 78359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* active bit resource protection */ 78459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong aver_QP = (pMP->encoded_frames == 0 ? 0 : pMP->sum_QP / (float)pMP->encoded_frames); 78559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong average_mad = (pMP->encoded_frames == 0 ? 0 : pMP->sum_mad / (float)pMP->encoded_frames); /* this function is called from the scond encoded frame*/ 78659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (pMP->diff_counter == 0 && 78759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong ((float)rc->Qc <= aver_QP*1.1 || curr_mad <= average_mad*1.1) && 78859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTsrc <= (pMP->counter_BTdst + (Int)(pMP->framerate*1.0 + 0.5))) 78959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 79059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->TMN_TH -= (Int)(pMP->target_bits_per_frame / 10.0); 79159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->T = rc->TMN_TH - rc->TMN_W; 79259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTsrc++; 79359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->diff_counter--; 79459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 79559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 79659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 79759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 79859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 79959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 80059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : updateRateControl */ 80159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 11/17/2000 */ 80259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose :Update the RD Modal (After Encoding the Current Frame) */ 80359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 80459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 80559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 80659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 80759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 80859f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid updateRateControl(rateControl *rc, VideoEncData *video) 80959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 81059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong Int frame_bits; 81159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 81259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 81359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* rate contro\l */ 81459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong frame_bits = (Int)(rc->bitrate / rc->framerate); 81559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->TMN_W += (rc->Rc - rc->TMN_TH); 81659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->VBV_fullness += (rc->Rc - frame_bits); //rc->Rp); 81759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //if(rc->VBV_fullness < 0) rc->VBV_fullness = -1; 81859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 81959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->encoded_frames++; 82059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 82159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* frame dropping */ 82259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->skip_next_frame = 0; 82359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 82459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if ((video->encParams->H263_Enabled && rc->Rc > video->encParams->maxFrameSize) || /* For H263/short header mode, drop the frame if the actual frame size exceeds the bound */ 82559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong (rc->VBV_fullness > rc->Bs / 2 && !rc->no_pre_skip)) /* skip the current frame */ /* rc->Bs */ 82659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 82759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->TMN_W -= (rc->Rc - rc->TMN_TH); 82859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->VBV_fullness -= rc->Rc; 82959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->skip_next_frame = -1; 83059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 83159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if ((float)(rc->VBV_fullness - rc->VBV_fullness_offset) > (rc->Bs / 2 - rc->VBV_fullness_offset)*0.95 && 83259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong !rc->no_frame_skip) /* skip next frame */ 83359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 83459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->VBV_fullness -= frame_bits; //rc->Rp; 83559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->skip_next_frame = 1; 83659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* skip more than 1 frames */ 83759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //while(rc->VBV_fullness > rc->Bs*0.475) 83859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong while ((rc->VBV_fullness - rc->VBV_fullness_offset) > (rc->Bs / 2 - rc->VBV_fullness_offset)*0.95) 83959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 84059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->VBV_fullness -= frame_bits; //rc->Rp; 84159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->skip_next_frame++; 84259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 84359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* END */ 84459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 84559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 84659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 84759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 84859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 84959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Function : updateRC_PostProc */ 85059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Date : 04/08/2002 */ 85159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Purpose : Remaing RC update stuff for frame skip and buffer underflow */ 85259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* check */ 85359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* In/out : */ 85459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Return : */ 85559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* Modified : */ 85659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */ 85759f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid updateRC_PostProc(rateControl *rc, VideoEncData *video) 85859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{ 85959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong MultiPass *pMP = video->pMP[video->currLayer]; 86059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 86159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc->skip_next_frame == 1 && !rc->no_frame_skip) /* skip next frame */ 86259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 86359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTsrc += 10 * rc->skip_next_frame; 86459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 86559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 86659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong else if (rc->skip_next_frame == -1 && !rc->no_pre_skip) /* skip current frame */ 86759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 86859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTdst -= pMP->diff_counter; 86959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTsrc += 10; 87059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 87159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->sum_mad -= pMP->mad; 87259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->aver_mad = (pMP->aver_mad * pMP->encoded_frames - pMP->mad) / (float)(pMP->encoded_frames - 1 + 0.0001); 87359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->sum_QP -= pMP->QP; 87459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->encoded_frames --; 87559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 87659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong /* some stuff in update VBV_fullness remains here */ 87759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong //if(rc->VBV_fullness < -rc->Bs/2) /* rc->Bs */ 87859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong if (rc->VBV_fullness < rc->low_bound) 87959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong { 88059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->VBV_fullness = rc->low_bound; // -rc->Bs/2; 88159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong rc->TMN_W = rc->VBV_fullness - rc->low_bound; 88259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong pMP->counter_BTsrc = pMP->counter_BTdst + (Int)((float)(rc->Bs / 2 - rc->low_bound) / 2.0 / (pMP->target_bits_per_frame / 10)); 88359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong } 88459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong} 88559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong 886