mot_est_comp.c
来自「实现在linux下的mpeg4编解码」· C语言 代码 · 共 643 行 · 第 1/2 页
C
643 行
/* Do motion estimation and store result in array */ halfpelflags=(SInt*)malloc(5*4*sizeof(SInt)); /* halfpelflags=(SInt*)malloc(9*4*sizeof(SInt)); */ sad = 0; for ( j=0; j< (br_height/MB_SIZE); j++) { hint_mv_w = hint_mv_h = 0.f; for ( i=0; i< (br_width/MB_SIZE); i++) { /* Integer pel search */ Int min_error; posmode = j * imas_w + i; pos16 = pos8 = 2*j*2*imas_w + 2*i; MBMotionEstimation(curr, prev, br_x, br_y, br_width, i, j, prev_x, prev_y, vop_width, vop_height, enable_8x8_mv, edge, f_code, sr_for, hint_mv_w, hint_mv_h, // the hint seeds mv16_w, mv16_h, mv8_w, mv8_h, &min_error, halfpelflags); /* Inter/Intra decision */ Mode = ChooseMode(curr, i*MB_SIZE,j*MB_SIZE, min_error, br_width); hint_mv_w = mv16_w[pos16]; hint_mv_h = mv16_h[pos16]; LoadArea(curr, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, (SInt *)curr_mb); /* 0==MBM_INTRA,1==MBM_INTER16||MBM_INTER8 */ if ( Mode != 0) { FindSubPel (i*MB_SIZE,j*MB_SIZE, prev_ipol, &curr_mb[0][0], 16, 16 , 0, br_x-prev_x,br_y-prev_y,vop_width, vop_height, edge, halfpelflags, &curr_comp_mb_16[0][0], &mv16_w[pos16], &mv16_h[pos16], &min_error16); /* sad16(0,0) already decreased by Nb/2+1 in FindHalfPel() */ sad16 = min_error16; mode16[posmode] = MBM_INTER16; if (enable_8x8_mv) { xsum = 0; ysum = 0; FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol, &curr_mb[0][0], 8, 8 , 0, br_x-prev_x,br_y-prev_y, vop_width, vop_height, edge, halfpelflags, &curr_comp_mb_8[0][0], &mv8_w[pos8], &mv8_h[pos8], &min_error8_0); xsum += (Int)(2*(mv8_w[pos8])); ysum += (Int)(2*(mv8_h[pos8])); FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol, &curr_mb[0][8], 8, 8 , 1, br_x-prev_x,br_y-prev_y, vop_width,vop_height, edge, halfpelflags, &curr_comp_mb_8[0][8], &mv8_w[pos8+1], &mv8_h[pos8+1], &min_error8_1); xsum += (Int)(2*(mv8_w[pos8+1])); ysum += (Int)(2*(mv8_h[pos8+1])); pos8+=2*imas_w; FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol, &curr_mb[8][0], 8, 8 , 2, br_x-prev_x,br_y-prev_y, vop_width,vop_height, edge, halfpelflags, &curr_comp_mb_8[8][0], &mv8_w[pos8], &mv8_h[pos8], &min_error8_2); xsum += (Int)(2*(mv8_w[pos8])); ysum += (Int)(2*(mv8_h[pos8])); FindSubPel(i*MB_SIZE, j*MB_SIZE, prev_ipol, &curr_mb[8][8], 8, 8 , 3, br_x-prev_x,br_y-prev_y, vop_width,vop_height, edge, halfpelflags, &curr_comp_mb_8[8][8], &mv8_w[pos8+1], &mv8_h[pos8+1], &min_error8_3); xsum += (Int)(2*(mv8_w[pos8+1])); ysum += (Int)(2*(mv8_h[pos8+1])); sad8 = min_error8_0+min_error8_1+min_error8_2+min_error8_3; /* Choose 8x8 or 16x16 vectors */ if (sad8 < (sad16 -(128+1))) mode16[posmode] = MBM_INTER8; } /* end of enable_8x8_mv mode */ /* When choose 16x16 vectors */ /* sad16(0,0) was decreased by MB_Nb, now add it back */ if ((mv16_w[pos16]==0.0) && (mv16_h[pos16]==0.0) && (mode16[posmode]==MBM_INTER16)) sad16 += 128+1; /* calculate motion vectors for chroma compensation */ if(mode16[posmode] == MBM_INTER8) { dx = SIGN (xsum) * (roundtab16[ABS (xsum) % 16] + (ABS (xsum) / 16) * 2); dy = SIGN (ysum) * (roundtab16[ABS (ysum) % 16] + (ABS (ysum) / 16) * 2); sad += sad8; } else /* mode == MBM_INTER16 */ { dx = (Int)(2 * mv16_w[pos16]); dy = (Int)(2 * mv16_h[pos16]); dx = ( dx % 4 == 0 ? dx >> 1 : (dx>>1)|1 ); dy = ( dy % 4 == 0 ? dy >> 1 : (dy>>1)|1 ); sad += sad16; } GetPred_Chroma (i*MB_SIZE, j*MB_SIZE, dx, dy, prev_u, prev_v, curr_comp_u, curr_comp_v, br_width, vop_width, prev_x_min/4,prev_y_min/4,prev_x_max/4,prev_y_max/4, rounding_type); } /* end of mode non zero */ else /* mode = 0 INTRA */ { mode16[posmode] = MBM_INTRA; for (k = 0; k < MB_SIZE*MB_SIZE; k++) { // for INTRA MB, set compensated 0 to generate correct error image curr_comp_mb_16[k/MB_SIZE][k%MB_SIZE] = 0; // for INTRA_MB, SAD is recalculated from image instead of using min_error sad += curr_mb[k/MB_SIZE][k%MB_SIZE]; } } if (mode16[posmode] == MBM_INTER8) SetArea((SInt*)curr_comp_mb_8, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, curr_comp_y); else SetArea((SInt*)curr_comp_mb_16, i*MB_SIZE, j*MB_SIZE, 16, 16, br_width, curr_comp_y); } /* end of i loop */ } /* end of j loop */ *mad = (float)sad/(br_width*br_height); free((Char*)halfpelflags); return;}/***********************************************************CommentBegin****** * * unrestricted_MC_chro * * Purpose : * To make unrestricted MC * ***********************************************************CommentEnd********//*Int unrestricted_MC_chro(Int x,Int y, Int npix, Int prev_x_min,Int prev_y_min, Int prev_x_max, Int prev_y_max){ if (x < prev_x_min) x = prev_x_min; else if (x >=prev_x_max) x = prev_x_max-1; if (y < prev_y_min) y = prev_y_min; else if (y >=prev_y_max) y = prev_y_max-1; return(x+y*npix);}*/#define unrestricted_MC_chro(x,y,npix,prev_x_min,prev_y_min,prev_x_max,prev_y_max) ((x)+(y)*(npix))/***********************************************************CommentBegin****** * * -- GetPred_Chroma -- Predicts chrominance macroblock * * Purpose : * Does the chrominance prediction for P-frames * * Arguments in : * current position in image, * motionvectors, * pointers to compensated and previous Vops, * width of the compensated Vop * width of the previous/reference Vop * ***********************************************************CommentEnd********/Void GetPred_Chroma ( Int x_curr, Int y_curr, Int dx, Int dy, SInt *prev_u, SInt *prev_v, SInt *comp_u, SInt *comp_v, Int width, Int width_prev, Int prev_x_min, Int prev_y_min, Int prev_x_max, Int prev_y_max, Int rounding_control){ Int m,n; Int x, y, ofx, ofy, lx; Int xint, yint; Int xh, yh; Int index1,index2,index3,index4; lx = width_prev/2; x = x_curr>>1; y = y_curr>>1; xint = dx>>1; xh = dx & 1; yint = dy>>1; yh = dy & 1; if (!xh && !yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min, prev_y_min,prev_x_max,prev_y_max); comp_u[(y+n)*width/2+x+m] = *(prev_u+index1); comp_v[(y+n)*width/2+x+m] = *(prev_v+index1); } } } else if (!xh && yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min, prev_y_min,prev_x_max,prev_y_max); index2 = unrestricted_MC_chro(ofx,ofy+yh,lx,prev_x_min, prev_y_min,prev_x_max,prev_y_max); comp_u[(y+n)*width/2+x+m] = (*(prev_u+index1) + *(prev_u+index2) + 1- rounding_control)>>1; comp_v[(y+n)*width/2+x+m] = (*(prev_v+index1) + *(prev_v+index2) + 1- rounding_control)>>1; } } } else if (xh && !yh) { for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min, prev_y_min,prev_x_max,prev_y_max); index2 = unrestricted_MC_chro(ofx+xh,ofy,lx,prev_x_min, prev_y_min,prev_x_max,prev_y_max); comp_u[(y+n)*width/2+x+m] = (*(prev_u+index1) + *(prev_u+index2) + 1- rounding_control)>>1; comp_v[(y+n)*width/2+x+m] = (*(prev_v+index1) + *(prev_v+index2) + 1- rounding_control)>>1; } } } else { /* xh && yh */ for (n = 0; n < 8; n++) { for (m = 0; m < 8; m++) { ofx = x + xint + m; ofy = y + yint + n; index1 = unrestricted_MC_chro(ofx,ofy,lx,prev_x_min, prev_y_min,prev_x_max,prev_y_max); index2 = unrestricted_MC_chro(ofx+xh,ofy,lx,prev_x_min, prev_y_min,prev_x_max,prev_y_max); index3 = unrestricted_MC_chro(ofx,ofy+yh,lx,prev_x_min, prev_y_min,prev_x_max,prev_y_max); index4 = unrestricted_MC_chro(ofx+xh,ofy+yh,lx,prev_x_min, prev_y_min,prev_x_max,prev_y_max); comp_u[(y+n)*width/2+x+m] = (*(prev_u+index1)+ *(prev_u+index2)+ *(prev_u+index3)+ *(prev_u+index4)+ 2- rounding_control)>>2; comp_v[(y+n)*width/2+x+m] = (*(prev_v+index1)+ *(prev_v+index2)+ *(prev_v+index3)+ *(prev_v+index4)+ 2- rounding_control)>>2; } } } return;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?