www.pudn.com > wm2.5.zip > motion_esti.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2004, Advanced Audio Video Coding Standard, Part II * * DISCLAIMER OF WARRANTY * * These software programs are available to the users without any * license fee or royalty on an "as is" basis. The AVS disclaims * any and all warranties, whether express, implied, or statutory, * including any implied warranties of merchantability or of fitness * for a particular purpose. In no event shall the contributors or * the AVS be liable for any incidental, punitive, or consequential * damages of any kind whatsoever arising from the use of this program. * * This disclaimer of warranty extends to the user of this program * and user's customers, employees, agents, transferees, successors, * and assigns. * * The AVS does not represent or warrant that the program furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of AVS, including shareware, may be * subject to royalty fees to patent holders. Information regarding * the AVS patent policy is available from the AVS Web site at * http://www.avs.org.cn * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. ************************************************************************ */ #include#include #include "global.h" #include "motion_esti.h" #include "interpred.h" #include "rdopt.h" //cbzhu 12-15 #ifdef _ISOLATED_REGION_ #include "IREG.h" #endif // _ISOLATED_REGION_ // for memset() function extern const int csiInter_Block_Size[4][2]; extern const int csiInter_Subblk_Size[4][2]; extern int AffectedByLeftover(int x_pos, int y_pos, int ref); /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function name : CalIntegerPixSAD + parameters : + return : returns SAD of a integer pel MV + descriptions : created by jhzheng : 2004/02/12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int CalIntegerPixSAD( int ref, int blkindex, int subblkindex, int blksize_x, int blksize_y, int cand_x, int cand_y, int mcost, int min_mcost, int y_pos, int x_pos) { int y,x; int ypos,xpos; int yoff,xoff,oriy,orix; xoff = ((blkindex & 1)<<3) + ((subblkindex & 1)<<2); yoff = ((blkindex >> 1)<<3) + ((subblkindex >> 1)<<2); for (y=0; y img_height+(PAD_SIZE<<1)-1); oriy = yoff + y; for (x=0; x img_width+(PAD_SIZE<<1)-1); orix = xoff + x; mcost += absm(pgMbData->org_luma[oriy][orix] - reference_frame[ref][0][ypos][xpos]); } if (mcost >= min_mcost) break; } return mcost; } /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function name : CalSubPixSAD + parameters : + return : returns SAD of a fractiona pel MV + descriptions : created by jhzheng : 2004/02/12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int CalSubPixSAD ( int ref, int blkindex, int blksize_x, int blksize_y, int cand_x, int cand_y, int mcost, int min_mcost) { int y,x8,i; int ypos,xpos; int yoff,xoff,oriy,orix; xoff = (blkindex & 1)<<3; yoff = (blkindex >> 1)<<3; for (y=0; y org_luma[oriy][orix+i] - pgMbData->Sub_pixel_buffer[ref][ypos][xpos+i*4]); } } if (mcost >= min_mcost) { break; } } return mcost; } /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function name : FME_Integer_Pel_Block_Motion_Search + parameters : + return : cost of the current block + descriptions : created by xyji & jhzheng : 2004/02/12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int // ==> minimum motion cost after search FME_Integer_Pel_Block_Motion_Search( int ref, int offx, int off_y, int blkindex, // <-- block index(0~3) int blktype, // <-- block type (1-16x16 ... 4-8x8) int subblkindex, int subblktype, int min_mcost, // <-- minimum motion cost (cost for center or huge value) int lambda_factor, // <-- factor for determining lagragian motion cost int ypos, int xpos ) { int pos, mcost; int best_x, best_y, cand_x, cand_y; int search_step, iYMinNow, iXMinNow; int i,m; int iAbort; int blksize_y; int blksize_x; if(blktype == 4) { blksize_y = (csiInter_Subblk_Size[subblktype - 1][1]); // vertical block size blksize_x = (csiInter_Subblk_Size[subblktype - 1][0]); // horizontal block size } else { blksize_y = (csiInter_Block_Size[blktype - 1][1]); // vertical block size blksize_x = (csiInter_Block_Size[blktype - 1][0]); // horizontal block size } for(i = 0 ; i < RANGE_FULL ; i ++) { memset(pgMbData->Diamond_status[i],0,RANGE_FULL*sizeof(pgMbData->Diamond_status[0][0])); } ////////////search around the predictor //check the center median predictor cand_x = offx; cand_y = off_y; mcost = MV_COST(lambda_factor, ((cand_x << 2) - sResidual_MV[0]), ((cand_y << 2) - sResidual_MV[1])); mcost = CalIntegerPixSAD(ref, blkindex,subblkindex,blksize_x,blksize_y, cand_x, cand_y,mcost,min_mcost, ypos, xpos); pgMbData->Diamond_status[cand_x+SEARCHRANGE][cand_y+SEARCHRANGE] = 1; 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 + pgMbData->Diamond_index[m][0]; cand_y = iYMinNow + pgMbData->Diamond_index[m][1]; SEARCH_ONE_PIXEL } //current position check //if (((offx - sInter_Pred_MV[blkindex][0]/4)!=0)||((off_y - sInter_Pred_MV[blkindex][1]/4)!=0)) if (((offx - sInteger_MV[0])!=0)||((off_y - sInteger_MV[1])!=0)) { cand_x = offx - sInteger_MV[0]; cand_y = off_y - sInteger_MV[1]; SEARCH_ONE_PIXEL iXMinNow = best_x; iYMinNow = best_y; for (m = 0; m < 4; m++) { cand_x = iXMinNow + pgMbData->Diamond_index[m][0]; cand_y = iYMinNow + pgMbData->Diamond_index[m][1]; SEARCH_ONE_PIXEL } } //strengthen local search iXMinNow = best_x; iYMinNow = best_y; for (m = 0; m < 4; m++) { cand_x = iXMinNow + pgMbData->Diamond_index[m][0]; cand_y = iYMinNow + pgMbData->Diamond_index[m][1]; SEARCH_ONE_PIXEL } //Unsymmetrical-cross search //first_step: iXMinNow = best_x; iYMinNow = best_y; for(i=1;i<=SEARCHRANGE>>1;i++) { search_step = (i<<1) - 1; cand_x = iXMinNow + search_step; cand_y = iYMinNow ; SEARCH_ONE_PIXEL cand_x = iXMinNow - search_step; cand_y = iYMinNow ; SEARCH_ONE_PIXEL } for(i=1;i<=SEARCHRANGE>>2;i++) { search_step = (i<<1) - 1; cand_x = iXMinNow ; cand_y = iYMinNow + search_step; SEARCH_ONE_PIXEL cand_x = iXMinNow ; cand_y = iYMinNow - search_step; SEARCH_ONE_PIXEL } // Uneven Multi-Hexagon-grid Search iXMinNow = best_x; iYMinNow = best_y; for(pos=1;pos<25;pos++) { cand_x = iXMinNow + pgMbData->Spiral_index[pos][0]; cand_y = iYMinNow + pgMbData->Spiral_index[pos][1]; SEARCH_ONE_PIXEL } for(i=1;i<=SEARCHRANGE>>2; i++) { //iAbort = 0; for (m = 0; m < 16; m++) { cand_x = iXMinNow + pgMbData->BigHexagon_index[m][0]*i; cand_y = iYMinNow + pgMbData->BigHexagon_index[m][1]*i; //SEARCH_ONE_PIXEL1(1) SEARCH_ONE_PIXEL } } //Extended Hexagon-based Search //sec_step: iXMinNow = best_x; iYMinNow = best_y; for(i=0;i Hexagon_index[m][0]; cand_y = iYMinNow + pgMbData->Hexagon_index[m][1]; SEARCH_ONE_PIXEL1(0) } if(iAbort) break; iXMinNow = best_x; iYMinNow = best_y; } // the third step with a small search pattern //third_step: iXMinNow = best_x; iYMinNow = best_y; for(i=0;i Diamond_index[m][0]; cand_y = iYMinNow + pgMbData->Diamond_index[m][1]; SEARCH_ONE_PIXEL1(0) } if(iAbort) break; iXMinNow = best_x; iYMinNow = best_y; } // best pos in integer search sInter_MV[blkindex][subblkindex][0] = best_x<<2; //qwang 2004-3-21 sInter_MV[blkindex][0] sInter_MV[blkindex][subblkindex][1] = best_y<<2; //qwang 2004-3-21 sInter_MV[blkindex][1] return min_mcost; } /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function name : FME_Sub_Pel_Block_Motion_Search + parameters : + return : cost of the current block + descriptions : created by xyji & jhzheng : 2004/02/12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int // ==> minimum motion cost after search FME_Sub_Pel_Block_Motion_Search( int ref, int xoff, int yoff, int blkindex, // <-- block index(0~3) int subblkindex, int subblktype, // <-- block type (1-16x16 ... 4-8x8) int min_mcost, // <-- minimum motion cost (cost for center or huge value) int lambda_factor, // <-- factor for determining lagragian motion cost int ypos, int xpos ) { int mcost; int blksize_y = (csiInter_Subblk_Size[subblktype - 1][1]); // vertical block size int blksize_x = (csiInter_Subblk_Size[subblktype - 1][0]); // horizontal block size int iXMinNow,iYMinNow,i; int cand_mv_x, cand_mv_y; int m,currmv_x,currmv_y; int abort_search; int full_x,full_y,sub_x,sub_y; int pred_frac_x,pred_frac_y; int refy, refx; int y0, oriy, orix, x0; int y_pos, x_pos; int j, diff[16]; int width4 = (pgImage->img_width + (PAD_SIZE<<1) - 1)<<2; int height4 = (pgImage->img_height + (PAD_SIZE<<1) - 1)<<2; for(i = 0 ; i < RANGE_SUB ; i ++) { memset(pgMbData->Diamond_status[i],0,RANGE_SUB*sizeof(pgMbData->Diamond_status[0][0])); } cand_mv_x = currmv_x = 0; cand_mv_y = currmv_y = 0; pgMbData->Diamond_status[cand_mv_y + SUBSEARANGE][cand_mv_x + SUBSEARANGE] = 1; full_x = sInter_MV[blkindex][0][0]; //best pos for Integer search //qwang 2004-3-21 sInter_MV[blkindex][0] full_y = sInter_MV[blkindex][0][1]; //qwang 2004-3-21 sInter_MV[blkindex][1] pred_frac_x = (sResidual_MV[0] - full_x) % 4 ;//&0x03; //coordinate in sub pixel area pred_frac_y = (sResidual_MV[1] - full_y) % 4 ;//&0x03; //search prediction pos in sub pixel area if(pred_frac_x!=0 || pred_frac_y!=0) { cand_mv_x = pred_frac_x; cand_mv_y = pred_frac_y; if(absm(cand_mv_x) <= SUBSEARANGE && absm(cand_mv_y) <= SUBSEARANGE) { mcost = MV_COST (lambda_factor, full_x + pred_frac_x - sResidual_MV[0], full_y + pred_frac_y - sResidual_MV[1]); //----- add up SAD ---- if(!input.hadamard) { for (y0 = 0; y0 < blksize_y; y0++) { oriy = yoff + y0; refy = HALF_CENTER_OFFSET + (y0 << 2) + cand_mv_y; for (x0 = 0; x0 < blksize_x; x0++) { orix = xoff + x0; refx = HALF_CENTER_OFFSET + (x0 << 2) + cand_mv_x; y_pos = ypos+ HALF_CENTER_OFFSET+(y0 << 2) + cand_mv_y + (PAD_SIZE<<2); x_pos = xpos+ HALF_CENTER_OFFSET+(x0 << 2) + cand_mv_x + (PAD_SIZE<<2); x_pos = (x_pos < 0) ? (x_pos & 3) : (x_pos > width4 ) ? (width4 + (x_pos & 3)) : x_pos; y_pos = (y_pos < 0) ? (y_pos & 3) : (y_pos > height4) ? (height4 + (y_pos & 3)) : y_pos; mcost += absm(pgMbData->org_luma[oriy][orix] - reference_quater_pel_frame[ref][y_pos][x_pos]); } } }else { for (y0 = 0; y0 < blksize_y; y0+=4) { oriy = yoff + y0; refy = HALF_CENTER_OFFSET + (y0 << 2) + cand_mv_y; for (x0 = 0; x0 < blksize_x; x0+=4) { orix = xoff + x0; refx = HALF_CENTER_OFFSET + (x0 << 2) + cand_mv_x; for(j=0; j<4;j++) for(i=0; i<4;i++) { y_pos = ypos+ HALF_CENTER_OFFSET+(y0 << 2) + (j<<2) + cand_mv_y + (PAD_SIZE<<2); x_pos = xpos+ HALF_CENTER_OFFSET+(x0 << 2) + (i<<2) + cand_mv_x + (PAD_SIZE<<2); x_pos = (x_pos < 0) ? (x_pos & 3) : (x_pos > width4 ) ? (width4 + (x_pos & 3)) : x_pos; y_pos = (y_pos < 0) ? (y_pos & 3) : (y_pos > height4) ? (height4 + (y_pos & 3)) : y_pos; diff[j*4+i] = pgMbData->org_luma[oriy+j][orix+i] - reference_quater_pel_frame[ref][y_pos][x_pos]; } mcost += SATD(diff); } } } pgMbData->Diamond_status[cand_mv_y + SUBSEARANGE][cand_mv_x + SUBSEARANGE] = 1; if (mcost < min_mcost) { min_mcost = mcost; currmv_x = cand_mv_x; currmv_y = cand_mv_y; } } } iXMinNow = currmv_x; iYMinNow = currmv_y; for(i = 0 ; i < RANGE_SUB ; i ++) { abort_search=1; for (m = 0; m < 4; m++) { cand_mv_x = iXMinNow + (pgMbData->Diamond_index[m][0]);//<<2); cand_mv_y = iYMinNow + (pgMbData->Diamond_index[m][1]);//<<2); if(absm(cand_mv_x) <= SUBSEARANGE && absm(cand_mv_y) <= SUBSEARANGE) { if(!pgMbData->Diamond_status[cand_mv_y + SUBSEARANGE][cand_mv_x + SUBSEARANGE]) { sub_x = full_x + cand_mv_x; sub_y = full_y + cand_mv_y; mcost = MV_COST (lambda_factor, sub_x - sResidual_MV[0], sub_y - sResidual_MV[1]); //----- add up SAD ---- if(!input.hadamard) { for (y0 = 0; y0 < blksize_y; y0++) { oriy = yoff + y0; refy = HALF_CENTER_OFFSET + (y0 << 2) + cand_mv_y; for (x0 = 0; x0 < blksize_x; x0++) { orix = xoff + x0; refx = HALF_CENTER_OFFSET + (x0 << 2) + cand_mv_x; y_pos = ypos+ HALF_CENTER_OFFSET+(y0 << 2) + cand_mv_y + (PAD_SIZE<<2); x_pos = xpos+ HALF_CENTER_OFFSET+(x0 << 2) + cand_mv_x + (PAD_SIZE<<2); x_pos = (x_pos < 0) ? (x_pos & 3) : (x_pos > width4 ) ? (width4 + (x_pos & 3)) : x_pos; y_pos = (y_pos < 0) ? (y_pos & 3) : (y_pos > height4) ? (height4 + (y_pos & 3)) : y_pos; mcost += absm(pgMbData->org_luma[oriy][orix] - reference_quater_pel_frame[ref][y_pos][x_pos]); } } }else { for (y0 = 0; y0 < blksize_y; y0+=4) { oriy = yoff + y0; refy = HALF_CENTER_OFFSET + (y0 << 2) + cand_mv_y; for (x0 = 0; x0 < blksize_x; x0+=4) { orix = xoff + x0; refx = HALF_CENTER_OFFSET + (x0 << 2) + cand_mv_x; for(j=0; j<4;j++) for(i=0; i<4;i++) { y_pos = ypos+ HALF_CENTER_OFFSET+(y0 << 2) + (j<<2) + cand_mv_y + (PAD_SIZE<<2); x_pos = xpos+ HALF_CENTER_OFFSET+(x0 << 2) + (i<<2) + cand_mv_x + (PAD_SIZE<<2); x_pos = (x_pos < 0) ? (x_pos & 3) : (x_pos > width4 ) ? (width4 + (x_pos & 3)) : x_pos; y_pos = (y_pos < 0) ? (y_pos & 3) : (y_pos > height4) ? (height4 + (y_pos & 3)) : y_pos; diff[j*4+i] = pgMbData->org_luma[oriy+j][orix+i] - reference_quater_pel_frame[ref][y_pos][x_pos]; } mcost += SATD(diff); } } } pgMbData->Diamond_status[cand_mv_y + SUBSEARANGE][cand_mv_x + SUBSEARANGE] = 1; if (mcost < min_mcost) { min_mcost = mcost; currmv_x = cand_mv_x; currmv_y = cand_mv_y; abort_search = 0; } } } } iXMinNow = currmv_x; iYMinNow = currmv_y; if(abort_search) break; } sInter_MV[blkindex][subblkindex][0] += currmv_x; //qwang 2004-3-21 sInter_MV[blkindex][0] sInter_MV[blkindex][subblkindex][1] += currmv_y; //qwang 2004-3-21 sInter_MV[blkindex][1] //===== return minimum motion cost ===== return min_mcost; } /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function name : Sub_Pel_Block_Motion_Search + parameters : void + return : cost of the current block + descriptions : created by xyji & jhzheng: 2004/02/12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int // ==> minimum motion cost after search //qwang 2004-3-24 Sub_Pel_Block_Motion_Search ( int ref, int offx, int off_y, int blkindex, int blktype, // <-- block type (1-16x16 ... 4-8x8) int subblkindex, int subblktype, int min_mcost, // <-- minimum motion cost (cost for center or huge value) int lambda_factor, // <-- factor for determining lagragian motion cost int ypos, int xpos ) { int pos, best_pos, mcost; int y0, x0; int cand_mv_x, cand_mv_y; //cbzhu 12-15 #ifdef _ISOLATED_REGION_ int Flag_IREG=0; int xpos_plusoffset = xpos + QUARTER_CENTER_OFFSET; int ypos_plusoffset = ypos + QUARTER_CENTER_OFFSET; #endif // _ISOLATED_REGION_ int blksize_y; // vertical block size int blksize_x; // horizontal block size int i, j; int quart_startpoint[2] ; int xoff,yoff,orix,oriy,refx,refy; int diff[16]; int y_pos, x_pos; int width4 = (pgImage->img_width + (PAD_SIZE<<1) - 1)<<2; int height4 = (pgImage->img_height + (PAD_SIZE<<1) - 1)<<2; xoff = ((blkindex & 1)<<3) + ((subblkindex & 1)<<2); yoff = ((blkindex >> 1)<<3) + ((subblkindex >> 1)<<2); if(blktype == 4) { blksize_y = (csiInter_Subblk_Size[subblktype - 1][1]); // vertical block size blksize_x = (csiInter_Subblk_Size[subblktype - 1][0]); // horizontal block size } else { blksize_y = (csiInter_Block_Size[blktype - 1][1]); // vertical block size blksize_x = (csiInter_Block_Size[blktype - 1][0]); // horizontal block size } quart_startpoint[0] = 0; quart_startpoint[1] = 0; //cbzhu 12-15 #ifdef _ISOLATED_REGION_ if (input.IREGEnable) { if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) { iSubPixFlag = 0; iSubPixFlag1 = 0; } else { iSubPixFlag = 1; iSubPixFlag1 = 0; } } #endif // _ISOLATED_REGION_ /********************************* ***** HALF-PEL REFINEMENT ***** *********************************/ //===== loop over search positions ===== for (best_pos = 0, pos = input.hadamard ? 0:1; pos < HALF_SEARCH_RANGE; pos++) { cand_mv_x = (pgMbData->Spiral_index [pos][0] << 1); // half-pel units cand_mv_y = (pgMbData->Spiral_index [pos][1] << 1); // half-pel units //cbzhu 12-15 #ifdef _ISOLATED_REGION_ if (input.IREGEnable) { if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) { Flag_IREG = 0; for (y0 = 0; y0 < blksize_y; y0++) { for (x0 = 0; x0 < blksize_x; x0++) { refx = xpos_plusoffset + ( x0 << 2 ) + cand_mv_x; refy = ypos_plusoffset + ( y0 << 2 ) + cand_mv_y; Flag_IREG = AffectedByLeftover(refx, refy, ref); if ( Flag_IREG ) { break; } } if ( Flag_IREG ) { break; } } if ( Flag_IREG ) { continue; } if(Flag_IREG==0)iSubPixFlag=1; }// if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) } #endif // _ISOLATED_REGION_ //----- set motion vector cost ----- //----- Yulejun 2004.Sep.04 ----- if ( pgImage->half_pixel_mv_flag == 0 ) { mcost = MV_COST (lambda_factor, // for 1/2 pixel ME ( cand_mv_x + sInter_MV[blkindex][subblkindex][0] - sResidual_MV[0] ), ( cand_mv_y + sInter_MV[blkindex][subblkindex][1] - sResidual_MV[1] ) ); } else // 1/2 pixel ME { mcost = MV_COST (lambda_factor, // for 1/2 pixel ME (cand_mv_x) + (sInter_MV[blkindex][subblkindex][0]>>1) - (sResidual_MV[0]>>1), (cand_mv_y) + (sInter_MV[blkindex][subblkindex][1]>>1) - (sResidual_MV[1]>>1) ); } //-------------------------------- //----- add up SAD ---- if(!input.hadamard) { for (y0 = 0; y0 < blksize_y; y0++) { oriy = yoff + y0; refy = HALF_CENTER_OFFSET + (y0 << 2) + cand_mv_y; for (x0 = 0; x0 < blksize_x; x0++) { orix = xoff + x0; refx = HALF_CENTER_OFFSET + (x0 << 2) + cand_mv_x; y_pos = ypos+ HALF_CENTER_OFFSET+(y0 << 2) + cand_mv_y + (PAD_SIZE<<2); x_pos = xpos+ HALF_CENTER_OFFSET+(x0 << 2) + cand_mv_x + (PAD_SIZE<<2); x_pos = (x_pos < 0) ? (x_pos & 3) : (x_pos > width4 ) ? (width4 + (x_pos & 3)) : x_pos; y_pos = (y_pos < 0) ? (y_pos & 3) : (y_pos > height4) ? (height4 + (y_pos & 3)) : y_pos; mcost += absm(pgMbData->org_luma[oriy][orix] - reference_quater_pel_frame[ref][y_pos][x_pos]); } } }else { for (y0 = 0; y0 < blksize_y; y0+=4) { oriy = yoff + y0; refy = HALF_CENTER_OFFSET + (y0 << 2) + cand_mv_y; for (x0 = 0; x0 < blksize_x; x0+=4) { orix = xoff + x0; refx = HALF_CENTER_OFFSET + (x0 << 2) + cand_mv_x; for(j=0; j<4;j++) for(i=0; i<4;i++) { y_pos = ypos+ HALF_CENTER_OFFSET+(y0 << 2) + (j<<2) + cand_mv_y + (PAD_SIZE<<2); x_pos = xpos+ HALF_CENTER_OFFSET+(x0 << 2) + (i<<2) + cand_mv_x + (PAD_SIZE<<2); x_pos = (x_pos < 0) ? (x_pos & 3) : (x_pos > width4 ) ? (width4 + (x_pos & 3)) : x_pos; y_pos = (y_pos < 0) ? (y_pos & 3) : (y_pos > height4) ? (height4 + (y_pos & 3)) : y_pos; diff[j*4+i] = pgMbData->org_luma[oriy+j][orix+i] - reference_quater_pel_frame[ref][y_pos][x_pos]; } mcost += SATD(diff); } } } if (mcost < min_mcost) { min_mcost = mcost; best_pos = pos; } } //cbzhu 12-15 #ifdef _ISOLATED_REGION_ if (input.IREGEnable) { if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) { if (iSubPixFlag == 0 && Flag_IREG == 1) { iSubPixFlag1 = 1; return (1 << 30); } } } #endif // _ISOLATED_REGION_ if (best_pos) { quart_startpoint[0] = (pgMbData->Spiral_index [best_pos][0] << 1); quart_startpoint[1] = (pgMbData->Spiral_index [best_pos][1] << 1); sInter_MV[blkindex][subblkindex][0] += quart_startpoint[0]; sInter_MV[blkindex][subblkindex][1] += quart_startpoint[1]; } //cbzhu 12-15 #ifdef _ISOLATED_REGION_ if (input.IREGEnable) { if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) { iSubPixFlag = 0; iSubPixFlag1 = 0; } else { iSubPixFlag = 1; iSubPixFlag1 = 0; } } #endif // _ISOLATED_REGION_ if ( pgImage->half_pixel_mv_flag == 0) // 1/4-pixel MV { /************************************ ***** QUARTER-PEL REFINEMENT ***** ************************************/ //===== loop over search positions ===== for (best_pos = 0, pos = 1; pos < QUARTER_SEARCH_RANGE; pos++) { cand_mv_x = quart_startpoint[0] + pgMbData->Spiral_index [pos][0]; // quarter-pel units cand_mv_y = quart_startpoint[1] + pgMbData->Spiral_index [pos][1]; // quarter-pel units //cbzhu 12-15 #ifdef _ISOLATED_REGION_ if (input.IREGEnable) { if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) { Flag_IREG = 0; for (y0 = 0; y0 < blksize_y; y0++) { for (x0 = 0; x0 < blksize_x; x0++) { refx = xpos_plusoffset + ( x0 << 2 ) + cand_mv_x; refy = ypos_plusoffset + ( y0 << 2 ) + cand_mv_y; Flag_IREG = AffectedByLeftover(refx, refy, ref); if ( Flag_IREG ) { break; } } if ( Flag_IREG ) { break; } } if ( Flag_IREG ) { continue; } if(Flag_IREG==0)iSubPixFlag=1; }//if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) }//if (input->IREGEnable) #endif // _ISOLATED_REGION_ //----- set motion vector cost ----- mcost = MV_COST (lambda_factor, pgMbData->Spiral_index [pos][0] + sInter_MV[blkindex][0][0] - sResidual_MV[0], //qwang 2004-3-21 sInter_MV[blkindex][0] pgMbData->Spiral_index [pos][1] + sInter_MV[blkindex][0][1] - sResidual_MV[1]); //qwang 2004-3-21 sInter_MV[blkindex][1] if(!input.hadamard) { //----- add up SAD ----- for (y0 = 0; y0 < blksize_y; y0++) { oriy = yoff + y0; refy = QUARTER_CENTER_OFFSET + (y0<<2) + cand_mv_y; for (x0 = 0; x0 < blksize_x; x0+=4) { orix = xoff + x0; refx = QUARTER_CENTER_OFFSET + (x0<<2) + cand_mv_x; for(i = 0 ; i < 4 ; i ++) { y_pos = ypos+ QUARTER_CENTER_OFFSET+(y0 << 2) + cand_mv_y + (PAD_SIZE<<2); x_pos = xpos+ QUARTER_CENTER_OFFSET+(x0 << 2) + (i<<2) + cand_mv_x + (PAD_SIZE<<2); x_pos = (x_pos < 0) ? (x_pos & 3) : (x_pos > width4 ) ? (width4 + (x_pos & 3)) : x_pos; y_pos = (y_pos < 0) ? (y_pos & 3) : (y_pos > height4) ? (height4 + (y_pos & 3)) : y_pos; mcost += absm(pgMbData->org_luma[oriy][orix + i] - reference_quater_pel_frame[ref][y_pos][x_pos]); } } } }else { for (y0 = 0; y0 < blksize_y; y0+=4) { oriy = yoff + y0; refy = QUARTER_CENTER_OFFSET + (y0<<2) + cand_mv_y; for (x0 = 0; x0 < blksize_x; x0+=4) { orix = xoff + x0; refx = QUARTER_CENTER_OFFSET + (x0<<2) + cand_mv_x; for(j=0; j<4;j++) for(i=0; i<4;i++) { y_pos = ypos+ QUARTER_CENTER_OFFSET+(y0 << 2) + (j<<2) + cand_mv_y + (PAD_SIZE<<2); x_pos = xpos+ QUARTER_CENTER_OFFSET+(x0 << 2) + (i<<2) + cand_mv_x + (PAD_SIZE<<2); x_pos = (x_pos < 0) ? (x_pos & 3) : (x_pos > width4 ) ? (width4 + (x_pos & 3)) : x_pos; y_pos = (y_pos < 0) ? (y_pos & 3) : (y_pos > height4) ? (height4 + (y_pos & 3)) : y_pos; diff[j*4+i] = pgMbData->org_luma[oriy+j][orix+i] - reference_quater_pel_frame[ref][y_pos][x_pos]; } mcost += SATD(diff); } } } if (mcost < min_mcost) { min_mcost = mcost; best_pos = pos; } } //cbzhu 12-15 #ifdef _ISOLATED_REGION_ if (input.IREGEnable) { if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) { if (iSubPixFlag == 0 && Flag_IREG == 1) { iSubPixFlag1 = 1; return (1 << 30); } } } #endif // _ISOLATED_REGION_ if (best_pos) { sInter_MV[blkindex][subblkindex][0] += pgMbData->Spiral_index [best_pos][0]; //qwang 2004-3-21 sInter_MV[blkindex][0] sInter_MV[blkindex][subblkindex][1] += pgMbData->Spiral_index [best_pos][1]; //qwang 2004-3-21 sInter_MV[blkindex][1] } } //===== return minimum motion cost ===== return min_mcost; } /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + function name : Full_Pel_Block_Motion_Search + parameters : void + return : cost of the current block + descriptions : created by jhzheng: 2004/02/26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int // ==> minimum motion cost after search // qwang 2004-3-22 Full_Integer_Pel_Block_Motion_Search ( int ref, int offx, int off_y, int blkindex, int blktype, // <-- block type (1-16x16 ... 4-8x8) int subblkindex, int subblktype, int min_mcost, // <-- minimum motion cost (cost for center or huge value) int lambda_factor, // <-- factor for determining lagragian motion cost int ypos, int xpos ) { int pos, cand_x, cand_y, mcost, best_pos; int blksize_y; // vertical block size int blksize_x; // horizontal block size //cbzhu 12-15 #ifdef _ISOLATED_REGION_ int refx, refy; int Flag_IREG=0; int x, y; #endif // _ISOLATED_REGION_ if(blktype == 4) { blksize_y = (csiInter_Subblk_Size[subblktype - 1][1]); // vertical block size blksize_x = (csiInter_Subblk_Size[subblktype - 1][0]); // horizontal block size } else { blksize_y = (csiInter_Block_Size[blktype - 1][1]); // vertical block size blksize_x = (csiInter_Block_Size[blktype - 1][0]); // horizontal block size } //int max_pos = SPIRALRANGE; //cbzhu 12-15 #ifdef _ISOLATED_REGION_ if (input.IREGEnable) { if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) { iIntegerPixFlag = 0; } else iIntegerPixFlag=1; } #endif // _ISOLATED_REGION_ //===== loop over all search positions ===== for (pos = 0; pos < SPIRALRANGE; pos ++) { //--- set candidate position (absolute position in pel units) --- cand_x = offx + pgMbData->Spiral_index [pos][0]; cand_y = off_y + pgMbData->Spiral_index [pos][1]; //cbzhu 12-15 #ifdef _ISOLATED_REGION_ if (input.IREGEnable) { if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) { Flag_IREG = 0; for (y = 0; y < blksize_y; y++) { for (x = 0; x < blksize_x; x++) { refx = (max(0, min(pgImage->img_width - 1, xpos + x + cand_x))); refy = (max(0, min(pgImage->img_height - 1, ypos + y + cand_y))); Flag_IREG = (IREGMap[ref][refy>>4][refx>>4] == 0);//not in iREG , flag=1 if ( Flag_IREG ) { break; } } if ( Flag_IREG ) { break; } } if ( Flag_IREG ) { continue; } } if(Flag_IREG==0)iIntegerPixFlag=1; }//if (input->IREGEnable) #endif // _ISOLATED_REGION_ //--- initialize motion cost (cost for motion vector) and check --- if ( pgImage->half_pixel_mv_flag == 0 ) // 1/4-PIXEL ME { mcost = MV_COST (lambda_factor, ((cand_x<<2) - (sResidual_MV[0])), // for 1/4 pixel ME ((cand_y<<2) - (sResidual_MV[1]))); } else { mcost = MV_COST (lambda_factor, ( (cand_x<<2) - (sResidual_MV[0])) >>1, // for 1/2 pixel ME ((cand_y<<2) - (sResidual_MV[1])) >> 1); } if (blktype == 1 && (cand_x == (offx - sInteger_MV[0])) && (cand_y == (off_y - sInteger_MV[1]))) { mcost -= WEIGHTED_COST (lambda_factor, 16); } if (mcost >= min_mcost) continue; mcost = CalIntegerPixSAD(ref,blkindex,subblkindex,blksize_x,blksize_y, cand_x,cand_y,mcost,min_mcost, ypos, xpos); //--- check if motion cost is less than minimum cost --- if (mcost < min_mcost) { best_pos = pos; min_mcost = mcost; } } //cbzhu 12-15 #ifdef _ISOLATED_REGION_ if (input.IREGEnable) { //can't find suitable mv or can't use mv if (pCurrFrmIREGMap[pgImage->mb_y][pgImage->mb_x] != 0) { if (iIntegerPixFlag == 0) { return 1<<20; } } } #endif // _ISOLATED_REGION_ //===== set best motion vector and return minimum motion cost ===== if (best_pos) { sInter_MV[blkindex][subblkindex][0] = (pgMbData->Spiral_index[best_pos][0] << 2); //qwang 2004-3-20 sInter_MV[blkindex][0] sInter_MV[blkindex][subblkindex][1] = (pgMbData->Spiral_index[best_pos][1] << 2); //qwang 2004-3-20 sInter_MV[blkindex][1] } else { sInter_MV[blkindex][subblkindex][0] = sInter_MV[blkindex][subblkindex][1] = 0; //qwang 2004-3-20 sInter_MV[blkindex][1] } return min_mcost; }