📄 motion_est.c
字号:
*my_ptr = 16 * s->mb_y;}static int full_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, int range, int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture){ int x1, y1, x2, y2, xx, yy, x, y; int mx, my, dmin, d; uint8_t *pix; xx = 16 * s->mb_x; yy = 16 * s->mb_y; x1 = xx - range + 1; /* we loose one pixel to avoid boundary pb with half pixel pred */ if (x1 < xmin) x1 = xmin; x2 = xx + range - 1; if (x2 > xmax) x2 = xmax; y1 = yy - range + 1; if (y1 < ymin) y1 = ymin; y2 = yy + range - 1; if (y2 > ymax) y2 = ymax; pix = s->new_picture.data[0] + (yy * s->linesize) + xx; dmin = 0x7fffffff; mx = 0; my = 0; for (y = y1; y <= y2; y++) { for (x = x1; x <= x2; x++) { d = s->dsp.pix_abs16x16(pix, ref_picture + (y * s->linesize) + x, s->linesize); if (d < dmin || (d == dmin && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { dmin = d; mx = x; my = y; } } } *mx_ptr = mx; *my_ptr = my;#if 0 if (*mx_ptr < -(2 * range) || *mx_ptr >= (2 * range) || *my_ptr < -(2 * range) || *my_ptr >= (2 * range)) { fprintf(stderr, "error %d %d\n", *mx_ptr, *my_ptr); }#endif return dmin;}static int log_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, int range, int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture){ int x1, y1, x2, y2, xx, yy, x, y; int mx, my, dmin, d; uint8_t *pix; xx = s->mb_x << 4; yy = s->mb_y << 4; /* Left limit */ x1 = xx - range; if (x1 < xmin) x1 = xmin; /* Right limit */ x2 = xx + range; if (x2 > xmax) x2 = xmax; /* Upper limit */ y1 = yy - range; if (y1 < ymin) y1 = ymin; /* Lower limit */ y2 = yy + range; if (y2 > ymax) y2 = ymax; pix = s->new_picture.data[0] + (yy * s->linesize) + xx; dmin = 0x7fffffff; mx = 0; my = 0; do { for (y = y1; y <= y2; y += range) { for (x = x1; x <= x2; x += range) { d = s->dsp.pix_abs16x16(pix, ref_picture + (y * s->linesize) + x, s->linesize); if (d < dmin || (d == dmin && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { dmin = d; mx = x; my = y; } } } range = range >> 1; x1 = mx - range; if (x1 < xmin) x1 = xmin; x2 = mx + range; if (x2 > xmax) x2 = xmax; y1 = my - range; if (y1 < ymin) y1 = ymin; y2 = my + range; if (y2 > ymax) y2 = ymax; } while (range >= 1);#ifdef DEBUG fprintf(stderr, "log - MX: %d\tMY: %d\n", mx, my);#endif *mx_ptr = mx; *my_ptr = my; return dmin;}static int phods_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, int range, int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture){ int x1, y1, x2, y2, xx, yy, x, y, lastx, d; int mx, my, dminx, dminy; uint8_t *pix; xx = s->mb_x << 4; yy = s->mb_y << 4; /* Left limit */ x1 = xx - range; if (x1 < xmin) x1 = xmin; /* Right limit */ x2 = xx + range; if (x2 > xmax) x2 = xmax; /* Upper limit */ y1 = yy - range; if (y1 < ymin) y1 = ymin; /* Lower limit */ y2 = yy + range; if (y2 > ymax) y2 = ymax; pix = s->new_picture.data[0] + (yy * s->linesize) + xx; mx = 0; my = 0; x = xx; y = yy; do { dminx = 0x7fffffff; dminy = 0x7fffffff; lastx = x; for (x = x1; x <= x2; x += range) { d = s->dsp.pix_abs16x16(pix, ref_picture + (y * s->linesize) + x, s->linesize); if (d < dminx || (d == dminx && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { dminx = d; mx = x; } } x = lastx; for (y = y1; y <= y2; y += range) { d = s->dsp.pix_abs16x16(pix, ref_picture + (y * s->linesize) + x, s->linesize); if (d < dminy || (d == dminy && (abs(x - xx) + abs(y - yy)) < (abs(mx - xx) + abs(my - yy)))) { dminy = d; my = y; } } range = range >> 1; x = mx; y = my; x1 = mx - range; if (x1 < xmin) x1 = xmin; x2 = mx + range; if (x2 > xmax) x2 = xmax; y1 = my - range; if (y1 < ymin) y1 = ymin; y2 = my + range; if (y2 > ymax) y2 = ymax; } while (range >= 1);#ifdef DEBUG fprintf(stderr, "phods - MX: %d\tMY: %d\n", mx, my);#endif /* half pixel search */ *mx_ptr = mx; *my_ptr = my; return dminy;}#define Z_THRESHOLD 256#define CHECK_SAD_HALF_MV(suffix, x, y) \{\ d= pix_abs_ ## suffix(pix, ptr+((x)>>1), s->linesize);\ d += (mv_penalty[pen_x + x] + mv_penalty[pen_y + y])*penalty_factor;\ COPY3_IF_LT(dminh, d, dx, x, dy, y)\}static inline int sad_hpel_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr, int dmin, int xmin, int ymin, int xmax, int ymax, int pred_x, int pred_y, Picture *picture, int n, int size, uint8_t * const mv_penalty){ uint8_t *ref_picture= picture->data[0]; uint32_t *score_map= s->me.score_map; const int penalty_factor= s->me.sub_penalty_factor; int mx, my, xx, yy, dminh; uint8_t *pix, *ptr; op_pixels_abs_func pix_abs_x2; op_pixels_abs_func pix_abs_y2; op_pixels_abs_func pix_abs_xy2; if(size==0){ pix_abs_x2 = s->dsp.pix_abs16x16_x2; pix_abs_y2 = s->dsp.pix_abs16x16_y2; pix_abs_xy2= s->dsp.pix_abs16x16_xy2; }else{ pix_abs_x2 = s->dsp.pix_abs8x8_x2; pix_abs_y2 = s->dsp.pix_abs8x8_y2; pix_abs_xy2= s->dsp.pix_abs8x8_xy2; } if(s->me.skip){// printf("S"); *mx_ptr = 0; *my_ptr = 0; return dmin; }// printf("N"); xx = 16 * s->mb_x + 8*(n&1); yy = 16 * s->mb_y + 8*(n>>1); pix = s->new_picture.data[0] + (yy * s->linesize) + xx; mx = *mx_ptr; my = *my_ptr; ptr = ref_picture + ((yy + my) * s->linesize) + (xx + mx); dminh = dmin; if (mx > xmin && mx < xmax && my > ymin && my < ymax) { int dx=0, dy=0; int d, pen_x, pen_y; const int index= (my<<ME_MAP_SHIFT) + mx; const int t= score_map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]; const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)]; const int r= score_map[(index+ 1 )&(ME_MAP_SIZE-1)]; const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]; mx<<=1; my<<=1; pen_x= pred_x + mx; pen_y= pred_y + my; ptr-= s->linesize; if(t<=b){ CHECK_SAD_HALF_MV(y2 , 0, -1) if(l<=r){ CHECK_SAD_HALF_MV(xy2, -1, -1) if(t+r<=b+l){ CHECK_SAD_HALF_MV(xy2, +1, -1) ptr+= s->linesize; }else{ ptr+= s->linesize; CHECK_SAD_HALF_MV(xy2, -1, +1) } CHECK_SAD_HALF_MV(x2 , -1, 0) }else{ CHECK_SAD_HALF_MV(xy2, +1, -1) if(t+l<=b+r){ CHECK_SAD_HALF_MV(xy2, -1, -1) ptr+= s->linesize; }else{ ptr+= s->linesize; CHECK_SAD_HALF_MV(xy2, +1, +1) } CHECK_SAD_HALF_MV(x2 , +1, 0) } }else{ if(l<=r){ if(t+l<=b+r){ CHECK_SAD_HALF_MV(xy2, -1, -1) ptr+= s->linesize; }else{ ptr+= s->linesize; CHECK_SAD_HALF_MV(xy2, +1, +1) } CHECK_SAD_HALF_MV(x2 , -1, 0) CHECK_SAD_HALF_MV(xy2, -1, +1) }else{ if(t+r<=b+l){ CHECK_SAD_HALF_MV(xy2, +1, -1) ptr+= s->linesize; }else{ ptr+= s->linesize; CHECK_SAD_HALF_MV(xy2, -1, +1) } CHECK_SAD_HALF_MV(x2 , +1, 0) CHECK_SAD_HALF_MV(xy2, +1, +1) } CHECK_SAD_HALF_MV(y2 , 0, +1) } mx+=dx; my+=dy; }else{ mx<<=1; my<<=1; } *mx_ptr = mx; *my_ptr = my; return dminh;}static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4){ const int xy= s->mb_x + s->mb_y*s->mb_stride; s->p_mv_table[xy][0] = mx; s->p_mv_table[xy][1] = my; /* has allready been set to the 4 MV if 4MV is done */ if(mv4){ int mot_xy= s->block_index[0]; s->motion_val[mot_xy ][0]= mx; s->motion_val[mot_xy ][1]= my; s->motion_val[mot_xy+1][0]= mx; s->motion_val[mot_xy+1][1]= my; mot_xy += s->block_wrap[0]; s->motion_val[mot_xy ][0]= mx; s->motion_val[mot_xy ][1]= my; s->motion_val[mot_xy+1][0]= mx; s->motion_val[mot_xy+1][1]= my; }}/** * get fullpel ME search limits. * @param range the approximate search range for the old ME code, unused for EPZS and newer */static inline void get_limits(MpegEncContext *s, int *range, int *xmin, int *ymin, int *xmax, int *ymax){ if(s->avctx->me_range) *range= s->avctx->me_range >> 1; else *range= 16; if (s->unrestricted_mv) { *xmin = -16; *ymin = -16; *xmax = s->mb_width*16; *ymax = s->mb_height*16; } else { *xmin = 0; *ymin = 0; *xmax = s->mb_width*16 - 16; *ymax = s->mb_height*16 - 16; } //FIXME try to limit x/y min/max if me_range is set}static inline int h263_mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, int ymax, int mx, int my, int shift){ int block; int P[10][2]; int dmin_sum=0, mx4_sum=0, my4_sum=0; uint8_t * const mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; int same=1; for(block=0; block<4; block++){ int mx4, my4; int pred_x4, pred_y4; int dmin4; static const int off[4]= {2, 1, 1, -1}; const int mot_stride = s->block_wrap[0]; const int mot_xy = s->block_index[block];// const int block_x= (block&1);// const int block_y= (block>>1);#if 1 // this saves us a bit of cliping work and shouldnt affect compression in a negative way const int rel_xmin4= xmin; const int rel_xmax4= xmax; const int rel_ymin4= ymin; const int rel_ymax4= ymax;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -