129a84457aed4c45bc900998b5e11c03023264208James Dong/* ------------------------------------------------------------------ 229a84457aed4c45bc900998b5e11c03023264208James Dong * Copyright (C) 1998-2009 PacketVideo 329a84457aed4c45bc900998b5e11c03023264208James Dong * 429a84457aed4c45bc900998b5e11c03023264208James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 529a84457aed4c45bc900998b5e11c03023264208James Dong * you may not use this file except in compliance with the License. 629a84457aed4c45bc900998b5e11c03023264208James Dong * You may obtain a copy of the License at 729a84457aed4c45bc900998b5e11c03023264208James Dong * 829a84457aed4c45bc900998b5e11c03023264208James Dong * http://www.apache.org/licenses/LICENSE-2.0 929a84457aed4c45bc900998b5e11c03023264208James Dong * 1029a84457aed4c45bc900998b5e11c03023264208James Dong * Unless required by applicable law or agreed to in writing, software 1129a84457aed4c45bc900998b5e11c03023264208James Dong * distributed under the License is distributed on an "AS IS" BASIS, 1229a84457aed4c45bc900998b5e11c03023264208James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 1329a84457aed4c45bc900998b5e11c03023264208James Dong * express or implied. 1429a84457aed4c45bc900998b5e11c03023264208James Dong * See the License for the specific language governing permissions 1529a84457aed4c45bc900998b5e11c03023264208James Dong * and limitations under the License. 1629a84457aed4c45bc900998b5e11c03023264208James Dong * ------------------------------------------------------------------- 1729a84457aed4c45bc900998b5e11c03023264208James Dong */ 1829a84457aed4c45bc900998b5e11c03023264208James Dong#include "avcenc_lib.h" 1929a84457aed4c45bc900998b5e11c03023264208James Dong#include <math.h> 2029a84457aed4c45bc900998b5e11c03023264208James Dong 2129a84457aed4c45bc900998b5e11c03023264208James Dong/* rate control variables */ 2229a84457aed4c45bc900998b5e11c03023264208James Dong#define RC_MAX_QUANT 51 2329a84457aed4c45bc900998b5e11c03023264208James Dong#define RC_MIN_QUANT 0 //cap to 10 to prevent rate fluctuation 2429a84457aed4c45bc900998b5e11c03023264208James Dong 2529a84457aed4c45bc900998b5e11c03023264208James Dong#define MAD_MIN 1 /* handle the case of devision by zero in RC */ 2629a84457aed4c45bc900998b5e11c03023264208James Dong 2729a84457aed4c45bc900998b5e11c03023264208James Dong 2829a84457aed4c45bc900998b5e11c03023264208James Dong/* local functions */ 2929a84457aed4c45bc900998b5e11c03023264208James Dongdouble QP2Qstep(int QP); 3029a84457aed4c45bc900998b5e11c03023264208James Dongint Qstep2QP(double Qstep); 3129a84457aed4c45bc900998b5e11c03023264208James Dong 3229a84457aed4c45bc900998b5e11c03023264208James Dongdouble ComputeFrameMAD(AVCCommonObj *video, AVCRateControl *rateCtrl); 3329a84457aed4c45bc900998b5e11c03023264208James Dong 3429a84457aed4c45bc900998b5e11c03023264208James Dongvoid targetBitCalculation(AVCEncObject *encvid, AVCCommonObj *video, AVCRateControl *rateCtrl, MultiPass *pMP); 3529a84457aed4c45bc900998b5e11c03023264208James Dong 3629a84457aed4c45bc900998b5e11c03023264208James Dongvoid calculateQuantizer_Multipass(AVCEncObject *encvid, AVCCommonObj *video, 3729a84457aed4c45bc900998b5e11c03023264208James Dong AVCRateControl *rateCtrl, MultiPass *pMP); 3829a84457aed4c45bc900998b5e11c03023264208James Dong 3929a84457aed4c45bc900998b5e11c03023264208James Dongvoid updateRC_PostProc(AVCRateControl *rateCtrl, MultiPass *pMP); 4029a84457aed4c45bc900998b5e11c03023264208James Dong 4129a84457aed4c45bc900998b5e11c03023264208James Dongvoid AVCSaveRDSamples(MultiPass *pMP, int counter_samples); 4229a84457aed4c45bc900998b5e11c03023264208James Dong 4329a84457aed4c45bc900998b5e11c03023264208James Dongvoid updateRateControl(AVCRateControl *rateControl, int nal_type); 4429a84457aed4c45bc900998b5e11c03023264208James Dong 4529a84457aed4c45bc900998b5e11c03023264208James Dongint GetAvgFrameQP(AVCRateControl *rateCtrl) 4629a84457aed4c45bc900998b5e11c03023264208James Dong{ 4729a84457aed4c45bc900998b5e11c03023264208James Dong return rateCtrl->Qc; 4829a84457aed4c45bc900998b5e11c03023264208James Dong} 4929a84457aed4c45bc900998b5e11c03023264208James Dong 5029a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status RCDetermineFrameNum(AVCEncObject *encvid, AVCRateControl *rateCtrl, uint32 modTime, uint *frameNum) 5129a84457aed4c45bc900998b5e11c03023264208James Dong{ 5229a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 5329a84457aed4c45bc900998b5e11c03023264208James Dong AVCSliceHeader *sliceHdr = video->sliceHdr; 5429a84457aed4c45bc900998b5e11c03023264208James Dong uint32 modTimeRef = encvid->modTimeRef; 5529a84457aed4c45bc900998b5e11c03023264208James Dong int32 currFrameNum ; 5629a84457aed4c45bc900998b5e11c03023264208James Dong int frameInc; 5729a84457aed4c45bc900998b5e11c03023264208James Dong 5829a84457aed4c45bc900998b5e11c03023264208James Dong 5929a84457aed4c45bc900998b5e11c03023264208James Dong /* check with the buffer fullness to make sure that we have enough bits to encode this frame */ 6029a84457aed4c45bc900998b5e11c03023264208James Dong /* we can use a threshold to guarantee minimum picture quality */ 6129a84457aed4c45bc900998b5e11c03023264208James Dong /**********************************/ 6229a84457aed4c45bc900998b5e11c03023264208James Dong 6329a84457aed4c45bc900998b5e11c03023264208James Dong /* for now, the default is to encode every frame, To Be Changed */ 6429a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->first_frame) 6529a84457aed4c45bc900998b5e11c03023264208James Dong { 6629a84457aed4c45bc900998b5e11c03023264208James Dong encvid->modTimeRef = modTime; 6729a84457aed4c45bc900998b5e11c03023264208James Dong encvid->wrapModTime = 0; 6829a84457aed4c45bc900998b5e11c03023264208James Dong encvid->prevFrameNum = 0; 6929a84457aed4c45bc900998b5e11c03023264208James Dong encvid->prevProcFrameNum = 0; 7029a84457aed4c45bc900998b5e11c03023264208James Dong 7129a84457aed4c45bc900998b5e11c03023264208James Dong *frameNum = 0; 7229a84457aed4c45bc900998b5e11c03023264208James Dong 7329a84457aed4c45bc900998b5e11c03023264208James Dong /* set frame type to IDR-frame */ 7429a84457aed4c45bc900998b5e11c03023264208James Dong video->nal_unit_type = AVC_NALTYPE_IDR; 7529a84457aed4c45bc900998b5e11c03023264208James Dong sliceHdr->slice_type = AVC_I_ALL_SLICE; 7629a84457aed4c45bc900998b5e11c03023264208James Dong video->slice_type = AVC_I_SLICE; 7729a84457aed4c45bc900998b5e11c03023264208James Dong 7829a84457aed4c45bc900998b5e11c03023264208James Dong return AVCENC_SUCCESS; 7929a84457aed4c45bc900998b5e11c03023264208James Dong } 8029a84457aed4c45bc900998b5e11c03023264208James Dong else 8129a84457aed4c45bc900998b5e11c03023264208James Dong { 8229a84457aed4c45bc900998b5e11c03023264208James Dong if (modTime < modTimeRef) /* modTime wrapped around */ 8329a84457aed4c45bc900998b5e11c03023264208James Dong { 8429a84457aed4c45bc900998b5e11c03023264208James Dong encvid->wrapModTime += ((uint32)0xFFFFFFFF - modTimeRef) + 1; 8529a84457aed4c45bc900998b5e11c03023264208James Dong encvid->modTimeRef = modTimeRef = 0; 8629a84457aed4c45bc900998b5e11c03023264208James Dong } 8729a84457aed4c45bc900998b5e11c03023264208James Dong modTime += encvid->wrapModTime; /* wrapModTime is non zero after wrap-around */ 8829a84457aed4c45bc900998b5e11c03023264208James Dong 8929a84457aed4c45bc900998b5e11c03023264208James Dong currFrameNum = (int32)(((modTime - modTimeRef) * rateCtrl->frame_rate + 200) / 1000); /* add small roundings */ 9029a84457aed4c45bc900998b5e11c03023264208James Dong 9129a84457aed4c45bc900998b5e11c03023264208James Dong if (currFrameNum <= (int32)encvid->prevProcFrameNum) 9229a84457aed4c45bc900998b5e11c03023264208James Dong { 9329a84457aed4c45bc900998b5e11c03023264208James Dong return AVCENC_FAIL; /* this is a late frame do not encode it */ 9429a84457aed4c45bc900998b5e11c03023264208James Dong } 9529a84457aed4c45bc900998b5e11c03023264208James Dong 9629a84457aed4c45bc900998b5e11c03023264208James Dong frameInc = currFrameNum - encvid->prevProcFrameNum; 9729a84457aed4c45bc900998b5e11c03023264208James Dong 9829a84457aed4c45bc900998b5e11c03023264208James Dong if (frameInc < rateCtrl->skip_next_frame + 1) 9929a84457aed4c45bc900998b5e11c03023264208James Dong { 10029a84457aed4c45bc900998b5e11c03023264208James Dong return AVCENC_FAIL; /* frame skip required to maintain the target bit rate. */ 10129a84457aed4c45bc900998b5e11c03023264208James Dong } 10229a84457aed4c45bc900998b5e11c03023264208James Dong 10329a84457aed4c45bc900998b5e11c03023264208James Dong RCUpdateBuffer(video, rateCtrl, frameInc - rateCtrl->skip_next_frame); /* in case more frames dropped */ 10429a84457aed4c45bc900998b5e11c03023264208James Dong 10529a84457aed4c45bc900998b5e11c03023264208James Dong *frameNum = currFrameNum; 10629a84457aed4c45bc900998b5e11c03023264208James Dong 10729a84457aed4c45bc900998b5e11c03023264208James Dong /* This part would be similar to DetermineVopType of m4venc */ 10829a84457aed4c45bc900998b5e11c03023264208James Dong if ((*frameNum >= (uint)rateCtrl->idrPeriod && rateCtrl->idrPeriod > 0) || (*frameNum > video->MaxFrameNum)) /* first frame or IDR*/ 10929a84457aed4c45bc900998b5e11c03023264208James Dong { 11029a84457aed4c45bc900998b5e11c03023264208James Dong /* set frame type to IDR-frame */ 11129a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->idrPeriod) 11229a84457aed4c45bc900998b5e11c03023264208James Dong { 11329a84457aed4c45bc900998b5e11c03023264208James Dong encvid->modTimeRef += (uint32)(rateCtrl->idrPeriod * 1000 / rateCtrl->frame_rate); 11429a84457aed4c45bc900998b5e11c03023264208James Dong *frameNum -= rateCtrl->idrPeriod; 11529a84457aed4c45bc900998b5e11c03023264208James Dong } 11629a84457aed4c45bc900998b5e11c03023264208James Dong else 11729a84457aed4c45bc900998b5e11c03023264208James Dong { 11829a84457aed4c45bc900998b5e11c03023264208James Dong encvid->modTimeRef += (uint32)(video->MaxFrameNum * 1000 / rateCtrl->frame_rate); 11929a84457aed4c45bc900998b5e11c03023264208James Dong *frameNum -= video->MaxFrameNum; 12029a84457aed4c45bc900998b5e11c03023264208James Dong } 12129a84457aed4c45bc900998b5e11c03023264208James Dong 12229a84457aed4c45bc900998b5e11c03023264208James Dong video->nal_unit_type = AVC_NALTYPE_IDR; 12329a84457aed4c45bc900998b5e11c03023264208James Dong sliceHdr->slice_type = AVC_I_ALL_SLICE; 12429a84457aed4c45bc900998b5e11c03023264208James Dong video->slice_type = AVC_I_SLICE; 12529a84457aed4c45bc900998b5e11c03023264208James Dong encvid->prevProcFrameNum = *frameNum; 12629a84457aed4c45bc900998b5e11c03023264208James Dong } 12729a84457aed4c45bc900998b5e11c03023264208James Dong else 12829a84457aed4c45bc900998b5e11c03023264208James Dong { 12929a84457aed4c45bc900998b5e11c03023264208James Dong video->nal_unit_type = AVC_NALTYPE_SLICE; 13029a84457aed4c45bc900998b5e11c03023264208James Dong sliceHdr->slice_type = AVC_P_ALL_SLICE; 13129a84457aed4c45bc900998b5e11c03023264208James Dong video->slice_type = AVC_P_SLICE; 13229a84457aed4c45bc900998b5e11c03023264208James Dong encvid->prevProcFrameNum = currFrameNum; 13329a84457aed4c45bc900998b5e11c03023264208James Dong } 13429a84457aed4c45bc900998b5e11c03023264208James Dong 13529a84457aed4c45bc900998b5e11c03023264208James Dong } 13629a84457aed4c45bc900998b5e11c03023264208James Dong 13729a84457aed4c45bc900998b5e11c03023264208James Dong return AVCENC_SUCCESS; 13829a84457aed4c45bc900998b5e11c03023264208James Dong} 13929a84457aed4c45bc900998b5e11c03023264208James Dong 14029a84457aed4c45bc900998b5e11c03023264208James Dongvoid RCUpdateBuffer(AVCCommonObj *video, AVCRateControl *rateCtrl, int frameInc) 14129a84457aed4c45bc900998b5e11c03023264208James Dong{ 14229a84457aed4c45bc900998b5e11c03023264208James Dong int tmp; 14329a84457aed4c45bc900998b5e11c03023264208James Dong MultiPass *pMP = rateCtrl->pMP; 14429a84457aed4c45bc900998b5e11c03023264208James Dong 14529a84457aed4c45bc900998b5e11c03023264208James Dong OSCL_UNUSED_ARG(video); 14629a84457aed4c45bc900998b5e11c03023264208James Dong 14729a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->rcEnable == TRUE) 14829a84457aed4c45bc900998b5e11c03023264208James Dong { 14929a84457aed4c45bc900998b5e11c03023264208James Dong if (frameInc > 1) 15029a84457aed4c45bc900998b5e11c03023264208James Dong { 15129a84457aed4c45bc900998b5e11c03023264208James Dong tmp = rateCtrl->bitsPerFrame * (frameInc - 1); 15229a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->VBV_fullness -= tmp; 15329a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc += 10 * (frameInc - 1); 15429a84457aed4c45bc900998b5e11c03023264208James Dong 15529a84457aed4c45bc900998b5e11c03023264208James Dong /* Check buffer underflow */ 15629a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->VBV_fullness < rateCtrl->low_bound) 15729a84457aed4c45bc900998b5e11c03023264208James Dong { 15829a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->VBV_fullness = rateCtrl->low_bound; // -rateCtrl->Bs/2; 15929a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_W = rateCtrl->VBV_fullness - rateCtrl->low_bound; 16029a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc = pMP->counter_BTdst + (int)((OsclFloat)(rateCtrl->Bs / 2 - rateCtrl->low_bound) / 2.0 / (pMP->target_bits_per_frame / 10)); 16129a84457aed4c45bc900998b5e11c03023264208James Dong } 16229a84457aed4c45bc900998b5e11c03023264208James Dong } 16329a84457aed4c45bc900998b5e11c03023264208James Dong } 16429a84457aed4c45bc900998b5e11c03023264208James Dong} 16529a84457aed4c45bc900998b5e11c03023264208James Dong 16629a84457aed4c45bc900998b5e11c03023264208James Dong 16729a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status InitRateControlModule(AVCHandle *avcHandle) 16829a84457aed4c45bc900998b5e11c03023264208James Dong{ 16929a84457aed4c45bc900998b5e11c03023264208James Dong AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject; 17029a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 17129a84457aed4c45bc900998b5e11c03023264208James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 17229a84457aed4c45bc900998b5e11c03023264208James Dong double L1, L2, L3, bpp; 17329a84457aed4c45bc900998b5e11c03023264208James Dong int qp; 17429a84457aed4c45bc900998b5e11c03023264208James Dong int i, j; 17529a84457aed4c45bc900998b5e11c03023264208James Dong 17629a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->basicUnit = video->PicSizeInMbs; 17729a84457aed4c45bc900998b5e11c03023264208James Dong 17829a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->MADofMB = (double*) avcHandle->CBAVC_Malloc(encvid->avcHandle->userData, 17929a84457aed4c45bc900998b5e11c03023264208James Dong video->PicSizeInMbs * sizeof(double), DEFAULT_ATTR); 18029a84457aed4c45bc900998b5e11c03023264208James Dong 18129a84457aed4c45bc900998b5e11c03023264208James Dong if (!rateCtrl->MADofMB) 18229a84457aed4c45bc900998b5e11c03023264208James Dong { 18329a84457aed4c45bc900998b5e11c03023264208James Dong goto CLEANUP_RC; 18429a84457aed4c45bc900998b5e11c03023264208James Dong } 18529a84457aed4c45bc900998b5e11c03023264208James Dong 18629a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->rcEnable == TRUE) 18729a84457aed4c45bc900998b5e11c03023264208James Dong { 18829a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP = (MultiPass*) avcHandle->CBAVC_Malloc(encvid->avcHandle->userData, sizeof(MultiPass), DEFAULT_ATTR); 18929a84457aed4c45bc900998b5e11c03023264208James Dong if (!rateCtrl->pMP) 19029a84457aed4c45bc900998b5e11c03023264208James Dong { 19129a84457aed4c45bc900998b5e11c03023264208James Dong goto CLEANUP_RC; 19229a84457aed4c45bc900998b5e11c03023264208James Dong } 19329a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->encoded_frames = -1; /* forget about the very first I frame */ 19429a84457aed4c45bc900998b5e11c03023264208James Dong 19529a84457aed4c45bc900998b5e11c03023264208James Dong /* RDInfo **pRDSamples */ 19629a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->pRDSamples = (RDInfo **)avcHandle->CBAVC_Malloc(encvid->avcHandle->userData, (30 * sizeof(RDInfo *)), DEFAULT_ATTR); 19729a84457aed4c45bc900998b5e11c03023264208James Dong if (!rateCtrl->pMP->pRDSamples) 19829a84457aed4c45bc900998b5e11c03023264208James Dong { 19929a84457aed4c45bc900998b5e11c03023264208James Dong goto CLEANUP_RC; 20029a84457aed4c45bc900998b5e11c03023264208James Dong } 20129a84457aed4c45bc900998b5e11c03023264208James Dong 20229a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 0; i < 30; i++) 20329a84457aed4c45bc900998b5e11c03023264208James Dong { 20429a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->pRDSamples[i] = (RDInfo *)avcHandle->CBAVC_Malloc(encvid->avcHandle->userData, (32 * sizeof(RDInfo)), DEFAULT_ATTR); 20529a84457aed4c45bc900998b5e11c03023264208James Dong if (!rateCtrl->pMP->pRDSamples[i]) 20629a84457aed4c45bc900998b5e11c03023264208James Dong { 20729a84457aed4c45bc900998b5e11c03023264208James Dong goto CLEANUP_RC; 20829a84457aed4c45bc900998b5e11c03023264208James Dong } 20929a84457aed4c45bc900998b5e11c03023264208James Dong } 21029a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->frameRange = (int)(rateCtrl->frame_rate * 1.0); /* 1.0s time frame*/ 21129a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->frameRange = AVC_MAX(rateCtrl->pMP->frameRange, 5); 21229a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->frameRange = AVC_MIN(rateCtrl->pMP->frameRange, 30); 21329a84457aed4c45bc900998b5e11c03023264208James Dong 21429a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->framePos = -1; 21529a84457aed4c45bc900998b5e11c03023264208James Dong 21629a84457aed4c45bc900998b5e11c03023264208James Dong 21729a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->bitsPerFrame = (int32)(rateCtrl->bitRate / rateCtrl->frame_rate); 21829a84457aed4c45bc900998b5e11c03023264208James Dong 21929a84457aed4c45bc900998b5e11c03023264208James Dong /* BX rate control */ 22029a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->skip_next_frame = 0; /* must be initialized */ 22129a84457aed4c45bc900998b5e11c03023264208James Dong 22229a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->Bs = rateCtrl->cpbSize; 22329a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_W = 0; 22429a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->VBV_fullness = (int)(rateCtrl->Bs * 0.5); /* rateCtrl->Bs */ 22529a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->encoded_frames = 0; 22629a84457aed4c45bc900998b5e11c03023264208James Dong 22729a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_TH = rateCtrl->bitsPerFrame; 22829a84457aed4c45bc900998b5e11c03023264208James Dong 22929a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->max_BitVariance_num = (int)((OsclFloat)(rateCtrl->Bs - rateCtrl->VBV_fullness) / (rateCtrl->bitsPerFrame / 10.0)) - 5; 23029a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->max_BitVariance_num < 0) rateCtrl->max_BitVariance_num += 5; 23129a84457aed4c45bc900998b5e11c03023264208James Dong 23229a84457aed4c45bc900998b5e11c03023264208James Dong // Set the initial buffer fullness 23329a84457aed4c45bc900998b5e11c03023264208James Dong /* According to the spec, the initial buffer fullness needs to be set to 1/3 */ 23429a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->VBV_fullness = (int)(rateCtrl->Bs / 3.0 - rateCtrl->Bs / 2.0); /* the buffer range is [-Bs/2, Bs/2] */ 23529a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->counter_BTsrc = (int)((rateCtrl->Bs / 2.0 - rateCtrl->Bs / 3.0) / (rateCtrl->bitsPerFrame / 10.0)); 23629a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_W = (int)(rateCtrl->VBV_fullness + rateCtrl->pMP->counter_BTsrc * (rateCtrl->bitsPerFrame / 10.0)); 23729a84457aed4c45bc900998b5e11c03023264208James Dong 23829a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->low_bound = -rateCtrl->Bs / 2; 23929a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->VBV_fullness_offset = 0; 24029a84457aed4c45bc900998b5e11c03023264208James Dong 24129a84457aed4c45bc900998b5e11c03023264208James Dong /* Setting the bitrate and framerate */ 24229a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->bitrate = rateCtrl->bitRate; 24329a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->framerate = rateCtrl->frame_rate; 24429a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->pMP->target_bits_per_frame = rateCtrl->pMP->bitrate / rateCtrl->pMP->framerate; 24529a84457aed4c45bc900998b5e11c03023264208James Dong 24629a84457aed4c45bc900998b5e11c03023264208James Dong /*compute the initial QP*/ 24729a84457aed4c45bc900998b5e11c03023264208James Dong bpp = 1.0 * rateCtrl->bitRate / (rateCtrl->frame_rate * (video->PicSizeInMbs << 8)); 24829a84457aed4c45bc900998b5e11c03023264208James Dong if (video->PicWidthInSamplesL == 176) 24929a84457aed4c45bc900998b5e11c03023264208James Dong { 25029a84457aed4c45bc900998b5e11c03023264208James Dong L1 = 0.1; 25129a84457aed4c45bc900998b5e11c03023264208James Dong L2 = 0.3; 25229a84457aed4c45bc900998b5e11c03023264208James Dong L3 = 0.6; 25329a84457aed4c45bc900998b5e11c03023264208James Dong } 25429a84457aed4c45bc900998b5e11c03023264208James Dong else if (video->PicWidthInSamplesL == 352) 25529a84457aed4c45bc900998b5e11c03023264208James Dong { 25629a84457aed4c45bc900998b5e11c03023264208James Dong L1 = 0.2; 25729a84457aed4c45bc900998b5e11c03023264208James Dong L2 = 0.6; 25829a84457aed4c45bc900998b5e11c03023264208James Dong L3 = 1.2; 25929a84457aed4c45bc900998b5e11c03023264208James Dong } 26029a84457aed4c45bc900998b5e11c03023264208James Dong else 26129a84457aed4c45bc900998b5e11c03023264208James Dong { 26229a84457aed4c45bc900998b5e11c03023264208James Dong L1 = 0.6; 26329a84457aed4c45bc900998b5e11c03023264208James Dong L2 = 1.4; 26429a84457aed4c45bc900998b5e11c03023264208James Dong L3 = 2.4; 26529a84457aed4c45bc900998b5e11c03023264208James Dong } 26629a84457aed4c45bc900998b5e11c03023264208James Dong 26729a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->initQP == 0) 26829a84457aed4c45bc900998b5e11c03023264208James Dong { 26929a84457aed4c45bc900998b5e11c03023264208James Dong if (bpp <= L1) 27029a84457aed4c45bc900998b5e11c03023264208James Dong qp = 35; 27129a84457aed4c45bc900998b5e11c03023264208James Dong else if (bpp <= L2) 27229a84457aed4c45bc900998b5e11c03023264208James Dong qp = 25; 27329a84457aed4c45bc900998b5e11c03023264208James Dong else if (bpp <= L3) 27429a84457aed4c45bc900998b5e11c03023264208James Dong qp = 20; 27529a84457aed4c45bc900998b5e11c03023264208James Dong else 27629a84457aed4c45bc900998b5e11c03023264208James Dong qp = 15; 27729a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->initQP = qp; 27829a84457aed4c45bc900998b5e11c03023264208James Dong } 27929a84457aed4c45bc900998b5e11c03023264208James Dong 28029a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->Qc = rateCtrl->initQP; 28129a84457aed4c45bc900998b5e11c03023264208James Dong } 28229a84457aed4c45bc900998b5e11c03023264208James Dong 28329a84457aed4c45bc900998b5e11c03023264208James Dong return AVCENC_SUCCESS; 28429a84457aed4c45bc900998b5e11c03023264208James Dong 28529a84457aed4c45bc900998b5e11c03023264208James DongCLEANUP_RC: 28629a84457aed4c45bc900998b5e11c03023264208James Dong 28729a84457aed4c45bc900998b5e11c03023264208James Dong CleanupRateControlModule(avcHandle); 28829a84457aed4c45bc900998b5e11c03023264208James Dong return AVCENC_MEMORY_FAIL; 28929a84457aed4c45bc900998b5e11c03023264208James Dong 29029a84457aed4c45bc900998b5e11c03023264208James Dong} 29129a84457aed4c45bc900998b5e11c03023264208James Dong 29229a84457aed4c45bc900998b5e11c03023264208James Dong 29329a84457aed4c45bc900998b5e11c03023264208James Dongvoid CleanupRateControlModule(AVCHandle *avcHandle) 29429a84457aed4c45bc900998b5e11c03023264208James Dong{ 29529a84457aed4c45bc900998b5e11c03023264208James Dong AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject; 29629a84457aed4c45bc900998b5e11c03023264208James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 29729a84457aed4c45bc900998b5e11c03023264208James Dong int i; 29829a84457aed4c45bc900998b5e11c03023264208James Dong 29929a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->MADofMB) 30029a84457aed4c45bc900998b5e11c03023264208James Dong { 30123da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo avcHandle->CBAVC_Free(avcHandle->userData, rateCtrl->MADofMB); 30229a84457aed4c45bc900998b5e11c03023264208James Dong } 30329a84457aed4c45bc900998b5e11c03023264208James Dong 30429a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->pMP) 30529a84457aed4c45bc900998b5e11c03023264208James Dong { 30629a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->pMP->pRDSamples) 30729a84457aed4c45bc900998b5e11c03023264208James Dong { 30829a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 0; i < 30; i++) 30929a84457aed4c45bc900998b5e11c03023264208James Dong { 31029a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->pMP->pRDSamples[i]) 31129a84457aed4c45bc900998b5e11c03023264208James Dong { 31223da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo avcHandle->CBAVC_Free(avcHandle->userData, rateCtrl->pMP->pRDSamples[i]); 31329a84457aed4c45bc900998b5e11c03023264208James Dong } 31429a84457aed4c45bc900998b5e11c03023264208James Dong } 31523da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo avcHandle->CBAVC_Free(avcHandle->userData, rateCtrl->pMP->pRDSamples); 31629a84457aed4c45bc900998b5e11c03023264208James Dong } 31723da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo avcHandle->CBAVC_Free(avcHandle->userData, rateCtrl->pMP); 31829a84457aed4c45bc900998b5e11c03023264208James Dong } 31929a84457aed4c45bc900998b5e11c03023264208James Dong 32029a84457aed4c45bc900998b5e11c03023264208James Dong return ; 32129a84457aed4c45bc900998b5e11c03023264208James Dong} 32229a84457aed4c45bc900998b5e11c03023264208James Dong 32329a84457aed4c45bc900998b5e11c03023264208James Dongvoid RCInitGOP(AVCEncObject *encvid) 32429a84457aed4c45bc900998b5e11c03023264208James Dong{ 32529a84457aed4c45bc900998b5e11c03023264208James Dong /* in BX RC, there's no GOP-level RC */ 32629a84457aed4c45bc900998b5e11c03023264208James Dong 32729a84457aed4c45bc900998b5e11c03023264208James Dong OSCL_UNUSED_ARG(encvid); 32829a84457aed4c45bc900998b5e11c03023264208James Dong 32929a84457aed4c45bc900998b5e11c03023264208James Dong return ; 33029a84457aed4c45bc900998b5e11c03023264208James Dong} 33129a84457aed4c45bc900998b5e11c03023264208James Dong 33229a84457aed4c45bc900998b5e11c03023264208James Dong 33329a84457aed4c45bc900998b5e11c03023264208James Dongvoid RCInitFrameQP(AVCEncObject *encvid) 33429a84457aed4c45bc900998b5e11c03023264208James Dong{ 33529a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 33629a84457aed4c45bc900998b5e11c03023264208James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 33729a84457aed4c45bc900998b5e11c03023264208James Dong AVCPicParamSet *picParam = video->currPicParams; 33829a84457aed4c45bc900998b5e11c03023264208James Dong MultiPass *pMP = rateCtrl->pMP; 33929a84457aed4c45bc900998b5e11c03023264208James Dong 34029a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->rcEnable == TRUE) 34129a84457aed4c45bc900998b5e11c03023264208James Dong { 34229a84457aed4c45bc900998b5e11c03023264208James Dong /* frame layer rate control */ 34329a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->encoded_frames == 0) 34429a84457aed4c45bc900998b5e11c03023264208James Dong { 34529a84457aed4c45bc900998b5e11c03023264208James Dong video->QPy = rateCtrl->Qc = rateCtrl->initQP; 34629a84457aed4c45bc900998b5e11c03023264208James Dong } 34729a84457aed4c45bc900998b5e11c03023264208James Dong else 34829a84457aed4c45bc900998b5e11c03023264208James Dong { 34929a84457aed4c45bc900998b5e11c03023264208James Dong calculateQuantizer_Multipass(encvid, video, rateCtrl, pMP); 35029a84457aed4c45bc900998b5e11c03023264208James Dong video->QPy = rateCtrl->Qc; 35129a84457aed4c45bc900998b5e11c03023264208James Dong } 35229a84457aed4c45bc900998b5e11c03023264208James Dong 35329a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->NumberofHeaderBits = 0; 35429a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->NumberofTextureBits = 0; 35529a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->numFrameBits = 0; // reset 35629a84457aed4c45bc900998b5e11c03023264208James Dong 35729a84457aed4c45bc900998b5e11c03023264208James Dong /* update pMP->framePos */ 35829a84457aed4c45bc900998b5e11c03023264208James Dong if (++pMP->framePos == pMP->frameRange) pMP->framePos = 0; 35929a84457aed4c45bc900998b5e11c03023264208James Dong 36029a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->T == 0) 36129a84457aed4c45bc900998b5e11c03023264208James Dong { 36229a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTdst = (int)(rateCtrl->frame_rate * 7.5 + 0.5); /* 0.75s time frame */ 36329a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTdst = AVC_MIN(pMP->counter_BTdst, (int)(rateCtrl->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 */ 36429a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTdst = AVC_MAX(pMP->counter_BTdst, (int)((rateCtrl->Bs / 2 - rateCtrl->VBV_fullness) * 0.30 / (rateCtrl->TMN_TH / 10.0) + 0.5)); /* At least 30% of VBV buffer size/2 */ 36529a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTdst = AVC_MIN(pMP->counter_BTdst, 20); /* Limit the target to be smaller than 3C */ 36629a84457aed4c45bc900998b5e11c03023264208James Dong 36729a84457aed4c45bc900998b5e11c03023264208James Dong pMP->target_bits = rateCtrl->T = rateCtrl->TMN_TH = (int)(rateCtrl->TMN_TH * (1.0 + pMP->counter_BTdst * 0.1)); 36829a84457aed4c45bc900998b5e11c03023264208James Dong pMP->diff_counter = pMP->counter_BTdst; 36929a84457aed4c45bc900998b5e11c03023264208James Dong } 37029a84457aed4c45bc900998b5e11c03023264208James Dong 37129a84457aed4c45bc900998b5e11c03023264208James Dong /* collect the necessary data: target bits, actual bits, mad and QP */ 37229a84457aed4c45bc900998b5e11c03023264208James Dong pMP->target_bits = rateCtrl->T; 37329a84457aed4c45bc900998b5e11c03023264208James Dong pMP->QP = video->QPy; 37429a84457aed4c45bc900998b5e11c03023264208James Dong 37529a84457aed4c45bc900998b5e11c03023264208James Dong pMP->mad = (OsclFloat)rateCtrl->totalSAD / video->PicSizeInMbs; //ComputeFrameMAD(video, rateCtrl); 37629a84457aed4c45bc900998b5e11c03023264208James Dong if (pMP->mad < MAD_MIN) pMP->mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ 37729a84457aed4c45bc900998b5e11c03023264208James Dong 37829a84457aed4c45bc900998b5e11c03023264208James Dong pMP->bitrate = rateCtrl->bitRate; /* calculated in RCVopQPSetting */ 37929a84457aed4c45bc900998b5e11c03023264208James Dong pMP->framerate = rateCtrl->frame_rate; 38029a84457aed4c45bc900998b5e11c03023264208James Dong 38129a84457aed4c45bc900998b5e11c03023264208James Dong /* first pass encoding */ 38229a84457aed4c45bc900998b5e11c03023264208James Dong pMP->nRe_Quantized = 0; 38329a84457aed4c45bc900998b5e11c03023264208James Dong 38429a84457aed4c45bc900998b5e11c03023264208James Dong } // rcEnable 38529a84457aed4c45bc900998b5e11c03023264208James Dong else 38629a84457aed4c45bc900998b5e11c03023264208James Dong { 38729a84457aed4c45bc900998b5e11c03023264208James Dong video->QPy = rateCtrl->initQP; 38829a84457aed4c45bc900998b5e11c03023264208James Dong } 38929a84457aed4c45bc900998b5e11c03023264208James Dong 39029a84457aed4c45bc900998b5e11c03023264208James Dong// printf(" %d ",video->QPy); 39129a84457aed4c45bc900998b5e11c03023264208James Dong 39229a84457aed4c45bc900998b5e11c03023264208James Dong if (video->CurrPicNum == 0 && encvid->outOfBandParamSet == FALSE) 39329a84457aed4c45bc900998b5e11c03023264208James Dong { 39429a84457aed4c45bc900998b5e11c03023264208James Dong picParam->pic_init_qs_minus26 = 0; 39529a84457aed4c45bc900998b5e11c03023264208James Dong picParam->pic_init_qp_minus26 = video->QPy - 26; 39629a84457aed4c45bc900998b5e11c03023264208James Dong } 39729a84457aed4c45bc900998b5e11c03023264208James Dong 39829a84457aed4c45bc900998b5e11c03023264208James Dong // need this for motion estimation 39929a84457aed4c45bc900998b5e11c03023264208James Dong encvid->lambda_mode = QP2QUANT[AVC_MAX(0, video->QPy-SHIFT_QP)]; 40029a84457aed4c45bc900998b5e11c03023264208James Dong encvid->lambda_motion = LAMBDA_FACTOR(encvid->lambda_mode); 40129a84457aed4c45bc900998b5e11c03023264208James Dong return ; 40229a84457aed4c45bc900998b5e11c03023264208James Dong} 40329a84457aed4c45bc900998b5e11c03023264208James Dong 40429a84457aed4c45bc900998b5e11c03023264208James Dong/* Mad based variable bit allocation + QP calculation with a new quadratic method */ 40529a84457aed4c45bc900998b5e11c03023264208James Dongvoid calculateQuantizer_Multipass(AVCEncObject *encvid, AVCCommonObj *video, 40629a84457aed4c45bc900998b5e11c03023264208James Dong AVCRateControl *rateCtrl, MultiPass *pMP) 40729a84457aed4c45bc900998b5e11c03023264208James Dong{ 40829a84457aed4c45bc900998b5e11c03023264208James Dong int prev_actual_bits = 0, curr_target, /*pos=0,*/i, j; 40929a84457aed4c45bc900998b5e11c03023264208James Dong OsclFloat Qstep, prev_QP = 0.625; 41029a84457aed4c45bc900998b5e11c03023264208James Dong 41129a84457aed4c45bc900998b5e11c03023264208James Dong OsclFloat curr_mad, prev_mad, curr_RD, prev_RD, average_mad, aver_QP; 41229a84457aed4c45bc900998b5e11c03023264208James Dong 41329a84457aed4c45bc900998b5e11c03023264208James Dong /* Mad based variable bit allocation */ 41429a84457aed4c45bc900998b5e11c03023264208James Dong targetBitCalculation(encvid, video, rateCtrl, pMP); 41529a84457aed4c45bc900998b5e11c03023264208James Dong 41629a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->T <= 0 || rateCtrl->totalSAD == 0) 41729a84457aed4c45bc900998b5e11c03023264208James Dong { 41829a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->T < 0) rateCtrl->Qc = RC_MAX_QUANT; 41929a84457aed4c45bc900998b5e11c03023264208James Dong return; 42029a84457aed4c45bc900998b5e11c03023264208James Dong } 42129a84457aed4c45bc900998b5e11c03023264208James Dong 42229a84457aed4c45bc900998b5e11c03023264208James Dong /* ---------------------------------------------------------------------------------------------------*/ 42329a84457aed4c45bc900998b5e11c03023264208James Dong /* current frame QP estimation */ 42429a84457aed4c45bc900998b5e11c03023264208James Dong curr_target = rateCtrl->T; 42529a84457aed4c45bc900998b5e11c03023264208James Dong curr_mad = (OsclFloat)rateCtrl->totalSAD / video->PicSizeInMbs; 42629a84457aed4c45bc900998b5e11c03023264208James Dong if (curr_mad < MAD_MIN) curr_mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ 42729a84457aed4c45bc900998b5e11c03023264208James Dong curr_RD = (OsclFloat)curr_target / curr_mad; 42829a84457aed4c45bc900998b5e11c03023264208James Dong 42929a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->skip_next_frame == -1) // previous was skipped 43029a84457aed4c45bc900998b5e11c03023264208James Dong { 43129a84457aed4c45bc900998b5e11c03023264208James Dong i = pMP->framePos; 43229a84457aed4c45bc900998b5e11c03023264208James Dong prev_mad = pMP->pRDSamples[i][0].mad; 43329a84457aed4c45bc900998b5e11c03023264208James Dong prev_QP = pMP->pRDSamples[i][0].QP; 43429a84457aed4c45bc900998b5e11c03023264208James Dong prev_actual_bits = pMP->pRDSamples[i][0].actual_bits; 43529a84457aed4c45bc900998b5e11c03023264208James Dong } 43629a84457aed4c45bc900998b5e11c03023264208James Dong else 43729a84457aed4c45bc900998b5e11c03023264208James Dong { 43829a84457aed4c45bc900998b5e11c03023264208James Dong /* Another version of search the optimal point */ 43929a84457aed4c45bc900998b5e11c03023264208James Dong prev_mad = 0.0; 44029a84457aed4c45bc900998b5e11c03023264208James Dong i = 0; 44129a84457aed4c45bc900998b5e11c03023264208James Dong while (i < pMP->frameRange && prev_mad < 0.001) /* find first one with nonzero prev_mad */ 44229a84457aed4c45bc900998b5e11c03023264208James Dong { 44329a84457aed4c45bc900998b5e11c03023264208James Dong prev_mad = pMP->pRDSamples[i][0].mad; 44429a84457aed4c45bc900998b5e11c03023264208James Dong i++; 44529a84457aed4c45bc900998b5e11c03023264208James Dong } 44629a84457aed4c45bc900998b5e11c03023264208James Dong 44729a84457aed4c45bc900998b5e11c03023264208James Dong if (i < pMP->frameRange) 44829a84457aed4c45bc900998b5e11c03023264208James Dong { 44929a84457aed4c45bc900998b5e11c03023264208James Dong prev_actual_bits = pMP->pRDSamples[i-1][0].actual_bits; 45029a84457aed4c45bc900998b5e11c03023264208James Dong 45129a84457aed4c45bc900998b5e11c03023264208James Dong for (j = 0; i < pMP->frameRange; i++) 45229a84457aed4c45bc900998b5e11c03023264208James Dong { 45329a84457aed4c45bc900998b5e11c03023264208James Dong if (pMP->pRDSamples[i][0].mad != 0 && 45429a84457aed4c45bc900998b5e11c03023264208James Dong AVC_ABS(prev_mad - curr_mad) > AVC_ABS(pMP->pRDSamples[i][0].mad - curr_mad)) 45529a84457aed4c45bc900998b5e11c03023264208James Dong { 45629a84457aed4c45bc900998b5e11c03023264208James Dong prev_mad = pMP->pRDSamples[i][0].mad; 45729a84457aed4c45bc900998b5e11c03023264208James Dong prev_actual_bits = pMP->pRDSamples[i][0].actual_bits; 45829a84457aed4c45bc900998b5e11c03023264208James Dong j = i; 45929a84457aed4c45bc900998b5e11c03023264208James Dong } 46029a84457aed4c45bc900998b5e11c03023264208James Dong } 46129a84457aed4c45bc900998b5e11c03023264208James Dong prev_QP = QP2Qstep(pMP->pRDSamples[j][0].QP); 46229a84457aed4c45bc900998b5e11c03023264208James Dong 46329a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 1; i < pMP->samplesPerFrame[j]; i++) 46429a84457aed4c45bc900998b5e11c03023264208James Dong { 46529a84457aed4c45bc900998b5e11c03023264208James Dong if (AVC_ABS(prev_actual_bits - curr_target) > AVC_ABS(pMP->pRDSamples[j][i].actual_bits - curr_target)) 46629a84457aed4c45bc900998b5e11c03023264208James Dong { 46729a84457aed4c45bc900998b5e11c03023264208James Dong prev_actual_bits = pMP->pRDSamples[j][i].actual_bits; 46829a84457aed4c45bc900998b5e11c03023264208James Dong prev_QP = QP2Qstep(pMP->pRDSamples[j][i].QP); 46929a84457aed4c45bc900998b5e11c03023264208James Dong } 47029a84457aed4c45bc900998b5e11c03023264208James Dong } 47129a84457aed4c45bc900998b5e11c03023264208James Dong } 47229a84457aed4c45bc900998b5e11c03023264208James Dong } 47329a84457aed4c45bc900998b5e11c03023264208James Dong 47429a84457aed4c45bc900998b5e11c03023264208James Dong // quadratic approximation 47529a84457aed4c45bc900998b5e11c03023264208James Dong if (prev_mad > 0.001) // only when prev_mad is greater than 0, otherwise keep using the same QP 47629a84457aed4c45bc900998b5e11c03023264208James Dong { 47729a84457aed4c45bc900998b5e11c03023264208James Dong prev_RD = (OsclFloat)prev_actual_bits / prev_mad; 47829a84457aed4c45bc900998b5e11c03023264208James Dong //rateCtrl->Qc = (Int)(prev_QP * sqrt(prev_actual_bits/curr_target) + 0.4); 47929a84457aed4c45bc900998b5e11c03023264208James Dong if (prev_QP == 0.625) // added this to allow getting out of QP = 0 easily 48029a84457aed4c45bc900998b5e11c03023264208James Dong { 48129a84457aed4c45bc900998b5e11c03023264208James Dong Qstep = (int)(prev_RD / curr_RD + 0.5); 48229a84457aed4c45bc900998b5e11c03023264208James Dong } 48329a84457aed4c45bc900998b5e11c03023264208James Dong else 48429a84457aed4c45bc900998b5e11c03023264208James Dong { 48529a84457aed4c45bc900998b5e11c03023264208James Dong // rateCtrl->Qc =(Int)(prev_QP * M4VENC_SQRT(prev_RD/curr_RD) + 0.9); 48629a84457aed4c45bc900998b5e11c03023264208James Dong 48729a84457aed4c45bc900998b5e11c03023264208James Dong if (prev_RD / curr_RD > 0.5 && prev_RD / curr_RD < 2.0) 48829a84457aed4c45bc900998b5e11c03023264208James Dong Qstep = (int)(prev_QP * (sqrt(prev_RD / curr_RD) + prev_RD / curr_RD) / 2.0 + 0.9); /* Quadratic and linear approximation */ 48929a84457aed4c45bc900998b5e11c03023264208James Dong else 49029a84457aed4c45bc900998b5e11c03023264208James Dong Qstep = (int)(prev_QP * (sqrt(prev_RD / curr_RD) + pow(prev_RD / curr_RD, 1.0 / 3.0)) / 2.0 + 0.9); 49129a84457aed4c45bc900998b5e11c03023264208James Dong } 49229a84457aed4c45bc900998b5e11c03023264208James Dong // lower bound on Qc should be a function of curr_mad 49329a84457aed4c45bc900998b5e11c03023264208James Dong // When mad is already low, lower bound on Qc doesn't have to be small. 49429a84457aed4c45bc900998b5e11c03023264208James Dong // Note, this doesn't work well for low complexity clip encoded at high bit rate 49529a84457aed4c45bc900998b5e11c03023264208James Dong // it doesn't hit the target bit rate due to this QP lower bound. 49629a84457aed4c45bc900998b5e11c03023264208James Dong /// if((curr_mad < 8) && (rateCtrl->Qc < 12)) rateCtrl->Qc = 12; 49729a84457aed4c45bc900998b5e11c03023264208James Dong // else if((curr_mad < 128) && (rateCtrl->Qc < 3)) rateCtrl->Qc = 3; 49829a84457aed4c45bc900998b5e11c03023264208James Dong 49929a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->Qc = Qstep2QP(Qstep); 50029a84457aed4c45bc900998b5e11c03023264208James Dong 50129a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->Qc < RC_MIN_QUANT) rateCtrl->Qc = RC_MIN_QUANT; 50229a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->Qc > RC_MAX_QUANT) rateCtrl->Qc = RC_MAX_QUANT; 50329a84457aed4c45bc900998b5e11c03023264208James Dong } 50429a84457aed4c45bc900998b5e11c03023264208James Dong 50529a84457aed4c45bc900998b5e11c03023264208James Dong /* active bit resource protection */ 50629a84457aed4c45bc900998b5e11c03023264208James Dong aver_QP = (pMP->encoded_frames == 0 ? 0 : pMP->sum_QP / (OsclFloat)pMP->encoded_frames); 50729a84457aed4c45bc900998b5e11c03023264208James Dong average_mad = (pMP->encoded_frames == 0 ? 0 : pMP->sum_mad / (OsclFloat)pMP->encoded_frames); /* this function is called from the scond encoded frame*/ 50829a84457aed4c45bc900998b5e11c03023264208James Dong if (pMP->diff_counter == 0 && 50929a84457aed4c45bc900998b5e11c03023264208James Dong ((OsclFloat)rateCtrl->Qc <= aver_QP*1.1 || curr_mad <= average_mad*1.1) && 51029a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc <= (pMP->counter_BTdst + (int)(pMP->framerate*1.0 + 0.5))) 51129a84457aed4c45bc900998b5e11c03023264208James Dong { 51229a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_TH -= (int)(pMP->target_bits_per_frame / 10.0); 51329a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->T = rateCtrl->TMN_TH - rateCtrl->TMN_W; 51429a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc++; 51529a84457aed4c45bc900998b5e11c03023264208James Dong pMP->diff_counter--; 51629a84457aed4c45bc900998b5e11c03023264208James Dong } 51729a84457aed4c45bc900998b5e11c03023264208James Dong 51829a84457aed4c45bc900998b5e11c03023264208James Dong} 51929a84457aed4c45bc900998b5e11c03023264208James Dong 52029a84457aed4c45bc900998b5e11c03023264208James Dongvoid targetBitCalculation(AVCEncObject *encvid, AVCCommonObj *video, AVCRateControl *rateCtrl, MultiPass *pMP) 52129a84457aed4c45bc900998b5e11c03023264208James Dong{ 52229a84457aed4c45bc900998b5e11c03023264208James Dong OSCL_UNUSED_ARG(encvid); 52329a84457aed4c45bc900998b5e11c03023264208James Dong OsclFloat curr_mad;//, average_mad; 52429a84457aed4c45bc900998b5e11c03023264208James Dong int diff_counter_BTsrc, diff_counter_BTdst, prev_counter_diff, curr_counter_diff, bound; 52529a84457aed4c45bc900998b5e11c03023264208James Dong /* BT = Bit Transfer, for pMP->counter_BTsrc, pMP->counter_BTdst */ 52629a84457aed4c45bc900998b5e11c03023264208James Dong 52729a84457aed4c45bc900998b5e11c03023264208James Dong /* some stuff about frame dropping remained here to be done because pMP cannot be inserted into updateRateControl()*/ 52829a84457aed4c45bc900998b5e11c03023264208James Dong updateRC_PostProc(rateCtrl, pMP); 52929a84457aed4c45bc900998b5e11c03023264208James Dong 53029a84457aed4c45bc900998b5e11c03023264208James Dong /* update pMP->counter_BTsrc and pMP->counter_BTdst to avoid interger overflow */ 53129a84457aed4c45bc900998b5e11c03023264208James Dong if (pMP->counter_BTsrc > 1000 && pMP->counter_BTdst > 1000) 53229a84457aed4c45bc900998b5e11c03023264208James Dong { 53329a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc -= 1000; 53429a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTdst -= 1000; 53529a84457aed4c45bc900998b5e11c03023264208James Dong } 53629a84457aed4c45bc900998b5e11c03023264208James Dong 53729a84457aed4c45bc900998b5e11c03023264208James Dong /* ---------------------------------------------------------------------------------------------------*/ 53829a84457aed4c45bc900998b5e11c03023264208James Dong /* target calculation */ 53929a84457aed4c45bc900998b5e11c03023264208James Dong curr_mad = (OsclFloat)rateCtrl->totalSAD / video->PicSizeInMbs; 54029a84457aed4c45bc900998b5e11c03023264208James Dong if (curr_mad < MAD_MIN) curr_mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ 54129a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTsrc = diff_counter_BTdst = 0; 54229a84457aed4c45bc900998b5e11c03023264208James Dong pMP->diff_counter = 0; 54329a84457aed4c45bc900998b5e11c03023264208James Dong 54429a84457aed4c45bc900998b5e11c03023264208James Dong 54529a84457aed4c45bc900998b5e11c03023264208James Dong /*1.calculate average mad */ 54629a84457aed4c45bc900998b5e11c03023264208James Dong pMP->sum_mad += curr_mad; 54729a84457aed4c45bc900998b5e11c03023264208James Dong //average_mad = (pMP->encoded_frames < 1 ? curr_mad : pMP->sum_mad/(OsclFloat)(pMP->encoded_frames+1)); /* this function is called from the scond encoded frame*/ 54829a84457aed4c45bc900998b5e11c03023264208James Dong //pMP->aver_mad = average_mad; 54929a84457aed4c45bc900998b5e11c03023264208James Dong if (pMP->encoded_frames >= 0) /* pMP->encoded_frames is set to -1 initially, so forget about the very first I frame */ 55029a84457aed4c45bc900998b5e11c03023264208James Dong pMP->aver_mad = (pMP->aver_mad * pMP->encoded_frames + curr_mad) / (pMP->encoded_frames + 1); 55129a84457aed4c45bc900998b5e11c03023264208James Dong 55229a84457aed4c45bc900998b5e11c03023264208James Dong if (pMP->overlapped_win_size > 0 && pMP->encoded_frames_prev >= 0) 55329a84457aed4c45bc900998b5e11c03023264208James Dong pMP->aver_mad_prev = (pMP->aver_mad_prev * pMP->encoded_frames_prev + curr_mad) / (pMP->encoded_frames_prev + 1); 55429a84457aed4c45bc900998b5e11c03023264208James Dong 55529a84457aed4c45bc900998b5e11c03023264208James Dong /*2.average_mad, mad ==> diff_counter_BTsrc, diff_counter_BTdst */ 55629a84457aed4c45bc900998b5e11c03023264208James Dong if (pMP->overlapped_win_size == 0) 55729a84457aed4c45bc900998b5e11c03023264208James Dong { 55829a84457aed4c45bc900998b5e11c03023264208James Dong /* original verison */ 55929a84457aed4c45bc900998b5e11c03023264208James Dong if (curr_mad > pMP->aver_mad*1.1) 56029a84457aed4c45bc900998b5e11c03023264208James Dong { 56129a84457aed4c45bc900998b5e11c03023264208James Dong if (curr_mad / (pMP->aver_mad + 0.0001) > 2) 56229a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTdst = (int)(sqrt(curr_mad / (pMP->aver_mad + 0.0001)) * 10 + 0.4) - 10; 56329a84457aed4c45bc900998b5e11c03023264208James Dong //diff_counter_BTdst = (int)((sqrt(curr_mad/pMP->aver_mad)*2+curr_mad/pMP->aver_mad)/(3*0.1) + 0.4) - 10; 56429a84457aed4c45bc900998b5e11c03023264208James Dong else 56529a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTdst = (int)(curr_mad / (pMP->aver_mad + 0.0001) * 10 + 0.4) - 10; 56629a84457aed4c45bc900998b5e11c03023264208James Dong } 56729a84457aed4c45bc900998b5e11c03023264208James Dong else /* curr_mad <= average_mad*1.1 */ 56829a84457aed4c45bc900998b5e11c03023264208James 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); 56929a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTsrc = 10 - (int)(sqrt(curr_mad / (pMP->aver_mad + 0.0001)) * 10 + 0.5); 57029a84457aed4c45bc900998b5e11c03023264208James Dong 57129a84457aed4c45bc900998b5e11c03023264208James Dong /* actively fill in the possible gap */ 57229a84457aed4c45bc900998b5e11c03023264208James Dong if (diff_counter_BTsrc == 0 && diff_counter_BTdst == 0 && 57329a84457aed4c45bc900998b5e11c03023264208James Dong curr_mad <= pMP->aver_mad*1.1 && pMP->counter_BTsrc < pMP->counter_BTdst) 57429a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTsrc = 1; 57529a84457aed4c45bc900998b5e11c03023264208James Dong 57629a84457aed4c45bc900998b5e11c03023264208James Dong } 57729a84457aed4c45bc900998b5e11c03023264208James Dong else if (pMP->overlapped_win_size > 0) 57829a84457aed4c45bc900998b5e11c03023264208James Dong { 57929a84457aed4c45bc900998b5e11c03023264208James Dong /* transition time: use previous average mad "pMP->aver_mad_prev" instead of the current average mad "pMP->aver_mad" */ 58029a84457aed4c45bc900998b5e11c03023264208James Dong if (curr_mad > pMP->aver_mad_prev*1.1) 58129a84457aed4c45bc900998b5e11c03023264208James Dong { 58229a84457aed4c45bc900998b5e11c03023264208James Dong if (curr_mad / pMP->aver_mad_prev > 2) 58329a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTdst = (int)(sqrt(curr_mad / (pMP->aver_mad_prev + 0.0001)) * 10 + 0.4) - 10; 58429a84457aed4c45bc900998b5e11c03023264208James 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; 58529a84457aed4c45bc900998b5e11c03023264208James Dong else 58629a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTdst = (int)(curr_mad / (pMP->aver_mad_prev + 0.0001) * 10 + 0.4) - 10; 58729a84457aed4c45bc900998b5e11c03023264208James Dong } 58829a84457aed4c45bc900998b5e11c03023264208James Dong else /* curr_mad <= average_mad*1.1 */ 58929a84457aed4c45bc900998b5e11c03023264208James 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); 59029a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTsrc = 10 - (int)(sqrt(curr_mad / (pMP->aver_mad_prev + 0.0001)) * 10 + 0.5); 59129a84457aed4c45bc900998b5e11c03023264208James Dong 59229a84457aed4c45bc900998b5e11c03023264208James Dong /* actively fill in the possible gap */ 59329a84457aed4c45bc900998b5e11c03023264208James Dong if (diff_counter_BTsrc == 0 && diff_counter_BTdst == 0 && 59429a84457aed4c45bc900998b5e11c03023264208James Dong curr_mad <= pMP->aver_mad_prev*1.1 && pMP->counter_BTsrc < pMP->counter_BTdst) 59529a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTsrc = 1; 59629a84457aed4c45bc900998b5e11c03023264208James Dong 59729a84457aed4c45bc900998b5e11c03023264208James Dong if (--pMP->overlapped_win_size <= 0) pMP->overlapped_win_size = 0; 59829a84457aed4c45bc900998b5e11c03023264208James Dong } 59929a84457aed4c45bc900998b5e11c03023264208James Dong 60029a84457aed4c45bc900998b5e11c03023264208James Dong 60129a84457aed4c45bc900998b5e11c03023264208James Dong /* if difference is too much, do clipping */ 60229a84457aed4c45bc900998b5e11c03023264208James Dong /* First, set the upper bound for current bit allocation variance: 80% of available buffer */ 60329a84457aed4c45bc900998b5e11c03023264208James Dong bound = (int)((rateCtrl->Bs / 2 - rateCtrl->VBV_fullness) * 0.6 / (pMP->target_bits_per_frame / 10)); /* rateCtrl->Bs */ 60429a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTsrc = AVC_MIN(diff_counter_BTsrc, bound); 60529a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTdst = AVC_MIN(diff_counter_BTdst, bound); 60629a84457aed4c45bc900998b5e11c03023264208James Dong 60729a84457aed4c45bc900998b5e11c03023264208James Dong /* Second, set another upper bound for current bit allocation: 4-5*bitrate/framerate */ 60829a84457aed4c45bc900998b5e11c03023264208James Dong bound = 50; 60929a84457aed4c45bc900998b5e11c03023264208James Dong// if(video->encParams->RC_Type == CBR_LOWDELAY) 61029a84457aed4c45bc900998b5e11c03023264208James Dong// not necessary bound = 10; -- For Low delay */ 61129a84457aed4c45bc900998b5e11c03023264208James Dong 61229a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTsrc = AVC_MIN(diff_counter_BTsrc, bound); 61329a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTdst = AVC_MIN(diff_counter_BTdst, bound); 61429a84457aed4c45bc900998b5e11c03023264208James Dong 61529a84457aed4c45bc900998b5e11c03023264208James Dong 61629a84457aed4c45bc900998b5e11c03023264208James Dong /* Third, check the buffer */ 61729a84457aed4c45bc900998b5e11c03023264208James Dong prev_counter_diff = pMP->counter_BTdst - pMP->counter_BTsrc; 61829a84457aed4c45bc900998b5e11c03023264208James Dong curr_counter_diff = prev_counter_diff + (diff_counter_BTdst - diff_counter_BTsrc); 61929a84457aed4c45bc900998b5e11c03023264208James Dong 62029a84457aed4c45bc900998b5e11c03023264208James Dong if (AVC_ABS(prev_counter_diff) >= rateCtrl->max_BitVariance_num || AVC_ABS(curr_counter_diff) >= rateCtrl->max_BitVariance_num) 62129a84457aed4c45bc900998b5e11c03023264208James Dong { //diff_counter_BTsrc = diff_counter_BTdst = 0; 62229a84457aed4c45bc900998b5e11c03023264208James Dong 62329a84457aed4c45bc900998b5e11c03023264208James Dong if (curr_counter_diff > rateCtrl->max_BitVariance_num && diff_counter_BTdst) 62429a84457aed4c45bc900998b5e11c03023264208James Dong { 62529a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTdst = (rateCtrl->max_BitVariance_num - prev_counter_diff) + diff_counter_BTsrc; 62629a84457aed4c45bc900998b5e11c03023264208James Dong if (diff_counter_BTdst < 0) diff_counter_BTdst = 0; 62729a84457aed4c45bc900998b5e11c03023264208James Dong } 62829a84457aed4c45bc900998b5e11c03023264208James Dong 62929a84457aed4c45bc900998b5e11c03023264208James Dong else if (curr_counter_diff < -rateCtrl->max_BitVariance_num && diff_counter_BTsrc) 63029a84457aed4c45bc900998b5e11c03023264208James Dong { 63129a84457aed4c45bc900998b5e11c03023264208James Dong diff_counter_BTsrc = diff_counter_BTdst - (-rateCtrl->max_BitVariance_num - prev_counter_diff); 63229a84457aed4c45bc900998b5e11c03023264208James Dong if (diff_counter_BTsrc < 0) diff_counter_BTsrc = 0; 63329a84457aed4c45bc900998b5e11c03023264208James Dong } 63429a84457aed4c45bc900998b5e11c03023264208James Dong } 63529a84457aed4c45bc900998b5e11c03023264208James Dong 63629a84457aed4c45bc900998b5e11c03023264208James Dong 63729a84457aed4c45bc900998b5e11c03023264208James Dong /*3.diff_counter_BTsrc, diff_counter_BTdst ==> TMN_TH */ 63829a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_TH = (int)(pMP->target_bits_per_frame); 63929a84457aed4c45bc900998b5e11c03023264208James Dong pMP->diff_counter = 0; 64029a84457aed4c45bc900998b5e11c03023264208James Dong 64129a84457aed4c45bc900998b5e11c03023264208James Dong if (diff_counter_BTsrc) 64229a84457aed4c45bc900998b5e11c03023264208James Dong { 64329a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_TH -= (int)(pMP->target_bits_per_frame * diff_counter_BTsrc * 0.1); 64429a84457aed4c45bc900998b5e11c03023264208James Dong pMP->diff_counter = -diff_counter_BTsrc; 64529a84457aed4c45bc900998b5e11c03023264208James Dong } 64629a84457aed4c45bc900998b5e11c03023264208James Dong else if (diff_counter_BTdst) 64729a84457aed4c45bc900998b5e11c03023264208James Dong { 64829a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_TH += (int)(pMP->target_bits_per_frame * diff_counter_BTdst * 0.1); 64929a84457aed4c45bc900998b5e11c03023264208James Dong pMP->diff_counter = diff_counter_BTdst; 65029a84457aed4c45bc900998b5e11c03023264208James Dong } 65129a84457aed4c45bc900998b5e11c03023264208James Dong 65229a84457aed4c45bc900998b5e11c03023264208James Dong 65329a84457aed4c45bc900998b5e11c03023264208James Dong /*4.update pMP->counter_BTsrc, pMP->counter_BTdst */ 65429a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc += diff_counter_BTsrc; 65529a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTdst += diff_counter_BTdst; 65629a84457aed4c45bc900998b5e11c03023264208James Dong 65729a84457aed4c45bc900998b5e11c03023264208James Dong 65829a84457aed4c45bc900998b5e11c03023264208James Dong /*5.target bit calculation */ 65929a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->T = rateCtrl->TMN_TH - rateCtrl->TMN_W; 66029a84457aed4c45bc900998b5e11c03023264208James Dong 66129a84457aed4c45bc900998b5e11c03023264208James Dong return ; 66229a84457aed4c45bc900998b5e11c03023264208James Dong} 66329a84457aed4c45bc900998b5e11c03023264208James Dong 66429a84457aed4c45bc900998b5e11c03023264208James Dongvoid updateRC_PostProc(AVCRateControl *rateCtrl, MultiPass *pMP) 66529a84457aed4c45bc900998b5e11c03023264208James Dong{ 66629a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->skip_next_frame > 0) /* skip next frame */ 66729a84457aed4c45bc900998b5e11c03023264208James Dong { 66829a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc += 10 * rateCtrl->skip_next_frame; 66929a84457aed4c45bc900998b5e11c03023264208James Dong 67029a84457aed4c45bc900998b5e11c03023264208James Dong } 67129a84457aed4c45bc900998b5e11c03023264208James Dong else if (rateCtrl->skip_next_frame == -1) /* skip current frame */ 67229a84457aed4c45bc900998b5e11c03023264208James Dong { 67329a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTdst -= pMP->diff_counter; 67429a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc += 10; 67529a84457aed4c45bc900998b5e11c03023264208James Dong 67629a84457aed4c45bc900998b5e11c03023264208James Dong pMP->sum_mad -= pMP->mad; 67729a84457aed4c45bc900998b5e11c03023264208James Dong pMP->aver_mad = (pMP->aver_mad * pMP->encoded_frames - pMP->mad) / (pMP->encoded_frames - 1 + 0.0001); 67829a84457aed4c45bc900998b5e11c03023264208James Dong pMP->sum_QP -= pMP->QP; 67929a84457aed4c45bc900998b5e11c03023264208James Dong pMP->encoded_frames --; 68029a84457aed4c45bc900998b5e11c03023264208James Dong } 68129a84457aed4c45bc900998b5e11c03023264208James Dong /* some stuff in update VBV_fullness remains here */ 68229a84457aed4c45bc900998b5e11c03023264208James Dong //if(rateCtrl->VBV_fullness < -rateCtrl->Bs/2) /* rateCtrl->Bs */ 68329a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->VBV_fullness < rateCtrl->low_bound) 68429a84457aed4c45bc900998b5e11c03023264208James Dong { 68529a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->VBV_fullness = rateCtrl->low_bound; // -rateCtrl->Bs/2; 68629a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_W = rateCtrl->VBV_fullness - rateCtrl->low_bound; 68729a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc = pMP->counter_BTdst + (int)((OsclFloat)(rateCtrl->Bs / 2 - rateCtrl->low_bound) / 2.0 / (pMP->target_bits_per_frame / 10)); 68829a84457aed4c45bc900998b5e11c03023264208James Dong } 68929a84457aed4c45bc900998b5e11c03023264208James Dong} 69029a84457aed4c45bc900998b5e11c03023264208James Dong 69129a84457aed4c45bc900998b5e11c03023264208James Dong 69229a84457aed4c45bc900998b5e11c03023264208James Dongvoid RCInitChromaQP(AVCEncObject *encvid) 69329a84457aed4c45bc900998b5e11c03023264208James Dong{ 69429a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 69529a84457aed4c45bc900998b5e11c03023264208James Dong AVCMacroblock *currMB = video->currMB; 69629a84457aed4c45bc900998b5e11c03023264208James Dong int q_bits; 69729a84457aed4c45bc900998b5e11c03023264208James Dong 69829a84457aed4c45bc900998b5e11c03023264208James Dong /* we have to do the same thing for AVC_CLIP3(0,51,video->QSy) */ 69929a84457aed4c45bc900998b5e11c03023264208James Dong 70029a84457aed4c45bc900998b5e11c03023264208James Dong video->QPy_div_6 = (currMB->QPy * 43) >> 8; 70129a84457aed4c45bc900998b5e11c03023264208James Dong video->QPy_mod_6 = currMB->QPy - 6 * video->QPy_div_6; 70229a84457aed4c45bc900998b5e11c03023264208James Dong currMB->QPc = video->QPc = mapQPi2QPc[AVC_CLIP3(0, 51, currMB->QPy + video->currPicParams->chroma_qp_index_offset)]; 70329a84457aed4c45bc900998b5e11c03023264208James Dong video->QPc_div_6 = (video->QPc * 43) >> 8; 70429a84457aed4c45bc900998b5e11c03023264208James Dong video->QPc_mod_6 = video->QPc - 6 * video->QPc_div_6; 70529a84457aed4c45bc900998b5e11c03023264208James Dong 70629a84457aed4c45bc900998b5e11c03023264208James Dong /* pre-calculate this to save computation */ 70729a84457aed4c45bc900998b5e11c03023264208James Dong q_bits = 4 + video->QPy_div_6; 70829a84457aed4c45bc900998b5e11c03023264208James Dong if (video->slice_type == AVC_I_SLICE) 70929a84457aed4c45bc900998b5e11c03023264208James Dong { 71029a84457aed4c45bc900998b5e11c03023264208James Dong encvid->qp_const = 682 << q_bits; // intra 71129a84457aed4c45bc900998b5e11c03023264208James Dong } 71229a84457aed4c45bc900998b5e11c03023264208James Dong else 71329a84457aed4c45bc900998b5e11c03023264208James Dong { 71429a84457aed4c45bc900998b5e11c03023264208James Dong encvid->qp_const = 342 << q_bits; // inter 71529a84457aed4c45bc900998b5e11c03023264208James Dong } 71629a84457aed4c45bc900998b5e11c03023264208James Dong 71729a84457aed4c45bc900998b5e11c03023264208James Dong q_bits = 4 + video->QPc_div_6; 71829a84457aed4c45bc900998b5e11c03023264208James Dong if (video->slice_type == AVC_I_SLICE) 71929a84457aed4c45bc900998b5e11c03023264208James Dong { 72029a84457aed4c45bc900998b5e11c03023264208James Dong encvid->qp_const_c = 682 << q_bits; // intra 72129a84457aed4c45bc900998b5e11c03023264208James Dong } 72229a84457aed4c45bc900998b5e11c03023264208James Dong else 72329a84457aed4c45bc900998b5e11c03023264208James Dong { 72429a84457aed4c45bc900998b5e11c03023264208James Dong encvid->qp_const_c = 342 << q_bits; // inter 72529a84457aed4c45bc900998b5e11c03023264208James Dong } 72629a84457aed4c45bc900998b5e11c03023264208James Dong 72729a84457aed4c45bc900998b5e11c03023264208James Dong encvid->lambda_mode = QP2QUANT[AVC_MAX(0, currMB->QPy-SHIFT_QP)]; 72829a84457aed4c45bc900998b5e11c03023264208James Dong encvid->lambda_motion = LAMBDA_FACTOR(encvid->lambda_mode); 72929a84457aed4c45bc900998b5e11c03023264208James Dong 73029a84457aed4c45bc900998b5e11c03023264208James Dong return ; 73129a84457aed4c45bc900998b5e11c03023264208James Dong} 73229a84457aed4c45bc900998b5e11c03023264208James Dong 73329a84457aed4c45bc900998b5e11c03023264208James Dong 73429a84457aed4c45bc900998b5e11c03023264208James Dongvoid RCInitMBQP(AVCEncObject *encvid) 73529a84457aed4c45bc900998b5e11c03023264208James Dong{ 73629a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 73729a84457aed4c45bc900998b5e11c03023264208James Dong AVCMacroblock *currMB = video->currMB; 73829a84457aed4c45bc900998b5e11c03023264208James Dong 73929a84457aed4c45bc900998b5e11c03023264208James Dong currMB->QPy = video->QPy; /* set to previous value or picture level */ 74029a84457aed4c45bc900998b5e11c03023264208James Dong 74129a84457aed4c45bc900998b5e11c03023264208James Dong RCInitChromaQP(encvid); 74229a84457aed4c45bc900998b5e11c03023264208James Dong 74329a84457aed4c45bc900998b5e11c03023264208James Dong} 74429a84457aed4c45bc900998b5e11c03023264208James Dong 74529a84457aed4c45bc900998b5e11c03023264208James Dongvoid RCPostMB(AVCCommonObj *video, AVCRateControl *rateCtrl, int num_header_bits, int num_texture_bits) 74629a84457aed4c45bc900998b5e11c03023264208James Dong{ 74729a84457aed4c45bc900998b5e11c03023264208James Dong OSCL_UNUSED_ARG(video); 74829a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->numMBHeaderBits = num_header_bits; 74929a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->numMBTextureBits = num_texture_bits; 75029a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->NumberofHeaderBits += rateCtrl->numMBHeaderBits; 75129a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->NumberofTextureBits += rateCtrl->numMBTextureBits; 75229a84457aed4c45bc900998b5e11c03023264208James Dong} 75329a84457aed4c45bc900998b5e11c03023264208James Dong 75429a84457aed4c45bc900998b5e11c03023264208James Dongvoid RCRestoreQP(AVCMacroblock *currMB, AVCCommonObj *video, AVCEncObject *encvid) 75529a84457aed4c45bc900998b5e11c03023264208James Dong{ 75629a84457aed4c45bc900998b5e11c03023264208James Dong currMB->QPy = video->QPy; /* use previous QP */ 75729a84457aed4c45bc900998b5e11c03023264208James Dong RCInitChromaQP(encvid); 75829a84457aed4c45bc900998b5e11c03023264208James Dong 75929a84457aed4c45bc900998b5e11c03023264208James Dong return ; 76029a84457aed4c45bc900998b5e11c03023264208James Dong} 76129a84457aed4c45bc900998b5e11c03023264208James Dong 76229a84457aed4c45bc900998b5e11c03023264208James Dong 76329a84457aed4c45bc900998b5e11c03023264208James Dongvoid RCCalculateMAD(AVCEncObject *encvid, AVCMacroblock *currMB, uint8 *orgL, int orgPitch) 76429a84457aed4c45bc900998b5e11c03023264208James Dong{ 76529a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 76629a84457aed4c45bc900998b5e11c03023264208James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 76729a84457aed4c45bc900998b5e11c03023264208James Dong uint32 dmin_lx; 76829a84457aed4c45bc900998b5e11c03023264208James Dong 76929a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->rcEnable == TRUE) 77029a84457aed4c45bc900998b5e11c03023264208James Dong { 77129a84457aed4c45bc900998b5e11c03023264208James Dong if (currMB->mb_intra) 77229a84457aed4c45bc900998b5e11c03023264208James Dong { 77329a84457aed4c45bc900998b5e11c03023264208James Dong if (currMB->mbMode == AVC_I16) 77429a84457aed4c45bc900998b5e11c03023264208James Dong { 77529a84457aed4c45bc900998b5e11c03023264208James Dong dmin_lx = (0xFFFF << 16) | orgPitch; 77629a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->MADofMB[video->mbNum] = AVCSAD_Macroblock_C(orgL, 77729a84457aed4c45bc900998b5e11c03023264208James Dong encvid->pred_i16[currMB->i16Mode], dmin_lx, NULL); 77829a84457aed4c45bc900998b5e11c03023264208James Dong } 77929a84457aed4c45bc900998b5e11c03023264208James Dong else /* i4 */ 78029a84457aed4c45bc900998b5e11c03023264208James Dong { 78129a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->MADofMB[video->mbNum] = encvid->i4_sad / 256.; 78229a84457aed4c45bc900998b5e11c03023264208James Dong } 78329a84457aed4c45bc900998b5e11c03023264208James Dong } 78429a84457aed4c45bc900998b5e11c03023264208James Dong /* for INTER, we have already saved it with the MV search */ 78529a84457aed4c45bc900998b5e11c03023264208James Dong } 78629a84457aed4c45bc900998b5e11c03023264208James Dong 78729a84457aed4c45bc900998b5e11c03023264208James Dong return ; 78829a84457aed4c45bc900998b5e11c03023264208James Dong} 78929a84457aed4c45bc900998b5e11c03023264208James Dong 79029a84457aed4c45bc900998b5e11c03023264208James Dong 79129a84457aed4c45bc900998b5e11c03023264208James Dong 79229a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status RCUpdateFrame(AVCEncObject *encvid) 79329a84457aed4c45bc900998b5e11c03023264208James Dong{ 79429a84457aed4c45bc900998b5e11c03023264208James Dong AVCCommonObj *video = encvid->common; 79529a84457aed4c45bc900998b5e11c03023264208James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 79629a84457aed4c45bc900998b5e11c03023264208James Dong AVCEnc_Status status = AVCENC_SUCCESS; 79729a84457aed4c45bc900998b5e11c03023264208James Dong MultiPass *pMP = rateCtrl->pMP; 79829a84457aed4c45bc900998b5e11c03023264208James Dong int diff_BTCounter; 79929a84457aed4c45bc900998b5e11c03023264208James Dong int nal_type = video->nal_unit_type; 80029a84457aed4c45bc900998b5e11c03023264208James Dong 80129a84457aed4c45bc900998b5e11c03023264208James Dong /* update the complexity weight of I, P, B frame */ 80229a84457aed4c45bc900998b5e11c03023264208James Dong 80329a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->rcEnable == TRUE) 80429a84457aed4c45bc900998b5e11c03023264208James Dong { 80529a84457aed4c45bc900998b5e11c03023264208James Dong pMP->actual_bits = rateCtrl->numFrameBits; 80629a84457aed4c45bc900998b5e11c03023264208James Dong pMP->mad = (OsclFloat)rateCtrl->totalSAD / video->PicSizeInMbs; //ComputeFrameMAD(video, rateCtrl); 80729a84457aed4c45bc900998b5e11c03023264208James Dong 80829a84457aed4c45bc900998b5e11c03023264208James Dong AVCSaveRDSamples(pMP, 0); 80929a84457aed4c45bc900998b5e11c03023264208James Dong 81029a84457aed4c45bc900998b5e11c03023264208James Dong pMP->encoded_frames++; 81129a84457aed4c45bc900998b5e11c03023264208James Dong 81229a84457aed4c45bc900998b5e11c03023264208James Dong /* for pMP->samplesPerFrame */ 81329a84457aed4c45bc900998b5e11c03023264208James Dong pMP->samplesPerFrame[pMP->framePos] = 0; 81429a84457aed4c45bc900998b5e11c03023264208James Dong 81529a84457aed4c45bc900998b5e11c03023264208James Dong pMP->sum_QP += pMP->QP; 81629a84457aed4c45bc900998b5e11c03023264208James Dong 81729a84457aed4c45bc900998b5e11c03023264208James Dong /* update pMP->counter_BTsrc, pMP->counter_BTdst */ 81829a84457aed4c45bc900998b5e11c03023264208James Dong /* re-allocate the target bit again and then stop encoding */ 81929a84457aed4c45bc900998b5e11c03023264208James Dong diff_BTCounter = (int)((OsclFloat)(rateCtrl->TMN_TH - rateCtrl->TMN_W - pMP->actual_bits) / 82029a84457aed4c45bc900998b5e11c03023264208James Dong (pMP->bitrate / (pMP->framerate + 0.0001) + 0.0001) / 0.1); 82129a84457aed4c45bc900998b5e11c03023264208James Dong if (diff_BTCounter >= 0) 82229a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc += diff_BTCounter; /* pMP->actual_bits is smaller */ 82329a84457aed4c45bc900998b5e11c03023264208James Dong else 82429a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTdst -= diff_BTCounter; /* pMP->actual_bits is bigger */ 82529a84457aed4c45bc900998b5e11c03023264208James Dong 82629a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_TH -= (int)((OsclFloat)pMP->bitrate / (pMP->framerate + 0.0001) * (diff_BTCounter * 0.1)); 82729a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->T = pMP->target_bits = rateCtrl->TMN_TH - rateCtrl->TMN_W; 82829a84457aed4c45bc900998b5e11c03023264208James Dong pMP->diff_counter -= diff_BTCounter; 82929a84457aed4c45bc900998b5e11c03023264208James Dong 83029a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->Rc = rateCtrl->numFrameBits; /* Total Bits for current frame */ 83129a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->Hc = rateCtrl->NumberofHeaderBits; /* Total Bits in Header and Motion Vector */ 83229a84457aed4c45bc900998b5e11c03023264208James Dong 83329a84457aed4c45bc900998b5e11c03023264208James Dong /* BX_RC */ 83429a84457aed4c45bc900998b5e11c03023264208James Dong updateRateControl(rateCtrl, nal_type); 83529a84457aed4c45bc900998b5e11c03023264208James Dong if (rateCtrl->skip_next_frame == -1) // skip current frame 83629a84457aed4c45bc900998b5e11c03023264208James Dong { 83729a84457aed4c45bc900998b5e11c03023264208James Dong status = AVCENC_SKIPPED_PICTURE; 83829a84457aed4c45bc900998b5e11c03023264208James Dong } 83929a84457aed4c45bc900998b5e11c03023264208James Dong } 84029a84457aed4c45bc900998b5e11c03023264208James Dong 84129a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->first_frame = 0; // reset here after we encode the first frame. 84229a84457aed4c45bc900998b5e11c03023264208James Dong 84329a84457aed4c45bc900998b5e11c03023264208James Dong return status; 84429a84457aed4c45bc900998b5e11c03023264208James Dong} 84529a84457aed4c45bc900998b5e11c03023264208James Dong 84629a84457aed4c45bc900998b5e11c03023264208James Dongvoid AVCSaveRDSamples(MultiPass *pMP, int counter_samples) 84729a84457aed4c45bc900998b5e11c03023264208James Dong{ 84829a84457aed4c45bc900998b5e11c03023264208James Dong /* for pMP->pRDSamples */ 84929a84457aed4c45bc900998b5e11c03023264208James Dong pMP->pRDSamples[pMP->framePos][counter_samples].QP = pMP->QP; 85029a84457aed4c45bc900998b5e11c03023264208James Dong pMP->pRDSamples[pMP->framePos][counter_samples].actual_bits = pMP->actual_bits; 85129a84457aed4c45bc900998b5e11c03023264208James Dong pMP->pRDSamples[pMP->framePos][counter_samples].mad = pMP->mad; 85229a84457aed4c45bc900998b5e11c03023264208James Dong pMP->pRDSamples[pMP->framePos][counter_samples].R_D = (OsclFloat)pMP->actual_bits / (pMP->mad + 0.0001); 85329a84457aed4c45bc900998b5e11c03023264208James Dong 85429a84457aed4c45bc900998b5e11c03023264208James Dong return ; 85529a84457aed4c45bc900998b5e11c03023264208James Dong} 85629a84457aed4c45bc900998b5e11c03023264208James Dong 85729a84457aed4c45bc900998b5e11c03023264208James Dongvoid updateRateControl(AVCRateControl *rateCtrl, int nal_type) 85829a84457aed4c45bc900998b5e11c03023264208James Dong{ 85929a84457aed4c45bc900998b5e11c03023264208James Dong int frame_bits; 86029a84457aed4c45bc900998b5e11c03023264208James Dong MultiPass *pMP = rateCtrl->pMP; 86129a84457aed4c45bc900998b5e11c03023264208James Dong 86229a84457aed4c45bc900998b5e11c03023264208James Dong /* BX rate contro\l */ 86329a84457aed4c45bc900998b5e11c03023264208James Dong frame_bits = (int)(rateCtrl->bitRate / rateCtrl->frame_rate); 86429a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_W += (rateCtrl->Rc - rateCtrl->TMN_TH); 86529a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->VBV_fullness += (rateCtrl->Rc - frame_bits); //rateCtrl->Rp); 86629a84457aed4c45bc900998b5e11c03023264208James Dong //if(rateCtrl->VBV_fullness < 0) rateCtrl->VBV_fullness = -1; 86729a84457aed4c45bc900998b5e11c03023264208James Dong 86829a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->encoded_frames++; 86929a84457aed4c45bc900998b5e11c03023264208James Dong 87029a84457aed4c45bc900998b5e11c03023264208James Dong /* frame dropping */ 87129a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->skip_next_frame = 0; 87229a84457aed4c45bc900998b5e11c03023264208James Dong 87329a84457aed4c45bc900998b5e11c03023264208James Dong if ((rateCtrl->VBV_fullness > rateCtrl->Bs / 2) && nal_type != AVC_NALTYPE_IDR) /* skip the current frame */ /* rateCtrl->Bs */ 87429a84457aed4c45bc900998b5e11c03023264208James Dong { 87529a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->TMN_W -= (rateCtrl->Rc - rateCtrl->TMN_TH); 87629a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->VBV_fullness -= rateCtrl->Rc; 87729a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->skip_next_frame = -1; 87829a84457aed4c45bc900998b5e11c03023264208James Dong } 87929a84457aed4c45bc900998b5e11c03023264208James Dong else if ((OsclFloat)(rateCtrl->VBV_fullness - rateCtrl->VBV_fullness_offset) > (rateCtrl->Bs / 2 - rateCtrl->VBV_fullness_offset)*0.95) /* skip next frame */ 88029a84457aed4c45bc900998b5e11c03023264208James Dong { 88129a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->VBV_fullness -= frame_bits; //rateCtrl->Rp; 88229a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->skip_next_frame = 1; 88329a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc -= (int)((OsclFloat)(rateCtrl->Bs / 2 - rateCtrl->low_bound) / 2.0 / (pMP->target_bits_per_frame / 10)); 88429a84457aed4c45bc900998b5e11c03023264208James Dong /* BX_1, skip more than 1 frames */ 88529a84457aed4c45bc900998b5e11c03023264208James Dong //while(rateCtrl->VBV_fullness > rateCtrl->Bs*0.475) 88629a84457aed4c45bc900998b5e11c03023264208James Dong while ((rateCtrl->VBV_fullness - rateCtrl->VBV_fullness_offset) > (rateCtrl->Bs / 2 - rateCtrl->VBV_fullness_offset)*0.95) 88729a84457aed4c45bc900998b5e11c03023264208James Dong { 88829a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->VBV_fullness -= frame_bits; //rateCtrl->Rp; 88929a84457aed4c45bc900998b5e11c03023264208James Dong rateCtrl->skip_next_frame++; 89029a84457aed4c45bc900998b5e11c03023264208James Dong pMP->counter_BTsrc -= (int)((OsclFloat)(rateCtrl->Bs / 2 - rateCtrl->low_bound) / 2.0 / (pMP->target_bits_per_frame / 10)); 89129a84457aed4c45bc900998b5e11c03023264208James Dong } 89229a84457aed4c45bc900998b5e11c03023264208James Dong 89329a84457aed4c45bc900998b5e11c03023264208James Dong /* END BX_1 */ 89429a84457aed4c45bc900998b5e11c03023264208James Dong } 89529a84457aed4c45bc900998b5e11c03023264208James Dong} 89629a84457aed4c45bc900998b5e11c03023264208James Dong 89729a84457aed4c45bc900998b5e11c03023264208James Dong 89829a84457aed4c45bc900998b5e11c03023264208James Dongdouble ComputeFrameMAD(AVCCommonObj *video, AVCRateControl *rateCtrl) 89929a84457aed4c45bc900998b5e11c03023264208James Dong{ 90029a84457aed4c45bc900998b5e11c03023264208James Dong double TotalMAD; 90129a84457aed4c45bc900998b5e11c03023264208James Dong int i; 90229a84457aed4c45bc900998b5e11c03023264208James Dong TotalMAD = 0.0; 90329a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 0; i < (int)video->PicSizeInMbs; i++) 90429a84457aed4c45bc900998b5e11c03023264208James Dong TotalMAD += rateCtrl->MADofMB[i]; 90529a84457aed4c45bc900998b5e11c03023264208James Dong TotalMAD /= video->PicSizeInMbs; 90629a84457aed4c45bc900998b5e11c03023264208James Dong return TotalMAD; 90729a84457aed4c45bc900998b5e11c03023264208James Dong} 90829a84457aed4c45bc900998b5e11c03023264208James Dong 90929a84457aed4c45bc900998b5e11c03023264208James Dong 91029a84457aed4c45bc900998b5e11c03023264208James Dong 91129a84457aed4c45bc900998b5e11c03023264208James Dong 91229a84457aed4c45bc900998b5e11c03023264208James Dong 91329a84457aed4c45bc900998b5e11c03023264208James Dong/* convert from QP to Qstep */ 91429a84457aed4c45bc900998b5e11c03023264208James Dongdouble QP2Qstep(int QP) 91529a84457aed4c45bc900998b5e11c03023264208James Dong{ 91629a84457aed4c45bc900998b5e11c03023264208James Dong int i; 91729a84457aed4c45bc900998b5e11c03023264208James Dong double Qstep; 91829a84457aed4c45bc900998b5e11c03023264208James Dong static const double QP2QSTEP[6] = { 0.625, 0.6875, 0.8125, 0.875, 1.0, 1.125 }; 91929a84457aed4c45bc900998b5e11c03023264208James Dong 92029a84457aed4c45bc900998b5e11c03023264208James Dong Qstep = QP2QSTEP[QP % 6]; 92129a84457aed4c45bc900998b5e11c03023264208James Dong for (i = 0; i < (QP / 6); i++) 92229a84457aed4c45bc900998b5e11c03023264208James Dong Qstep *= 2; 92329a84457aed4c45bc900998b5e11c03023264208James Dong 92429a84457aed4c45bc900998b5e11c03023264208James Dong return Qstep; 92529a84457aed4c45bc900998b5e11c03023264208James Dong} 92629a84457aed4c45bc900998b5e11c03023264208James Dong 92729a84457aed4c45bc900998b5e11c03023264208James Dong/* convert from step size to QP */ 92829a84457aed4c45bc900998b5e11c03023264208James Dongint Qstep2QP(double Qstep) 92929a84457aed4c45bc900998b5e11c03023264208James Dong{ 93029a84457aed4c45bc900998b5e11c03023264208James Dong int q_per = 0, q_rem = 0; 93129a84457aed4c45bc900998b5e11c03023264208James Dong 93229a84457aed4c45bc900998b5e11c03023264208James Dong // assert( Qstep >= QP2Qstep(0) && Qstep <= QP2Qstep(51) ); 93329a84457aed4c45bc900998b5e11c03023264208James Dong if (Qstep < QP2Qstep(0)) 93429a84457aed4c45bc900998b5e11c03023264208James Dong return 0; 93529a84457aed4c45bc900998b5e11c03023264208James Dong else if (Qstep > QP2Qstep(51)) 93629a84457aed4c45bc900998b5e11c03023264208James Dong return 51; 93729a84457aed4c45bc900998b5e11c03023264208James Dong 93829a84457aed4c45bc900998b5e11c03023264208James Dong while (Qstep > QP2Qstep(5)) 93929a84457aed4c45bc900998b5e11c03023264208James Dong { 94029a84457aed4c45bc900998b5e11c03023264208James Dong Qstep /= 2; 94129a84457aed4c45bc900998b5e11c03023264208James Dong q_per += 1; 94229a84457aed4c45bc900998b5e11c03023264208James Dong } 94329a84457aed4c45bc900998b5e11c03023264208James Dong 94429a84457aed4c45bc900998b5e11c03023264208James Dong if (Qstep <= (0.625 + 0.6875) / 2) 94529a84457aed4c45bc900998b5e11c03023264208James Dong { 94629a84457aed4c45bc900998b5e11c03023264208James Dong Qstep = 0.625; 94729a84457aed4c45bc900998b5e11c03023264208James Dong q_rem = 0; 94829a84457aed4c45bc900998b5e11c03023264208James Dong } 94929a84457aed4c45bc900998b5e11c03023264208James Dong else if (Qstep <= (0.6875 + 0.8125) / 2) 95029a84457aed4c45bc900998b5e11c03023264208James Dong { 95129a84457aed4c45bc900998b5e11c03023264208James Dong Qstep = 0.6875; 95229a84457aed4c45bc900998b5e11c03023264208James Dong q_rem = 1; 95329a84457aed4c45bc900998b5e11c03023264208James Dong } 95429a84457aed4c45bc900998b5e11c03023264208James Dong else if (Qstep <= (0.8125 + 0.875) / 2) 95529a84457aed4c45bc900998b5e11c03023264208James Dong { 95629a84457aed4c45bc900998b5e11c03023264208James Dong Qstep = 0.8125; 95729a84457aed4c45bc900998b5e11c03023264208James Dong q_rem = 2; 95829a84457aed4c45bc900998b5e11c03023264208James Dong } 95929a84457aed4c45bc900998b5e11c03023264208James Dong else if (Qstep <= (0.875 + 1.0) / 2) 96029a84457aed4c45bc900998b5e11c03023264208James Dong { 96129a84457aed4c45bc900998b5e11c03023264208James Dong Qstep = 0.875; 96229a84457aed4c45bc900998b5e11c03023264208James Dong q_rem = 3; 96329a84457aed4c45bc900998b5e11c03023264208James Dong } 96429a84457aed4c45bc900998b5e11c03023264208James Dong else if (Qstep <= (1.0 + 1.125) / 2) 96529a84457aed4c45bc900998b5e11c03023264208James Dong { 96629a84457aed4c45bc900998b5e11c03023264208James Dong Qstep = 1.0; 96729a84457aed4c45bc900998b5e11c03023264208James Dong q_rem = 4; 96829a84457aed4c45bc900998b5e11c03023264208James Dong } 96929a84457aed4c45bc900998b5e11c03023264208James Dong else 97029a84457aed4c45bc900998b5e11c03023264208James Dong { 97129a84457aed4c45bc900998b5e11c03023264208James Dong Qstep = 1.125; 97229a84457aed4c45bc900998b5e11c03023264208James Dong q_rem = 5; 97329a84457aed4c45bc900998b5e11c03023264208James Dong } 97429a84457aed4c45bc900998b5e11c03023264208James Dong 97529a84457aed4c45bc900998b5e11c03023264208James Dong return (q_per * 6 + q_rem); 97629a84457aed4c45bc900998b5e11c03023264208James Dong} 97729a84457aed4c45bc900998b5e11c03023264208James Dong 97829a84457aed4c45bc900998b5e11c03023264208James Dong 97929a84457aed4c45bc900998b5e11c03023264208James Dong 980