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