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