void RCInitChromaQP(AVCEncObject *encvid) { AVCCommonObj *video = encvid->common; AVCMacroblock *currMB = video->currMB; int q_bits; /* we have to do the same thing for AVC_CLIP3(0,51,video->QSy) */ video->QPy_div_6 = (currMB->QPy * 43) >> 8; video->QPy_mod_6 = currMB->QPy - 6 * video->QPy_div_6; currMB->QPc = video->QPc = mapQPi2QPc[AVC_CLIP3(0, 51, currMB->QPy + video->currPicParams->chroma_qp_index_offset)]; video->QPc_div_6 = (video->QPc * 43) >> 8; video->QPc_mod_6 = video->QPc - 6 * video->QPc_div_6; /* pre-calculate this to save computation */ q_bits = 4 + video->QPy_div_6; if (video->slice_type == AVC_I_SLICE) { encvid->qp_const = 682 << q_bits; // intra } else { encvid->qp_const = 342 << q_bits; // inter } q_bits = 4 + video->QPc_div_6; if (video->slice_type == AVC_I_SLICE) { encvid->qp_const_c = 682 << q_bits; // intra } else { encvid->qp_const_c = 342 << q_bits; // inter } encvid->lambda_mode = QP2QUANT[AVC_MAX(0, currMB->QPy-SHIFT_QP)]; encvid->lambda_motion = LAMBDA_FACTOR(encvid->lambda_mode); return ; }
void RCInitFrameQP(AVCEncObject *encvid) { AVCCommonObj *video = encvid->common; AVCRateControl *rateCtrl = encvid->rateCtrl; AVCPicParamSet *picParam = video->currPicParams; MultiPass *pMP = rateCtrl->pMP; if (rateCtrl->rcEnable == TRUE) { /* frame layer rate control */ if (rateCtrl->encoded_frames == 0) { video->QPy = rateCtrl->Qc = rateCtrl->initQP; } else { calculateQuantizer_Multipass(encvid, video, rateCtrl, pMP); video->QPy = rateCtrl->Qc; } rateCtrl->NumberofHeaderBits = 0; rateCtrl->NumberofTextureBits = 0; rateCtrl->numFrameBits = 0; // reset /* update pMP->framePos */ if (++pMP->framePos == pMP->frameRange) pMP->framePos = 0; if (rateCtrl->T == 0) { pMP->counter_BTdst = (int)(rateCtrl->frame_rate * 7.5 + 0.5); /* 0.75s time frame */ pMP->counter_BTdst = AVC_MIN(pMP->counter_BTdst, (int)(rateCtrl->max_BitVariance_num / 2 * 0.40)); /* 0.75s time frame may go beyond VBV buffer if we set the buffer size smaller than 0.75s */ pMP->counter_BTdst = AVC_MAX(pMP->counter_BTdst, (int)((rateCtrl->Bs / 2 - rateCtrl->VBV_fullness) * 0.30 / (rateCtrl->TMN_TH / 10.0) + 0.5)); /* At least 30% of VBV buffer size/2 */ pMP->counter_BTdst = AVC_MIN(pMP->counter_BTdst, 20); /* Limit the target to be smaller than 3C */ pMP->target_bits = rateCtrl->T = rateCtrl->TMN_TH = (int)(rateCtrl->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 = rateCtrl->T; pMP->QP = video->QPy; pMP->mad = (OsclFloat)rateCtrl->totalSAD / video->PicSizeInMbs; //ComputeFrameMAD(video, rateCtrl); if (pMP->mad < MAD_MIN) pMP->mad = MAD_MIN; /* MAD_MIN is defined as 1 in mp4def.h */ pMP->bitrate = rateCtrl->bitRate; /* calculated in RCVopQPSetting */ pMP->framerate = rateCtrl->frame_rate; /* first pass encoding */ pMP->nRe_Quantized = 0; } // rcEnable else { video->QPy = rateCtrl->initQP; } // printf(" %d ",video->QPy); if (video->CurrPicNum == 0 && encvid->outOfBandParamSet == FALSE) { picParam->pic_init_qs_minus26 = 0; picParam->pic_init_qp_minus26 = video->QPy - 26; } // need this for motion estimation encvid->lambda_mode = QP2QUANT[AVC_MAX(0, video->QPy-SHIFT_QP)]; encvid->lambda_motion = LAMBDA_FACTOR(encvid->lambda_mode); return ; }
/*! ************************************************************************ * \brief * FastIntegerPelBlockMotionSearch: fast pixel block motion search * this algrithm is called UMHexagonS(see JVT-D016),which includes * four steps with different kinds of search patterns * \par Input: * pel_t** orig_pic, // <-- original picture * int ref, // <-- reference frame (0... or -1 (backward)) * int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block * int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block * int blocktype, // <-- block type (1-16x16 ... 7-4x4) * int pred_mv_x, // <-- motion vector predictor (x) in sub-pel units * int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units * int* mv_x, // --> motion vector (x) - in pel units * int* mv_y, // --> motion vector (y) - in pel units * int search_range, // <-- 1-d search range in pel units * int min_mcost, // <-- minimum motion cost (cost for center or huge value) * double lambda // <-- lagrangian parameter for determining motion cost * \par * Three macro definitions defined in this program: * 1. EARLY_TERMINATION: early termination algrithm, refer to JVT-D016.doc * 2. SEARCH_ONE_PIXEL: search one pixel in search range * 3. SEARCH_ONE_PIXEL1(value_iAbort): search one pixel in search range, * but give a parameter to show if mincost refeshed * \ Main contributors: (see contributors.h for copyright, address and affiliation details) * Zhibo Chen <*****@*****.**> * JianFeng Xu <*****@*****.**> * \date : 2003.8 ************************************************************************ */ int // ==> minimum motion cost after search FastIntegerPelBlockMotionSearch (pel_t** orig_pic, // <-- not used int ref, // <-- reference frame (0... or -1 (backward)) int list, int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block int blocktype, // <-- block type (1-16x16 ... 7-4x4) int pred_mv_x, // <-- motion vector predictor (x) in sub-pel units int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units int* mv_x, // --> motion vector (x) - in pel units int* mv_y, // --> motion vector (y) - in pel units int search_range, // <-- 1-d search range in pel units int min_mcost, // <-- minimum motion cost (cost for center or huge value) double lambda) // <-- lagrangian parameter for determining motion cost { static int Diamond_x[4] = {-1, 0, 1, 0}; static int Diamond_y[4] = {0, 1, 0, -1}; static int Hexagon_x[6] = {2, 1, -1, -2, -1, 1}; static int Hexagon_y[6] = {0, -2, -2, 0, 2, 2}; static int Big_Hexagon_x[16] = {0,-2, -4,-4,-4, -4, -4, -2, 0, 2, 4, 4, 4, 4, 4, 2}; static int Big_Hexagon_y[16] = {4, 3, 2, 1, 0, -1, -2, -3, -4, -3, -2, -1, 0, 1, 2, 3}; int pos, cand_x, cand_y, mcost; pel_t *(*get_ref_line)(int, pel_t*, int, int, int, int); int list_offset = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? img->current_mb_nr%2 ? 4 : 2 : 0; pel_t* ref_pic = listX[list+list_offset][ref]->imgY_11;//img->type==B_IMG? Refbuf11 [ref+((mref==mref_fld)) +1] : Refbuf11[ref]; int best_pos = 0; // position with minimum motion cost int max_pos = (2*search_range+1)*(2*search_range+1); // number of search positions int lambda_factor = LAMBDA_FACTOR (lambda); // factor for determining lagragian motion cost int mvshift = 2; // motion vector shift for getting sub-pel units int blocksize_y = input->blc_size[blocktype][1]; // vertical block size int blocksize_x = input->blc_size[blocktype][0]; // horizontal block size int blocksize_x4 = blocksize_x >> 2; // horizontal block size in 4-pel units int pred_x = (pic_pix_x << mvshift) + pred_mv_x; // predicted position x (in sub-pel units) int pred_y = (pic_pix_y << mvshift) + pred_mv_y; // predicted position y (in sub-pel units) int center_x = pic_pix_x + *mv_x; // center position x (in pel units) int center_y = pic_pix_y + *mv_y; // center position y (in pel units) int best_x, best_y; int check_for_00 = (blocktype==1 && !input->rdopt && img->type!=B_SLICE && ref==0); int search_step,iYMinNow, iXMinNow; int i,m, iSADLayer; int iAbort; int N_Bframe = input->successive_Bframe; float betaSec,betaThird; int height=((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))?img->height/2:img->height; //===== set function for getting reference picture lines ===== if ((center_x > search_range) && (center_x < img->width -1-search_range-blocksize_x) && (center_y > search_range) && (center_y < height-1-search_range-blocksize_y) ) { get_ref_line = FastLineX; } else { get_ref_line = UMVLineX; } //////allocate memory for search state////////////////////////// memset(McostState[0],0,(2*search_range+1)*(2*search_range+1)*4); ///////Threshold defined for early termination/////////////////// if(ref>0) { if(pred_SAD_ref!=0) { betaSec = Bsize[blocktype]/(pred_SAD_ref*pred_SAD_ref)-AlphaSec[blocktype]; betaThird = Bsize[blocktype]/(pred_SAD_ref*pred_SAD_ref)-AlphaThird[blocktype]; } else { betaSec = 0; betaThird = 0; } } else { if(blocktype==1) { if(pred_SAD_space !=0) { betaSec = Bsize[blocktype]/(pred_SAD_space*pred_SAD_space)-AlphaSec[blocktype]; betaThird = Bsize[blocktype]/(pred_SAD_space*pred_SAD_space)-AlphaThird[blocktype]; } else { betaSec = 0; betaThird = 0; } } else { if(pred_SAD_uplayer !=0) { betaSec = Bsize[blocktype]/(pred_SAD_uplayer*pred_SAD_uplayer)-AlphaSec[blocktype]; betaThird = Bsize[blocktype]/(pred_SAD_uplayer*pred_SAD_uplayer)-AlphaThird[blocktype]; } else { betaSec = 0; betaThird = 0; } } } /*****************************/ //check the center median predictor cand_x = center_x ; cand_y = center_y ; mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y); mcost = PartCalMad(ref_pic, orig_pic, get_ref_line,blocksize_y,blocksize_x,blocksize_x4,mcost,min_mcost,cand_x,cand_y); McostState[search_range][search_range] = mcost; if (mcost < min_mcost) { min_mcost = mcost; best_x = cand_x; best_y = cand_y; } iXMinNow = best_x; iYMinNow = best_y; for (m = 0; m < 4; m++) { cand_x = iXMinNow + Diamond_x[m]; cand_y = iYMinNow + Diamond_y[m]; SEARCH_ONE_PIXEL } if(center_x != pic_pix_x || center_y != pic_pix_y) { cand_x = pic_pix_x ; cand_y = pic_pix_y ; SEARCH_ONE_PIXEL iXMinNow = best_x; iYMinNow = best_y; for (m = 0; m < 4; m++) { cand_x = iXMinNow + Diamond_x[m]; cand_y = iYMinNow + Diamond_y[m]; SEARCH_ONE_PIXEL } }