11cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* ------------------------------------------------------------------ 21cc31e629e8132df390ae692873c847d1c2f62c0James Dong * Copyright (C) 1998-2009 PacketVideo 31cc31e629e8132df390ae692873c847d1c2f62c0James Dong * 41cc31e629e8132df390ae692873c847d1c2f62c0James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 51cc31e629e8132df390ae692873c847d1c2f62c0James Dong * you may not use this file except in compliance with the License. 61cc31e629e8132df390ae692873c847d1c2f62c0James Dong * You may obtain a copy of the License at 71cc31e629e8132df390ae692873c847d1c2f62c0James Dong * 81cc31e629e8132df390ae692873c847d1c2f62c0James Dong * http://www.apache.org/licenses/LICENSE-2.0 91cc31e629e8132df390ae692873c847d1c2f62c0James Dong * 101cc31e629e8132df390ae692873c847d1c2f62c0James Dong * Unless required by applicable law or agreed to in writing, software 111cc31e629e8132df390ae692873c847d1c2f62c0James Dong * distributed under the License is distributed on an "AS IS" BASIS, 121cc31e629e8132df390ae692873c847d1c2f62c0James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 131cc31e629e8132df390ae692873c847d1c2f62c0James Dong * express or implied. 141cc31e629e8132df390ae692873c847d1c2f62c0James Dong * See the License for the specific language governing permissions 151cc31e629e8132df390ae692873c847d1c2f62c0James Dong * and limitations under the License. 161cc31e629e8132df390ae692873c847d1c2f62c0James Dong * ------------------------------------------------------------------- 171cc31e629e8132df390ae692873c847d1c2f62c0James Dong */ 181cc31e629e8132df390ae692873c847d1c2f62c0James Dong#include "avcenc_lib.h" 191cc31e629e8132df390ae692873c847d1c2f62c0James Dong#include <math.h> 201cc31e629e8132df390ae692873c847d1c2f62c0James Dong 211cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* rate control variables */ 221cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define RC_MAX_QUANT 51 231cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define RC_MIN_QUANT 0 //cap to 10 to prevent rate fluctuation 241cc31e629e8132df390ae692873c847d1c2f62c0James Dong 251cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define MAD_MIN 1 /* handle the case of devision by zero in RC */ 261cc31e629e8132df390ae692873c847d1c2f62c0James Dong 271cc31e629e8132df390ae692873c847d1c2f62c0James Dong 281cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* local functions */ 291cc31e629e8132df390ae692873c847d1c2f62c0James Dongdouble QP2Qstep(int QP); 301cc31e629e8132df390ae692873c847d1c2f62c0James Dongint Qstep2QP(double Qstep); 311cc31e629e8132df390ae692873c847d1c2f62c0James Dong 321cc31e629e8132df390ae692873c847d1c2f62c0James Dongdouble ComputeFrameMAD(AVCCommonObj *video, AVCRateControl *rateCtrl); 331cc31e629e8132df390ae692873c847d1c2f62c0James Dong 341cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid targetBitCalculation(AVCEncObject *encvid, AVCCommonObj *video, AVCRateControl *rateCtrl, MultiPass *pMP); 351cc31e629e8132df390ae692873c847d1c2f62c0James Dong 361cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid calculateQuantizer_Multipass(AVCEncObject *encvid, AVCCommonObj *video, 371cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRateControl *rateCtrl, MultiPass *pMP); 381cc31e629e8132df390ae692873c847d1c2f62c0James Dong 391cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid updateRC_PostProc(AVCRateControl *rateCtrl, MultiPass *pMP); 401cc31e629e8132df390ae692873c847d1c2f62c0James Dong 411cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid AVCSaveRDSamples(MultiPass *pMP, int counter_samples); 421cc31e629e8132df390ae692873c847d1c2f62c0James Dong 431cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid updateRateControl(AVCRateControl *rateControl, int nal_type); 441cc31e629e8132df390ae692873c847d1c2f62c0James Dong 451cc31e629e8132df390ae692873c847d1c2f62c0James Dongint GetAvgFrameQP(AVCRateControl *rateCtrl) 461cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 471cc31e629e8132df390ae692873c847d1c2f62c0James Dong return rateCtrl->Qc; 481cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 491cc31e629e8132df390ae692873c847d1c2f62c0James Dong 501cc31e629e8132df390ae692873c847d1c2f62c0James DongAVCEnc_Status RCDetermineFrameNum(AVCEncObject *encvid, AVCRateControl *rateCtrl, uint32 modTime, uint *frameNum) 511cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 521cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 531cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCSliceHeader *sliceHdr = video->sliceHdr; 541cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint32 modTimeRef = encvid->modTimeRef; 551cc31e629e8132df390ae692873c847d1c2f62c0James Dong int32 currFrameNum ; 561cc31e629e8132df390ae692873c847d1c2f62c0James Dong int frameInc; 571cc31e629e8132df390ae692873c847d1c2f62c0James Dong 581cc31e629e8132df390ae692873c847d1c2f62c0James Dong 591cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* check with the buffer fullness to make sure that we have enough bits to encode this frame */ 601cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* we can use a threshold to guarantee minimum picture quality */ 611cc31e629e8132df390ae692873c847d1c2f62c0James Dong /**********************************/ 621cc31e629e8132df390ae692873c847d1c2f62c0James Dong 631cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* for now, the default is to encode every frame, To Be Changed */ 641cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->first_frame) 651cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 661cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->modTimeRef = modTime; 671cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->wrapModTime = 0; 681cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->prevFrameNum = 0; 691cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->prevProcFrameNum = 0; 701cc31e629e8132df390ae692873c847d1c2f62c0James Dong 711cc31e629e8132df390ae692873c847d1c2f62c0James Dong *frameNum = 0; 721cc31e629e8132df390ae692873c847d1c2f62c0James Dong 731cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* set frame type to IDR-frame */ 741cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->nal_unit_type = AVC_NALTYPE_IDR; 751cc31e629e8132df390ae692873c847d1c2f62c0James Dong sliceHdr->slice_type = AVC_I_ALL_SLICE; 761cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->slice_type = AVC_I_SLICE; 771cc31e629e8132df390ae692873c847d1c2f62c0James Dong 781cc31e629e8132df390ae692873c847d1c2f62c0James Dong return AVCENC_SUCCESS; 791cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 801cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 811cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 821cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (modTime < modTimeRef) /* modTime wrapped around */ 831cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 841cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->wrapModTime += ((uint32)0xFFFFFFFF - modTimeRef) + 1; 851cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->modTimeRef = modTimeRef = 0; 861cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 871cc31e629e8132df390ae692873c847d1c2f62c0James Dong modTime += encvid->wrapModTime; /* wrapModTime is non zero after wrap-around */ 881cc31e629e8132df390ae692873c847d1c2f62c0James Dong 891cc31e629e8132df390ae692873c847d1c2f62c0James Dong currFrameNum = (int32)(((modTime - modTimeRef) * rateCtrl->frame_rate + 200) / 1000); /* add small roundings */ 901cc31e629e8132df390ae692873c847d1c2f62c0James Dong 911cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (currFrameNum <= (int32)encvid->prevProcFrameNum) 921cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 931cc31e629e8132df390ae692873c847d1c2f62c0James Dong return AVCENC_FAIL; /* this is a late frame do not encode it */ 941cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 951cc31e629e8132df390ae692873c847d1c2f62c0James Dong 961cc31e629e8132df390ae692873c847d1c2f62c0James Dong frameInc = currFrameNum - encvid->prevProcFrameNum; 971cc31e629e8132df390ae692873c847d1c2f62c0James Dong 981cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (frameInc < rateCtrl->skip_next_frame + 1) 991cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1001cc31e629e8132df390ae692873c847d1c2f62c0James Dong return AVCENC_FAIL; /* frame skip required to maintain the target bit rate. */ 1011cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1021cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1031cc31e629e8132df390ae692873c847d1c2f62c0James Dong RCUpdateBuffer(video, rateCtrl, frameInc - rateCtrl->skip_next_frame); /* in case more frames dropped */ 1041cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1051cc31e629e8132df390ae692873c847d1c2f62c0James Dong *frameNum = currFrameNum; 1061cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1071cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* This part would be similar to DetermineVopType of m4venc */ 1081cc31e629e8132df390ae692873c847d1c2f62c0James Dong if ((*frameNum >= (uint)rateCtrl->idrPeriod && rateCtrl->idrPeriod > 0) || (*frameNum > video->MaxFrameNum)) /* first frame or IDR*/ 1091cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1101cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* set frame type to IDR-frame */ 1111cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->idrPeriod) 1121cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1131cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->modTimeRef += (uint32)(rateCtrl->idrPeriod * 1000 / rateCtrl->frame_rate); 1141cc31e629e8132df390ae692873c847d1c2f62c0James Dong *frameNum -= rateCtrl->idrPeriod; 1151cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1161cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 1171cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1181cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->modTimeRef += (uint32)(video->MaxFrameNum * 1000 / rateCtrl->frame_rate); 1191cc31e629e8132df390ae692873c847d1c2f62c0James Dong *frameNum -= video->MaxFrameNum; 1201cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1221cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->nal_unit_type = AVC_NALTYPE_IDR; 1231cc31e629e8132df390ae692873c847d1c2f62c0James Dong sliceHdr->slice_type = AVC_I_ALL_SLICE; 1241cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->slice_type = AVC_I_SLICE; 1251cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->prevProcFrameNum = *frameNum; 1261cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1271cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 1281cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1291cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->nal_unit_type = AVC_NALTYPE_SLICE; 1301cc31e629e8132df390ae692873c847d1c2f62c0James Dong sliceHdr->slice_type = AVC_P_ALL_SLICE; 1311cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->slice_type = AVC_P_SLICE; 1321cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->prevProcFrameNum = currFrameNum; 1331cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1341cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1351cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1361cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1371cc31e629e8132df390ae692873c847d1c2f62c0James Dong return AVCENC_SUCCESS; 1381cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 1391cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1401cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid RCUpdateBuffer(AVCCommonObj *video, AVCRateControl *rateCtrl, int frameInc) 1411cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 1421cc31e629e8132df390ae692873c847d1c2f62c0James Dong int tmp; 1431cc31e629e8132df390ae692873c847d1c2f62c0James Dong MultiPass *pMP = rateCtrl->pMP; 1441cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1451cc31e629e8132df390ae692873c847d1c2f62c0James Dong OSCL_UNUSED_ARG(video); 1461cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1471cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->rcEnable == TRUE) 1481cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1491cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (frameInc > 1) 1501cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1511cc31e629e8132df390ae692873c847d1c2f62c0James Dong tmp = rateCtrl->bitsPerFrame * (frameInc - 1); 1521cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->VBV_fullness -= tmp; 1531cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc += 10 * (frameInc - 1); 1541cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1551cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* Check buffer underflow */ 1561cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->VBV_fullness < rateCtrl->low_bound) 1571cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1581cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->VBV_fullness = rateCtrl->low_bound; // -rateCtrl->Bs/2; 1591cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_W = rateCtrl->VBV_fullness - rateCtrl->low_bound; 1601cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc = pMP->counter_BTdst + (int)((OsclFloat)(rateCtrl->Bs / 2 - rateCtrl->low_bound) / 2.0 / (pMP->target_bits_per_frame / 10)); 1611cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1621cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1631cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1641cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 1651cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1661cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1671cc31e629e8132df390ae692873c847d1c2f62c0James DongAVCEnc_Status InitRateControlModule(AVCHandle *avcHandle) 1681cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 1691cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject; 1701cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 1711cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 1721cc31e629e8132df390ae692873c847d1c2f62c0James Dong double L1, L2, L3, bpp; 1731cc31e629e8132df390ae692873c847d1c2f62c0James Dong int qp; 1741cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i, j; 1751cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1761cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->basicUnit = video->PicSizeInMbs; 1771cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1781cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->MADofMB = (double*) avcHandle->CBAVC_Malloc(encvid->avcHandle->userData, 1791cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->PicSizeInMbs * sizeof(double), DEFAULT_ATTR); 1801cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1811cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (!rateCtrl->MADofMB) 1821cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1831cc31e629e8132df390ae692873c847d1c2f62c0James Dong goto CLEANUP_RC; 1841cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1851cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1861cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->rcEnable == TRUE) 1871cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1881cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP = (MultiPass*) avcHandle->CBAVC_Malloc(encvid->avcHandle->userData, sizeof(MultiPass), DEFAULT_ATTR); 1891cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (!rateCtrl->pMP) 1901cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1911cc31e629e8132df390ae692873c847d1c2f62c0James Dong goto CLEANUP_RC; 1921cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1931cc31e629e8132df390ae692873c847d1c2f62c0James Dong memset(rateCtrl->pMP, 0, sizeof(MultiPass)); 1941cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->encoded_frames = -1; /* forget about the very first I frame */ 1951cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1961cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* RDInfo **pRDSamples */ 1971cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->pRDSamples = (RDInfo **)avcHandle->CBAVC_Malloc(encvid->avcHandle->userData, (30 * sizeof(RDInfo *)), DEFAULT_ATTR); 1981cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (!rateCtrl->pMP->pRDSamples) 1991cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2001cc31e629e8132df390ae692873c847d1c2f62c0James Dong goto CLEANUP_RC; 2011cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2021cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2031cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 30; i++) 2041cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2051cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->pRDSamples[i] = (RDInfo *)avcHandle->CBAVC_Malloc(encvid->avcHandle->userData, (32 * sizeof(RDInfo)), DEFAULT_ATTR); 2061cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (!rateCtrl->pMP->pRDSamples[i]) 2071cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2081cc31e629e8132df390ae692873c847d1c2f62c0James Dong goto CLEANUP_RC; 2091cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2101cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (j = 0; j < 32; j++) memset(&(rateCtrl->pMP->pRDSamples[i][j]), 0, sizeof(RDInfo)); 2111cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2121cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->frameRange = (int)(rateCtrl->frame_rate * 1.0); /* 1.0s time frame*/ 2131cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->frameRange = AVC_MAX(rateCtrl->pMP->frameRange, 5); 2141cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->frameRange = AVC_MIN(rateCtrl->pMP->frameRange, 30); 2151cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2161cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->framePos = -1; 2171cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2181cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2191cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->bitsPerFrame = (int32)(rateCtrl->bitRate / rateCtrl->frame_rate); 2201cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2211cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* BX rate control */ 2221cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->skip_next_frame = 0; /* must be initialized */ 2231cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2241cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->Bs = rateCtrl->cpbSize; 2251cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_W = 0; 2261cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->VBV_fullness = (int)(rateCtrl->Bs * 0.5); /* rateCtrl->Bs */ 2271cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->encoded_frames = 0; 2281cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2291cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_TH = rateCtrl->bitsPerFrame; 2301cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2311cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->max_BitVariance_num = (int)((OsclFloat)(rateCtrl->Bs - rateCtrl->VBV_fullness) / (rateCtrl->bitsPerFrame / 10.0)) - 5; 2321cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->max_BitVariance_num < 0) rateCtrl->max_BitVariance_num += 5; 2331cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2341cc31e629e8132df390ae692873c847d1c2f62c0James Dong // Set the initial buffer fullness 2351cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* According to the spec, the initial buffer fullness needs to be set to 1/3 */ 2361cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->VBV_fullness = (int)(rateCtrl->Bs / 3.0 - rateCtrl->Bs / 2.0); /* the buffer range is [-Bs/2, Bs/2] */ 2371cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->counter_BTsrc = (int)((rateCtrl->Bs / 2.0 - rateCtrl->Bs / 3.0) / (rateCtrl->bitsPerFrame / 10.0)); 2381cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_W = (int)(rateCtrl->VBV_fullness + rateCtrl->pMP->counter_BTsrc * (rateCtrl->bitsPerFrame / 10.0)); 2391cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2401cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->low_bound = -rateCtrl->Bs / 2; 2411cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->VBV_fullness_offset = 0; 2421cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2431cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* Setting the bitrate and framerate */ 2441cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->bitrate = rateCtrl->bitRate; 2451cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->framerate = rateCtrl->frame_rate; 2461cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->pMP->target_bits_per_frame = rateCtrl->pMP->bitrate / rateCtrl->pMP->framerate; 2471cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2481cc31e629e8132df390ae692873c847d1c2f62c0James Dong /*compute the initial QP*/ 2491cc31e629e8132df390ae692873c847d1c2f62c0James Dong bpp = 1.0 * rateCtrl->bitRate / (rateCtrl->frame_rate * (video->PicSizeInMbs << 8)); 2501cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (video->PicWidthInSamplesL == 176) 2511cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2521cc31e629e8132df390ae692873c847d1c2f62c0James Dong L1 = 0.1; 2531cc31e629e8132df390ae692873c847d1c2f62c0James Dong L2 = 0.3; 2541cc31e629e8132df390ae692873c847d1c2f62c0James Dong L3 = 0.6; 2551cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2561cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (video->PicWidthInSamplesL == 352) 2571cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2581cc31e629e8132df390ae692873c847d1c2f62c0James Dong L1 = 0.2; 2591cc31e629e8132df390ae692873c847d1c2f62c0James Dong L2 = 0.6; 2601cc31e629e8132df390ae692873c847d1c2f62c0James Dong L3 = 1.2; 2611cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2621cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 2631cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2641cc31e629e8132df390ae692873c847d1c2f62c0James Dong L1 = 0.6; 2651cc31e629e8132df390ae692873c847d1c2f62c0James Dong L2 = 1.4; 2661cc31e629e8132df390ae692873c847d1c2f62c0James Dong L3 = 2.4; 2671cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2681cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2691cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->initQP == 0) 2701cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2711cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (bpp <= L1) 2721cc31e629e8132df390ae692873c847d1c2f62c0James Dong qp = 35; 2731cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (bpp <= L2) 2741cc31e629e8132df390ae692873c847d1c2f62c0James Dong qp = 25; 2751cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (bpp <= L3) 2761cc31e629e8132df390ae692873c847d1c2f62c0James Dong qp = 20; 2771cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 2781cc31e629e8132df390ae692873c847d1c2f62c0James Dong qp = 15; 2791cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->initQP = qp; 2801cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2811cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2821cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->Qc = rateCtrl->initQP; 2831cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2841cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2851cc31e629e8132df390ae692873c847d1c2f62c0James Dong return AVCENC_SUCCESS; 2861cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2871cc31e629e8132df390ae692873c847d1c2f62c0James DongCLEANUP_RC: 2881cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2891cc31e629e8132df390ae692873c847d1c2f62c0James Dong CleanupRateControlModule(avcHandle); 2901cc31e629e8132df390ae692873c847d1c2f62c0James Dong return AVCENC_MEMORY_FAIL; 2911cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2921cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 2931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2941cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2951cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid CleanupRateControlModule(AVCHandle *avcHandle) 2961cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 2971cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject; 2981cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 2991cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i; 3001cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3011cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->MADofMB) 3021cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3031cc31e629e8132df390ae692873c847d1c2f62c0James Dong avcHandle->CBAVC_Free(avcHandle->userData, (int)(rateCtrl->MADofMB)); 3041cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3051cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3061cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->pMP) 3071cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3081cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->pMP->pRDSamples) 3091cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3101cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 30; i++) 3111cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3121cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->pMP->pRDSamples[i]) 3131cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3141cc31e629e8132df390ae692873c847d1c2f62c0James Dong avcHandle->CBAVC_Free(avcHandle->userData, (int)rateCtrl->pMP->pRDSamples[i]); 3151cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3161cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3171cc31e629e8132df390ae692873c847d1c2f62c0James Dong avcHandle->CBAVC_Free(avcHandle->userData, (int)rateCtrl->pMP->pRDSamples); 3181cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3191cc31e629e8132df390ae692873c847d1c2f62c0James Dong avcHandle->CBAVC_Free(avcHandle->userData, (int)(rateCtrl->pMP)); 3201cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3221cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 3231cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 3241cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3251cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid RCInitGOP(AVCEncObject *encvid) 3261cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 3271cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* in BX RC, there's no GOP-level RC */ 3281cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3291cc31e629e8132df390ae692873c847d1c2f62c0James Dong OSCL_UNUSED_ARG(encvid); 3301cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3311cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 3321cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 3331cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3341cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3351cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid RCInitFrameQP(AVCEncObject *encvid) 3361cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 3371cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 3381cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 3391cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCPicParamSet *picParam = video->currPicParams; 3401cc31e629e8132df390ae692873c847d1c2f62c0James Dong MultiPass *pMP = rateCtrl->pMP; 3411cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3421cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->rcEnable == TRUE) 3431cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3441cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* frame layer rate control */ 3451cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->encoded_frames == 0) 3461cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3471cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->QPy = rateCtrl->Qc = rateCtrl->initQP; 3481cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3491cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 3501cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3511cc31e629e8132df390ae692873c847d1c2f62c0James Dong calculateQuantizer_Multipass(encvid, video, rateCtrl, pMP); 3521cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->QPy = rateCtrl->Qc; 3531cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3541cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3551cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->NumberofHeaderBits = 0; 3561cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->NumberofTextureBits = 0; 3571cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->numFrameBits = 0; // reset 3581cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3591cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* update pMP->framePos */ 3601cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (++pMP->framePos == pMP->frameRange) pMP->framePos = 0; 3611cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3621cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->T == 0) 3631cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3641cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTdst = (int)(rateCtrl->frame_rate * 7.5 + 0.5); /* 0.75s time frame */ 3651cc31e629e8132df390ae692873c847d1c2f62c0James 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 */ 3661cc31e629e8132df390ae692873c847d1c2f62c0James 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 */ 3671cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTdst = AVC_MIN(pMP->counter_BTdst, 20); /* Limit the target to be smaller than 3C */ 3681cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3691cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->target_bits = rateCtrl->T = rateCtrl->TMN_TH = (int)(rateCtrl->TMN_TH * (1.0 + pMP->counter_BTdst * 0.1)); 3701cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->diff_counter = pMP->counter_BTdst; 3711cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3721cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3731cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* collect the necessary data: target bits, actual bits, mad and QP */ 3741cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->target_bits = rateCtrl->T; 3751cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->QP = video->QPy; 3761cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3771cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->mad = (OsclFloat)rateCtrl->totalSAD / video->PicSizeInMbs; //ComputeFrameMAD(video, rateCtrl); 3781cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (pMP->mad < MAD_MIN) pMP->mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ 3791cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3801cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->bitrate = rateCtrl->bitRate; /* calculated in RCVopQPSetting */ 3811cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->framerate = rateCtrl->frame_rate; 3821cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3831cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* first pass encoding */ 3841cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->nRe_Quantized = 0; 3851cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3861cc31e629e8132df390ae692873c847d1c2f62c0James Dong } // rcEnable 3871cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 3881cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3891cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->QPy = rateCtrl->initQP; 3901cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3911cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3921cc31e629e8132df390ae692873c847d1c2f62c0James Dong// printf(" %d ",video->QPy); 3931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3941cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (video->CurrPicNum == 0 && encvid->outOfBandParamSet == FALSE) 3951cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3961cc31e629e8132df390ae692873c847d1c2f62c0James Dong picParam->pic_init_qs_minus26 = 0; 3971cc31e629e8132df390ae692873c847d1c2f62c0James Dong picParam->pic_init_qp_minus26 = video->QPy - 26; 3981cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3991cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4001cc31e629e8132df390ae692873c847d1c2f62c0James Dong // need this for motion estimation 4011cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->lambda_mode = QP2QUANT[AVC_MAX(0, video->QPy-SHIFT_QP)]; 4021cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->lambda_motion = LAMBDA_FACTOR(encvid->lambda_mode); 4031cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 4041cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 4051cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4061cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* Mad based variable bit allocation + QP calculation with a new quadratic method */ 4071cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid calculateQuantizer_Multipass(AVCEncObject *encvid, AVCCommonObj *video, 4081cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRateControl *rateCtrl, MultiPass *pMP) 4091cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 4101cc31e629e8132df390ae692873c847d1c2f62c0James Dong int prev_actual_bits = 0, curr_target, /*pos=0,*/i, j; 4111cc31e629e8132df390ae692873c847d1c2f62c0James Dong OsclFloat Qstep, prev_QP = 0.625; 4121cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4131cc31e629e8132df390ae692873c847d1c2f62c0James Dong OsclFloat curr_mad, prev_mad, curr_RD, prev_RD, average_mad, aver_QP; 4141cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4151cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* Mad based variable bit allocation */ 4161cc31e629e8132df390ae692873c847d1c2f62c0James Dong targetBitCalculation(encvid, video, rateCtrl, pMP); 4171cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4181cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->T <= 0 || rateCtrl->totalSAD == 0) 4191cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4201cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->T < 0) rateCtrl->Qc = RC_MAX_QUANT; 4211cc31e629e8132df390ae692873c847d1c2f62c0James Dong return; 4221cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4231cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4241cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* ---------------------------------------------------------------------------------------------------*/ 4251cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* current frame QP estimation */ 4261cc31e629e8132df390ae692873c847d1c2f62c0James Dong curr_target = rateCtrl->T; 4271cc31e629e8132df390ae692873c847d1c2f62c0James Dong curr_mad = (OsclFloat)rateCtrl->totalSAD / video->PicSizeInMbs; 4281cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (curr_mad < MAD_MIN) curr_mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ 4291cc31e629e8132df390ae692873c847d1c2f62c0James Dong curr_RD = (OsclFloat)curr_target / curr_mad; 4301cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4311cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->skip_next_frame == -1) // previous was skipped 4321cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4331cc31e629e8132df390ae692873c847d1c2f62c0James Dong i = pMP->framePos; 4341cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_mad = pMP->pRDSamples[i][0].mad; 4351cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_QP = pMP->pRDSamples[i][0].QP; 4361cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_actual_bits = pMP->pRDSamples[i][0].actual_bits; 4371cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4381cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 4391cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4401cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* Another version of search the optimal point */ 4411cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_mad = 0.0; 4421cc31e629e8132df390ae692873c847d1c2f62c0James Dong i = 0; 4431cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (i < pMP->frameRange && prev_mad < 0.001) /* find first one with nonzero prev_mad */ 4441cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4451cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_mad = pMP->pRDSamples[i][0].mad; 4461cc31e629e8132df390ae692873c847d1c2f62c0James Dong i++; 4471cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4481cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4491cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (i < pMP->frameRange) 4501cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4511cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_actual_bits = pMP->pRDSamples[i-1][0].actual_bits; 4521cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4531cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (j = 0; i < pMP->frameRange; i++) 4541cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4551cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (pMP->pRDSamples[i][0].mad != 0 && 4561cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVC_ABS(prev_mad - curr_mad) > AVC_ABS(pMP->pRDSamples[i][0].mad - curr_mad)) 4571cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4581cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_mad = pMP->pRDSamples[i][0].mad; 4591cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_actual_bits = pMP->pRDSamples[i][0].actual_bits; 4601cc31e629e8132df390ae692873c847d1c2f62c0James Dong j = i; 4611cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4621cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4631cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_QP = QP2Qstep(pMP->pRDSamples[j][0].QP); 4641cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4651cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 1; i < pMP->samplesPerFrame[j]; i++) 4661cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4671cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (AVC_ABS(prev_actual_bits - curr_target) > AVC_ABS(pMP->pRDSamples[j][i].actual_bits - curr_target)) 4681cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4691cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_actual_bits = pMP->pRDSamples[j][i].actual_bits; 4701cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_QP = QP2Qstep(pMP->pRDSamples[j][i].QP); 4711cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4721cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4731cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4741cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4751cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4761cc31e629e8132df390ae692873c847d1c2f62c0James Dong // quadratic approximation 4771cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (prev_mad > 0.001) // only when prev_mad is greater than 0, otherwise keep using the same QP 4781cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4791cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_RD = (OsclFloat)prev_actual_bits / prev_mad; 4801cc31e629e8132df390ae692873c847d1c2f62c0James Dong //rateCtrl->Qc = (Int)(prev_QP * sqrt(prev_actual_bits/curr_target) + 0.4); 4811cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (prev_QP == 0.625) // added this to allow getting out of QP = 0 easily 4821cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4831cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep = (int)(prev_RD / curr_RD + 0.5); 4841cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4851cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 4861cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4871cc31e629e8132df390ae692873c847d1c2f62c0James Dong // rateCtrl->Qc =(Int)(prev_QP * M4VENC_SQRT(prev_RD/curr_RD) + 0.9); 4881cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4891cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (prev_RD / curr_RD > 0.5 && prev_RD / curr_RD < 2.0) 4901cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep = (int)(prev_QP * (sqrt(prev_RD / curr_RD) + prev_RD / curr_RD) / 2.0 + 0.9); /* Quadratic and linear approximation */ 4911cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 4921cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep = (int)(prev_QP * (sqrt(prev_RD / curr_RD) + pow(prev_RD / curr_RD, 1.0 / 3.0)) / 2.0 + 0.9); 4931cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4941cc31e629e8132df390ae692873c847d1c2f62c0James Dong // lower bound on Qc should be a function of curr_mad 4951cc31e629e8132df390ae692873c847d1c2f62c0James Dong // When mad is already low, lower bound on Qc doesn't have to be small. 4961cc31e629e8132df390ae692873c847d1c2f62c0James Dong // Note, this doesn't work well for low complexity clip encoded at high bit rate 4971cc31e629e8132df390ae692873c847d1c2f62c0James Dong // it doesn't hit the target bit rate due to this QP lower bound. 4981cc31e629e8132df390ae692873c847d1c2f62c0James Dong /// if((curr_mad < 8) && (rateCtrl->Qc < 12)) rateCtrl->Qc = 12; 4991cc31e629e8132df390ae692873c847d1c2f62c0James Dong // else if((curr_mad < 128) && (rateCtrl->Qc < 3)) rateCtrl->Qc = 3; 5001cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5011cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->Qc = Qstep2QP(Qstep); 5021cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5031cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->Qc < RC_MIN_QUANT) rateCtrl->Qc = RC_MIN_QUANT; 5041cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->Qc > RC_MAX_QUANT) rateCtrl->Qc = RC_MAX_QUANT; 5051cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5061cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5071cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* active bit resource protection */ 5081cc31e629e8132df390ae692873c847d1c2f62c0James Dong aver_QP = (pMP->encoded_frames == 0 ? 0 : pMP->sum_QP / (OsclFloat)pMP->encoded_frames); 5091cc31e629e8132df390ae692873c847d1c2f62c0James Dong average_mad = (pMP->encoded_frames == 0 ? 0 : pMP->sum_mad / (OsclFloat)pMP->encoded_frames); /* this function is called from the scond encoded frame*/ 5101cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (pMP->diff_counter == 0 && 5111cc31e629e8132df390ae692873c847d1c2f62c0James Dong ((OsclFloat)rateCtrl->Qc <= aver_QP*1.1 || curr_mad <= average_mad*1.1) && 5121cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc <= (pMP->counter_BTdst + (int)(pMP->framerate*1.0 + 0.5))) 5131cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5141cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_TH -= (int)(pMP->target_bits_per_frame / 10.0); 5151cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->T = rateCtrl->TMN_TH - rateCtrl->TMN_W; 5161cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc++; 5171cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->diff_counter--; 5181cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5191cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5201cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 5211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5221cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid targetBitCalculation(AVCEncObject *encvid, AVCCommonObj *video, AVCRateControl *rateCtrl, MultiPass *pMP) 5231cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 5241cc31e629e8132df390ae692873c847d1c2f62c0James Dong OSCL_UNUSED_ARG(encvid); 5251cc31e629e8132df390ae692873c847d1c2f62c0James Dong OsclFloat curr_mad;//, average_mad; 5261cc31e629e8132df390ae692873c847d1c2f62c0James Dong int diff_counter_BTsrc, diff_counter_BTdst, prev_counter_diff, curr_counter_diff, bound; 5271cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* BT = Bit Transfer, for pMP->counter_BTsrc, pMP->counter_BTdst */ 5281cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5291cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* some stuff about frame dropping remained here to be done because pMP cannot be inserted into updateRateControl()*/ 5301cc31e629e8132df390ae692873c847d1c2f62c0James Dong updateRC_PostProc(rateCtrl, pMP); 5311cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5321cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* update pMP->counter_BTsrc and pMP->counter_BTdst to avoid interger overflow */ 5331cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (pMP->counter_BTsrc > 1000 && pMP->counter_BTdst > 1000) 5341cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5351cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc -= 1000; 5361cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTdst -= 1000; 5371cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5381cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5391cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* ---------------------------------------------------------------------------------------------------*/ 5401cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* target calculation */ 5411cc31e629e8132df390ae692873c847d1c2f62c0James Dong curr_mad = (OsclFloat)rateCtrl->totalSAD / video->PicSizeInMbs; 5421cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (curr_mad < MAD_MIN) curr_mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ 5431cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTsrc = diff_counter_BTdst = 0; 5441cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->diff_counter = 0; 5451cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5461cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5471cc31e629e8132df390ae692873c847d1c2f62c0James Dong /*1.calculate average mad */ 5481cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->sum_mad += curr_mad; 5491cc31e629e8132df390ae692873c847d1c2f62c0James 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*/ 5501cc31e629e8132df390ae692873c847d1c2f62c0James Dong //pMP->aver_mad = average_mad; 5511cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (pMP->encoded_frames >= 0) /* pMP->encoded_frames is set to -1 initially, so forget about the very first I frame */ 5521cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->aver_mad = (pMP->aver_mad * pMP->encoded_frames + curr_mad) / (pMP->encoded_frames + 1); 5531cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5541cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (pMP->overlapped_win_size > 0 && pMP->encoded_frames_prev >= 0) 5551cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->aver_mad_prev = (pMP->aver_mad_prev * pMP->encoded_frames_prev + curr_mad) / (pMP->encoded_frames_prev + 1); 5561cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5571cc31e629e8132df390ae692873c847d1c2f62c0James Dong /*2.average_mad, mad ==> diff_counter_BTsrc, diff_counter_BTdst */ 5581cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (pMP->overlapped_win_size == 0) 5591cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5601cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* original verison */ 5611cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (curr_mad > pMP->aver_mad*1.1) 5621cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5631cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (curr_mad / (pMP->aver_mad + 0.0001) > 2) 5641cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTdst = (int)(sqrt(curr_mad / (pMP->aver_mad + 0.0001)) * 10 + 0.4) - 10; 5651cc31e629e8132df390ae692873c847d1c2f62c0James Dong //diff_counter_BTdst = (int)((sqrt(curr_mad/pMP->aver_mad)*2+curr_mad/pMP->aver_mad)/(3*0.1) + 0.4) - 10; 5661cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 5671cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTdst = (int)(curr_mad / (pMP->aver_mad + 0.0001) * 10 + 0.4) - 10; 5681cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5691cc31e629e8132df390ae692873c847d1c2f62c0James Dong else /* curr_mad <= average_mad*1.1 */ 5701cc31e629e8132df390ae692873c847d1c2f62c0James 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); 5711cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTsrc = 10 - (int)(sqrt(curr_mad / (pMP->aver_mad + 0.0001)) * 10 + 0.5); 5721cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5731cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* actively fill in the possible gap */ 5741cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (diff_counter_BTsrc == 0 && diff_counter_BTdst == 0 && 5751cc31e629e8132df390ae692873c847d1c2f62c0James Dong curr_mad <= pMP->aver_mad*1.1 && pMP->counter_BTsrc < pMP->counter_BTdst) 5761cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTsrc = 1; 5771cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5781cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5791cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (pMP->overlapped_win_size > 0) 5801cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5811cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* transition time: use previous average mad "pMP->aver_mad_prev" instead of the current average mad "pMP->aver_mad" */ 5821cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (curr_mad > pMP->aver_mad_prev*1.1) 5831cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5841cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (curr_mad / pMP->aver_mad_prev > 2) 5851cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTdst = (int)(sqrt(curr_mad / (pMP->aver_mad_prev + 0.0001)) * 10 + 0.4) - 10; 5861cc31e629e8132df390ae692873c847d1c2f62c0James 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; 5871cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 5881cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTdst = (int)(curr_mad / (pMP->aver_mad_prev + 0.0001) * 10 + 0.4) - 10; 5891cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5901cc31e629e8132df390ae692873c847d1c2f62c0James Dong else /* curr_mad <= average_mad*1.1 */ 5911cc31e629e8132df390ae692873c847d1c2f62c0James 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); 5921cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTsrc = 10 - (int)(sqrt(curr_mad / (pMP->aver_mad_prev + 0.0001)) * 10 + 0.5); 5931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5941cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* actively fill in the possible gap */ 5951cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (diff_counter_BTsrc == 0 && diff_counter_BTdst == 0 && 5961cc31e629e8132df390ae692873c847d1c2f62c0James Dong curr_mad <= pMP->aver_mad_prev*1.1 && pMP->counter_BTsrc < pMP->counter_BTdst) 5971cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTsrc = 1; 5981cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5991cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (--pMP->overlapped_win_size <= 0) pMP->overlapped_win_size = 0; 6001cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6011cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6021cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6031cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* if difference is too much, do clipping */ 6041cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* First, set the upper bound for current bit allocation variance: 80% of available buffer */ 6051cc31e629e8132df390ae692873c847d1c2f62c0James Dong bound = (int)((rateCtrl->Bs / 2 - rateCtrl->VBV_fullness) * 0.6 / (pMP->target_bits_per_frame / 10)); /* rateCtrl->Bs */ 6061cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTsrc = AVC_MIN(diff_counter_BTsrc, bound); 6071cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTdst = AVC_MIN(diff_counter_BTdst, bound); 6081cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6091cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* Second, set another upper bound for current bit allocation: 4-5*bitrate/framerate */ 6101cc31e629e8132df390ae692873c847d1c2f62c0James Dong bound = 50; 6111cc31e629e8132df390ae692873c847d1c2f62c0James Dong// if(video->encParams->RC_Type == CBR_LOWDELAY) 6121cc31e629e8132df390ae692873c847d1c2f62c0James Dong// not necessary bound = 10; -- For Low delay */ 6131cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6141cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTsrc = AVC_MIN(diff_counter_BTsrc, bound); 6151cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTdst = AVC_MIN(diff_counter_BTdst, bound); 6161cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6171cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6181cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* Third, check the buffer */ 6191cc31e629e8132df390ae692873c847d1c2f62c0James Dong prev_counter_diff = pMP->counter_BTdst - pMP->counter_BTsrc; 6201cc31e629e8132df390ae692873c847d1c2f62c0James Dong curr_counter_diff = prev_counter_diff + (diff_counter_BTdst - diff_counter_BTsrc); 6211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6221cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (AVC_ABS(prev_counter_diff) >= rateCtrl->max_BitVariance_num || AVC_ABS(curr_counter_diff) >= rateCtrl->max_BitVariance_num) 6231cc31e629e8132df390ae692873c847d1c2f62c0James Dong { //diff_counter_BTsrc = diff_counter_BTdst = 0; 6241cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6251cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (curr_counter_diff > rateCtrl->max_BitVariance_num && diff_counter_BTdst) 6261cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6271cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTdst = (rateCtrl->max_BitVariance_num - prev_counter_diff) + diff_counter_BTsrc; 6281cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (diff_counter_BTdst < 0) diff_counter_BTdst = 0; 6291cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6301cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6311cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (curr_counter_diff < -rateCtrl->max_BitVariance_num && diff_counter_BTsrc) 6321cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6331cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_counter_BTsrc = diff_counter_BTdst - (-rateCtrl->max_BitVariance_num - prev_counter_diff); 6341cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (diff_counter_BTsrc < 0) diff_counter_BTsrc = 0; 6351cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6361cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6371cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6381cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6391cc31e629e8132df390ae692873c847d1c2f62c0James Dong /*3.diff_counter_BTsrc, diff_counter_BTdst ==> TMN_TH */ 6401cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_TH = (int)(pMP->target_bits_per_frame); 6411cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->diff_counter = 0; 6421cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6431cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (diff_counter_BTsrc) 6441cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6451cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_TH -= (int)(pMP->target_bits_per_frame * diff_counter_BTsrc * 0.1); 6461cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->diff_counter = -diff_counter_BTsrc; 6471cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6481cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (diff_counter_BTdst) 6491cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6501cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_TH += (int)(pMP->target_bits_per_frame * diff_counter_BTdst * 0.1); 6511cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->diff_counter = diff_counter_BTdst; 6521cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6531cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6541cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6551cc31e629e8132df390ae692873c847d1c2f62c0James Dong /*4.update pMP->counter_BTsrc, pMP->counter_BTdst */ 6561cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc += diff_counter_BTsrc; 6571cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTdst += diff_counter_BTdst; 6581cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6591cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6601cc31e629e8132df390ae692873c847d1c2f62c0James Dong /*5.target bit calculation */ 6611cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->T = rateCtrl->TMN_TH - rateCtrl->TMN_W; 6621cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6631cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 6641cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 6651cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6661cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid updateRC_PostProc(AVCRateControl *rateCtrl, MultiPass *pMP) 6671cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 6681cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->skip_next_frame > 0) /* skip next frame */ 6691cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6701cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc += 10 * rateCtrl->skip_next_frame; 6711cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6721cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6731cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (rateCtrl->skip_next_frame == -1) /* skip current frame */ 6741cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6751cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTdst -= pMP->diff_counter; 6761cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc += 10; 6771cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6781cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->sum_mad -= pMP->mad; 6791cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->aver_mad = (pMP->aver_mad * pMP->encoded_frames - pMP->mad) / (pMP->encoded_frames - 1 + 0.0001); 6801cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->sum_QP -= pMP->QP; 6811cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->encoded_frames --; 6821cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6831cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* some stuff in update VBV_fullness remains here */ 6841cc31e629e8132df390ae692873c847d1c2f62c0James Dong //if(rateCtrl->VBV_fullness < -rateCtrl->Bs/2) /* rateCtrl->Bs */ 6851cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->VBV_fullness < rateCtrl->low_bound) 6861cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6871cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->VBV_fullness = rateCtrl->low_bound; // -rateCtrl->Bs/2; 6881cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_W = rateCtrl->VBV_fullness - rateCtrl->low_bound; 6891cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc = pMP->counter_BTdst + (int)((OsclFloat)(rateCtrl->Bs / 2 - rateCtrl->low_bound) / 2.0 / (pMP->target_bits_per_frame / 10)); 6901cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6911cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 6921cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6941cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid RCInitChromaQP(AVCEncObject *encvid) 6951cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 6961cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 6971cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMacroblock *currMB = video->currMB; 6981cc31e629e8132df390ae692873c847d1c2f62c0James Dong int q_bits; 6991cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7001cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* we have to do the same thing for AVC_CLIP3(0,51,video->QSy) */ 7011cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7021cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->QPy_div_6 = (currMB->QPy * 43) >> 8; 7031cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->QPy_mod_6 = currMB->QPy - 6 * video->QPy_div_6; 7041cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->QPc = video->QPc = mapQPi2QPc[AVC_CLIP3(0, 51, currMB->QPy + video->currPicParams->chroma_qp_index_offset)]; 7051cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->QPc_div_6 = (video->QPc * 43) >> 8; 7061cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->QPc_mod_6 = video->QPc - 6 * video->QPc_div_6; 7071cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7081cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* pre-calculate this to save computation */ 7091cc31e629e8132df390ae692873c847d1c2f62c0James Dong q_bits = 4 + video->QPy_div_6; 7101cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (video->slice_type == AVC_I_SLICE) 7111cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7121cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->qp_const = 682 << q_bits; // intra 7131cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7141cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 7151cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7161cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->qp_const = 342 << q_bits; // inter 7171cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7181cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7191cc31e629e8132df390ae692873c847d1c2f62c0James Dong q_bits = 4 + video->QPc_div_6; 7201cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (video->slice_type == AVC_I_SLICE) 7211cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7221cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->qp_const_c = 682 << q_bits; // intra 7231cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7241cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 7251cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7261cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->qp_const_c = 342 << q_bits; // inter 7271cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7281cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7291cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->lambda_mode = QP2QUANT[AVC_MAX(0, currMB->QPy-SHIFT_QP)]; 7301cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->lambda_motion = LAMBDA_FACTOR(encvid->lambda_mode); 7311cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7321cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 7331cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 7341cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7351cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7361cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid RCInitMBQP(AVCEncObject *encvid) 7371cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 7381cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 7391cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMacroblock *currMB = video->currMB; 7401cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7411cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->QPy = video->QPy; /* set to previous value or picture level */ 7421cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7431cc31e629e8132df390ae692873c847d1c2f62c0James Dong RCInitChromaQP(encvid); 7441cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7451cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 7461cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7471cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid RCPostMB(AVCCommonObj *video, AVCRateControl *rateCtrl, int num_header_bits, int num_texture_bits) 7481cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 7491cc31e629e8132df390ae692873c847d1c2f62c0James Dong OSCL_UNUSED_ARG(video); 7501cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->numMBHeaderBits = num_header_bits; 7511cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->numMBTextureBits = num_texture_bits; 7521cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->NumberofHeaderBits += rateCtrl->numMBHeaderBits; 7531cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->NumberofTextureBits += rateCtrl->numMBTextureBits; 7541cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 7551cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7561cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid RCRestoreQP(AVCMacroblock *currMB, AVCCommonObj *video, AVCEncObject *encvid) 7571cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 7581cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->QPy = video->QPy; /* use previous QP */ 7591cc31e629e8132df390ae692873c847d1c2f62c0James Dong RCInitChromaQP(encvid); 7601cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7611cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 7621cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 7631cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7641cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7651cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid RCCalculateMAD(AVCEncObject *encvid, AVCMacroblock *currMB, uint8 *orgL, int orgPitch) 7661cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 7671cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 7681cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 7691cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint32 dmin_lx; 7701cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7711cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->rcEnable == TRUE) 7721cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7731cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (currMB->mb_intra) 7741cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7751cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (currMB->mbMode == AVC_I16) 7761cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7771cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin_lx = (0xFFFF << 16) | orgPitch; 7781cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->MADofMB[video->mbNum] = AVCSAD_Macroblock_C(orgL, 7791cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->pred_i16[currMB->i16Mode], dmin_lx, NULL); 7801cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7811cc31e629e8132df390ae692873c847d1c2f62c0James Dong else /* i4 */ 7821cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7831cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->MADofMB[video->mbNum] = encvid->i4_sad / 256.; 7841cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7851cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7861cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* for INTER, we have already saved it with the MV search */ 7871cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7881cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7891cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 7901cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 7911cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7921cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7941cc31e629e8132df390ae692873c847d1c2f62c0James DongAVCEnc_Status RCUpdateFrame(AVCEncObject *encvid) 7951cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 7961cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 7971cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 7981cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCEnc_Status status = AVCENC_SUCCESS; 7991cc31e629e8132df390ae692873c847d1c2f62c0James Dong MultiPass *pMP = rateCtrl->pMP; 8001cc31e629e8132df390ae692873c847d1c2f62c0James Dong int diff_BTCounter; 8011cc31e629e8132df390ae692873c847d1c2f62c0James Dong int nal_type = video->nal_unit_type; 8021cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8031cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* update the complexity weight of I, P, B frame */ 8041cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8051cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->rcEnable == TRUE) 8061cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8071cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->actual_bits = rateCtrl->numFrameBits; 8081cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->mad = (OsclFloat)rateCtrl->totalSAD / video->PicSizeInMbs; //ComputeFrameMAD(video, rateCtrl); 8091cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8101cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCSaveRDSamples(pMP, 0); 8111cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8121cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->encoded_frames++; 8131cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8141cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* for pMP->samplesPerFrame */ 8151cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->samplesPerFrame[pMP->framePos] = 0; 8161cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8171cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->sum_QP += pMP->QP; 8181cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8191cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* update pMP->counter_BTsrc, pMP->counter_BTdst */ 8201cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* re-allocate the target bit again and then stop encoding */ 8211cc31e629e8132df390ae692873c847d1c2f62c0James Dong diff_BTCounter = (int)((OsclFloat)(rateCtrl->TMN_TH - rateCtrl->TMN_W - pMP->actual_bits) / 8221cc31e629e8132df390ae692873c847d1c2f62c0James Dong (pMP->bitrate / (pMP->framerate + 0.0001) + 0.0001) / 0.1); 8231cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (diff_BTCounter >= 0) 8241cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc += diff_BTCounter; /* pMP->actual_bits is smaller */ 8251cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 8261cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTdst -= diff_BTCounter; /* pMP->actual_bits is bigger */ 8271cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8281cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_TH -= (int)((OsclFloat)pMP->bitrate / (pMP->framerate + 0.0001) * (diff_BTCounter * 0.1)); 8291cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->T = pMP->target_bits = rateCtrl->TMN_TH - rateCtrl->TMN_W; 8301cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->diff_counter -= diff_BTCounter; 8311cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8321cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->Rc = rateCtrl->numFrameBits; /* Total Bits for current frame */ 8331cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->Hc = rateCtrl->NumberofHeaderBits; /* Total Bits in Header and Motion Vector */ 8341cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8351cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* BX_RC */ 8361cc31e629e8132df390ae692873c847d1c2f62c0James Dong updateRateControl(rateCtrl, nal_type); 8371cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->skip_next_frame == -1) // skip current frame 8381cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8391cc31e629e8132df390ae692873c847d1c2f62c0James Dong status = AVCENC_SKIPPED_PICTURE; 8401cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8411cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8421cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8431cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->first_frame = 0; // reset here after we encode the first frame. 8441cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8451cc31e629e8132df390ae692873c847d1c2f62c0James Dong return status; 8461cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 8471cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8481cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid AVCSaveRDSamples(MultiPass *pMP, int counter_samples) 8491cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 8501cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* for pMP->pRDSamples */ 8511cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->pRDSamples[pMP->framePos][counter_samples].QP = pMP->QP; 8521cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->pRDSamples[pMP->framePos][counter_samples].actual_bits = pMP->actual_bits; 8531cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->pRDSamples[pMP->framePos][counter_samples].mad = pMP->mad; 8541cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->pRDSamples[pMP->framePos][counter_samples].R_D = (OsclFloat)pMP->actual_bits / (pMP->mad + 0.0001); 8551cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8561cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 8571cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 8581cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8591cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid updateRateControl(AVCRateControl *rateCtrl, int nal_type) 8601cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 8611cc31e629e8132df390ae692873c847d1c2f62c0James Dong int frame_bits; 8621cc31e629e8132df390ae692873c847d1c2f62c0James Dong MultiPass *pMP = rateCtrl->pMP; 8631cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8641cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* BX rate contro\l */ 8651cc31e629e8132df390ae692873c847d1c2f62c0James Dong frame_bits = (int)(rateCtrl->bitRate / rateCtrl->frame_rate); 8661cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_W += (rateCtrl->Rc - rateCtrl->TMN_TH); 8671cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->VBV_fullness += (rateCtrl->Rc - frame_bits); //rateCtrl->Rp); 8681cc31e629e8132df390ae692873c847d1c2f62c0James Dong //if(rateCtrl->VBV_fullness < 0) rateCtrl->VBV_fullness = -1; 8691cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8701cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->encoded_frames++; 8711cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8721cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* frame dropping */ 8731cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->skip_next_frame = 0; 8741cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8751cc31e629e8132df390ae692873c847d1c2f62c0James Dong if ((rateCtrl->VBV_fullness > rateCtrl->Bs / 2) && nal_type != AVC_NALTYPE_IDR) /* skip the current frame */ /* rateCtrl->Bs */ 8761cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8771cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->TMN_W -= (rateCtrl->Rc - rateCtrl->TMN_TH); 8781cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->VBV_fullness -= rateCtrl->Rc; 8791cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->skip_next_frame = -1; 8801cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8811cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if ((OsclFloat)(rateCtrl->VBV_fullness - rateCtrl->VBV_fullness_offset) > (rateCtrl->Bs / 2 - rateCtrl->VBV_fullness_offset)*0.95) /* skip next frame */ 8821cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8831cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->VBV_fullness -= frame_bits; //rateCtrl->Rp; 8841cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->skip_next_frame = 1; 8851cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc -= (int)((OsclFloat)(rateCtrl->Bs / 2 - rateCtrl->low_bound) / 2.0 / (pMP->target_bits_per_frame / 10)); 8861cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* BX_1, skip more than 1 frames */ 8871cc31e629e8132df390ae692873c847d1c2f62c0James Dong //while(rateCtrl->VBV_fullness > rateCtrl->Bs*0.475) 8881cc31e629e8132df390ae692873c847d1c2f62c0James Dong while ((rateCtrl->VBV_fullness - rateCtrl->VBV_fullness_offset) > (rateCtrl->Bs / 2 - rateCtrl->VBV_fullness_offset)*0.95) 8891cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8901cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->VBV_fullness -= frame_bits; //rateCtrl->Rp; 8911cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->skip_next_frame++; 8921cc31e629e8132df390ae692873c847d1c2f62c0James Dong pMP->counter_BTsrc -= (int)((OsclFloat)(rateCtrl->Bs / 2 - rateCtrl->low_bound) / 2.0 / (pMP->target_bits_per_frame / 10)); 8931cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8941cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8951cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* END BX_1 */ 8961cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8971cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 8981cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8991cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9001cc31e629e8132df390ae692873c847d1c2f62c0James Dongdouble ComputeFrameMAD(AVCCommonObj *video, AVCRateControl *rateCtrl) 9011cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 9021cc31e629e8132df390ae692873c847d1c2f62c0James Dong double TotalMAD; 9031cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i; 9041cc31e629e8132df390ae692873c847d1c2f62c0James Dong TotalMAD = 0.0; 9051cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < (int)video->PicSizeInMbs; i++) 9061cc31e629e8132df390ae692873c847d1c2f62c0James Dong TotalMAD += rateCtrl->MADofMB[i]; 9071cc31e629e8132df390ae692873c847d1c2f62c0James Dong TotalMAD /= video->PicSizeInMbs; 9081cc31e629e8132df390ae692873c847d1c2f62c0James Dong return TotalMAD; 9091cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 9101cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9111cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9121cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9131cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9141cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9151cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* convert from QP to Qstep */ 9161cc31e629e8132df390ae692873c847d1c2f62c0James Dongdouble QP2Qstep(int QP) 9171cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 9181cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i; 9191cc31e629e8132df390ae692873c847d1c2f62c0James Dong double Qstep; 9201cc31e629e8132df390ae692873c847d1c2f62c0James Dong static const double QP2QSTEP[6] = { 0.625, 0.6875, 0.8125, 0.875, 1.0, 1.125 }; 9211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9221cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep = QP2QSTEP[QP % 6]; 9231cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < (QP / 6); i++) 9241cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep *= 2; 9251cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9261cc31e629e8132df390ae692873c847d1c2f62c0James Dong return Qstep; 9271cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 9281cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9291cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* convert from step size to QP */ 9301cc31e629e8132df390ae692873c847d1c2f62c0James Dongint Qstep2QP(double Qstep) 9311cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 9321cc31e629e8132df390ae692873c847d1c2f62c0James Dong int q_per = 0, q_rem = 0; 9331cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9341cc31e629e8132df390ae692873c847d1c2f62c0James Dong // assert( Qstep >= QP2Qstep(0) && Qstep <= QP2Qstep(51) ); 9351cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (Qstep < QP2Qstep(0)) 9361cc31e629e8132df390ae692873c847d1c2f62c0James Dong return 0; 9371cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (Qstep > QP2Qstep(51)) 9381cc31e629e8132df390ae692873c847d1c2f62c0James Dong return 51; 9391cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9401cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (Qstep > QP2Qstep(5)) 9411cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9421cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep /= 2; 9431cc31e629e8132df390ae692873c847d1c2f62c0James Dong q_per += 1; 9441cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9451cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9461cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (Qstep <= (0.625 + 0.6875) / 2) 9471cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9481cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep = 0.625; 9491cc31e629e8132df390ae692873c847d1c2f62c0James Dong q_rem = 0; 9501cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9511cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (Qstep <= (0.6875 + 0.8125) / 2) 9521cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9531cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep = 0.6875; 9541cc31e629e8132df390ae692873c847d1c2f62c0James Dong q_rem = 1; 9551cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9561cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (Qstep <= (0.8125 + 0.875) / 2) 9571cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9581cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep = 0.8125; 9591cc31e629e8132df390ae692873c847d1c2f62c0James Dong q_rem = 2; 9601cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9611cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (Qstep <= (0.875 + 1.0) / 2) 9621cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9631cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep = 0.875; 9641cc31e629e8132df390ae692873c847d1c2f62c0James Dong q_rem = 3; 9651cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9661cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (Qstep <= (1.0 + 1.125) / 2) 9671cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9681cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep = 1.0; 9691cc31e629e8132df390ae692873c847d1c2f62c0James Dong q_rem = 4; 9701cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9711cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 9721cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9731cc31e629e8132df390ae692873c847d1c2f62c0James Dong Qstep = 1.125; 9741cc31e629e8132df390ae692873c847d1c2f62c0James Dong q_rem = 5; 9751cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9761cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9771cc31e629e8132df390ae692873c847d1c2f62c0James Dong return (q_per * 6 + q_rem); 9781cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 9791cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9801cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9811cc31e629e8132df390ae692873c847d1c2f62c0James Dong 982