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; }