PV_STATUS RC_VopQPSetting(VideoEncData *video, rateControl *prc[])
{
    Int currLayer = video->currLayer;
    Vol *currVol = video->vol[currLayer];
    Vop *currVop = video->currVop;
#ifdef TEST_MBBASED_QP
    int i;
#endif

    rateControl *rc = video->rc[currLayer];
    MultiPass *pMP = video->pMP[currLayer];

    OSCL_UNUSED_ARG(prc);

    if (video->encParams->RC_Type == CONSTANT_Q)
    {
        M4VENC_MEMSET(video->QPMB, currVop->quantizer, sizeof(UChar)*currVol->nTotalMB);
        return PV_SUCCESS;
    }
    else
    {

        if (video->rc[currLayer]->encoded_frames == 0) /* rc[currLayer]->totalFrameNumber*/
        {
            M4VENC_MEMSET(video->QPMB, currVop->quantizer, sizeof(UChar)*currVol->nTotalMB);
            video->rc[currLayer]->Qc = video->encParams->InitQuantIvop[currLayer];
        }
        else
        {
            calculateQuantizer_Multipass((void*) video);
            currVop->quantizer = video->rc[currLayer]->Qc;
#ifdef TEST_MBBASED_QP
            i = currVol->nTotalMB;  /* testing changing QP at MB level */
            while (i)
            {
                i--;
                video->QPMB[i] = (i & 1) ? currVop->quantizer - 1 : currVop->quantizer + 1;
            }
#else
            M4VENC_MEMSET(video->QPMB, currVop->quantizer, sizeof(UChar)*currVol->nTotalMB);
#endif
        }

        video->header_bits = 0;
    }

    /* update pMP->framePos */
    if (++pMP->framePos == pMP->frameRange) pMP->framePos = 0;

    if (rc->T == 0)
    {
        pMP->counter_BTdst = (Int)(video->encParams->LayerFrameRate[video->currLayer] * 7.5 + 0.5); /* 0.75s time frame */
        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 */
        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 */
        pMP->counter_BTdst = PV_MIN(pMP->counter_BTdst, 20); /* Limit the target to be smaller than 3C */

        pMP->target_bits = rc->T = rc->TMN_TH = (Int)(rc->TMN_TH * (1.0 + pMP->counter_BTdst * 0.1));
        pMP->diff_counter = pMP->counter_BTdst;
    }

    /* collect the necessary data: target bits, actual bits, mad and QP */
    pMP->target_bits = rc->T;
    pMP->QP  = currVop->quantizer;

    pMP->mad = video->sumMAD / (float)currVol->nTotalMB;
    if (pMP->mad < MAD_MIN) pMP->mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */

    pMP->bitrate = rc->bitrate; /* calculated in RCVopQPSetting */
    pMP->framerate = rc->framerate;

    /* first pass encoding */
    pMP->nRe_Quantized = 0;

    return  PV_SUCCESS;
}
/* ======================================================================== */
PV_STATUS EncodeVop(VideoEncData *video)
{

    PV_STATUS status;
    Int currLayer = video->currLayer;
    Vol *currVol = video->vol[currLayer];
    Vop *currVop = video->currVop;
//	BitstreamEncVideo *stream=video->bitstream1;
    UChar *Mode = video->headerInfo.Mode;
    rateControl **rc = video->rc;
//	UInt time=0;

    /*******************/
    /* Initialize mode */
    /*******************/

    switch (currVop->predictionType)
    {
        case I_VOP:
            M4VENC_MEMSET(Mode, MODE_INTRA, sizeof(UChar)*currVol->nTotalMB);
            break;
        case P_VOP:
            M4VENC_MEMSET(Mode, MODE_INTER, sizeof(UChar)*currVol->nTotalMB);
            break;
        case B_VOP:
            /*M4VENC_MEMSET(Mode, MODE_INTER_B,sizeof(UChar)*nTotalMB);*/
            return PV_FAIL;
        default:
            return PV_FAIL;
    }

    /*********************/
    /* Motion Estimation */
    /* compute MVs, scene change detection, edge padding, */
    /* intra refresh, compute block activity */
    /*********************/
    MotionEstimation(video);	/* do ME for the whole frame */

    /***************************/
    /* rate Control (assign QP) */
    /* 4/11/01, clean-up, and put into a separate function */
    /***************************/
    status = RC_VopQPSetting(video, rc);
    if (status == PV_FAIL)
        return PV_FAIL;

    /**********************/
    /*     Encode VOP     */
    /**********************/
    if (video->slice_coding) /* end here */
    {
        /* initialize state variable for slice-based APIs */
        video->totalSAD = 0;
        video->mbnum = 0;
        video->sliceNo[0] = 0;
        video->numIntra = 0;
        video->offset = 0;
        video->end_of_buf = 0;
        video->hp_guess = -1;
        return status;
    }

    status = EncodeVop_NoME(video);

    /******************************/
    /* rate control (update stat) */
    /* 6/2/01 separate function */
    /******************************/

    RC_VopUpdateStat(video, rc[currLayer]);

    return status;
}