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