📄 motion_est_template.c
字号:
for(i=0; i<minima_count; i++){ const int x= minima[i].x; const int y= minima[i].y; int d; if(minima[i].checked) continue; if( x >= xmax || x <= xmin || y >= ymax || y <= ymin) continue; SAB_CHECK_MV(x-1, y) SAB_CHECK_MV(x+1, y) SAB_CHECK_MV(x , y-1) SAB_CHECK_MV(x , y+1) minima[i].checked= 1; } best[0]= minima[0].x; best[1]= minima[0].y; dmin= minima[0].height; if( best[0] < xmax && best[0] > xmin && best[1] < ymax && best[1] > ymin){ int d; //ensure that the refernece samples for hpel refinement are in the map CHECK_MV(best[0]-1, best[1]) CHECK_MV(best[0]+1, best[1]) CHECK_MV(best[0], best[1]-1) CHECK_MV(best[0], best[1]+1) } return dmin; }static inline int RENAME(var_diamond_search)(MpegEncContext * s, int *best, int dmin, uint8_t *src_data[3], uint8_t *ref_data[3], int stride, int uvstride, int const pred_x, int const pred_y, int const penalty_factor, int const shift, uint32_t *map, int map_generation, int size, int h, uint8_t * const mv_penalty ){ me_cmp_func cmp, chroma_cmp; int dia_size; LOAD_COMMON cmp= s->dsp.me_cmp[size]; chroma_cmp= s->dsp.me_cmp[size+1]; for(dia_size=1; dia_size<=s->me.dia_size; dia_size++){ int dir, start, end; const int x= best[0]; const int y= best[1]; start= FFMAX(0, y + dia_size - ymax); end = FFMIN(dia_size, xmax - x + 1); for(dir= start; dir<end; dir++){ int d;//check(x + dir,y + dia_size - dir,0, a0) CHECK_MV(x + dir , y + dia_size - dir); } start= FFMAX(0, x + dia_size - xmax); end = FFMIN(dia_size, y - ymin + 1); for(dir= start; dir<end; dir++){ int d;//check(x + dia_size - dir, y - dir,0, a1) CHECK_MV(x + dia_size - dir, y - dir ); } start= FFMAX(0, -y + dia_size + ymin ); end = FFMIN(dia_size, x - xmin + 1); for(dir= start; dir<end; dir++){ int d;//check(x - dir,y - dia_size + dir,0, a2) CHECK_MV(x - dir , y - dia_size + dir); } start= FFMAX(0, -x + dia_size + xmin ); end = FFMIN(dia_size, ymax - y + 1); for(dir= start; dir<end; dir++){ int d;//check(x - dia_size + dir, y + dir,0, a3) CHECK_MV(x - dia_size + dir, y + dir ); } if(x!=best[0] || y!=best[1]) dia_size=0;#if 0{int dx, dy, i;static int stats[8*8];dx= ABS(x-best[0]);dy= ABS(y-best[1]);stats[dy*8 + dx] ++;if(256*256*256*64 % (stats[0]+1)==0){ for(i=0; i<64; i++){ if((i&7)==0) printf("\n"); printf("%6d ", stats[i]); } printf("\n");}}#endif } return dmin; }static int RENAME(epzs_motion_search)(MpegEncContext * s, int *mx_ptr, int *my_ptr, int P[10][2], int pred_x, int pred_y, uint8_t *src_data[3], uint8_t *ref_data[3], int stride, int uvstride, int16_t (*last_mv)[2], int ref_mv_scale, uint8_t * const mv_penalty){ int best[2]={0, 0}; int d, dmin; const int shift= 1+s->quarter_sample; uint32_t *map= s->me.map; int map_generation; const int penalty_factor= s->me.penalty_factor; const int size=0; const int h=16; const int ref_mv_stride= s->mb_stride; //pass as arg FIXME const int ref_mv_xy= s->mb_x + s->mb_y*ref_mv_stride; //add to last_mv beforepassing FIXME me_cmp_func cmp, chroma_cmp; LOAD_COMMON cmp= s->dsp.me_cmp[size]; chroma_cmp= s->dsp.me_cmp[size+1]; map_generation= update_map_generation(s); CMP(dmin, 0, 0, size); map[0]= map_generation; score_map[0]= dmin; /* first line */ if (s->first_slice_line) { CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) }else{ if(dmin<256 && ( P_LEFT[0] |P_LEFT[1] |P_TOP[0] |P_TOP[1] |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){ *mx_ptr= 0; *my_ptr= 0; s->me.skip=1; return dmin; } CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) if(dmin>256*2){ CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) CHECK_MV(P_LEFT[0] >>shift, P_LEFT[1] >>shift) CHECK_MV(P_TOP[0] >>shift, P_TOP[1] >>shift) CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) } } if(dmin>256*4){ if(s->me.pre_pass){ CHECK_CLIPED_MV((last_mv[ref_mv_xy-1][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16) if(!s->first_slice_line) CHECK_CLIPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) }else{ CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) if(s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) } } if(s->avctx->last_predictor_count){ const int count= s->avctx->last_predictor_count; const int xstart= FFMAX(0, s->mb_x - count); const int ystart= FFMAX(0, s->mb_y - count); const int xend= FFMIN(s->mb_width , s->mb_x + count + 1); const int yend= FFMIN(s->mb_height, s->mb_y + count + 1); int mb_y; for(mb_y=ystart; mb_y<yend; mb_y++){ int mb_x; for(mb_x=xstart; mb_x<xend; mb_x++){ const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride; int mx= (last_mv[xy][0]*ref_mv_scale + (1<<15))>>16; int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16; if(mx>xmax || mx<xmin || my>ymax || my<ymin) continue; CHECK_MV(mx,my) } } }//check(best[0],best[1],0, b0) if(s->me.dia_size==-1) dmin= RENAME(funny_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else if(s->me.dia_size<-1) dmin= RENAME(sab_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else if(s->me.dia_size<2) dmin= RENAME(small_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else dmin= RENAME(var_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty);//check(best[0],best[1],0, b1) *mx_ptr= best[0]; *my_ptr= best[1]; // printf("%d %d %d \n", best[0], best[1], dmin); return dmin;}#ifndef CMP_DIRECT /* no 4mv search needed in direct mode */static int RENAME(epzs_motion_search4)(MpegEncContext * s, int *mx_ptr, int *my_ptr, int P[10][2], int pred_x, int pred_y, uint8_t *src_data[3], uint8_t *ref_data[3], int stride, int uvstride, int16_t (*last_mv)[2], int ref_mv_scale, uint8_t * const mv_penalty){ int best[2]={0, 0}; int d, dmin; const int shift= 1+s->quarter_sample; uint32_t *map= s->me.map; int map_generation; const int penalty_factor= s->me.penalty_factor; const int size=1; const int h=8; const int ref_mv_stride= s->mb_stride; const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride; me_cmp_func cmp, chroma_cmp; LOAD_COMMON cmp= s->dsp.me_cmp[size]; chroma_cmp= s->dsp.me_cmp[size+1]; map_generation= update_map_generation(s); dmin = 1000000;//printf("%d %d %d %d //",xmin, ymin, xmax, ymax); /* first line */ if (s->first_slice_line) { CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) }else{ CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) //FIXME try some early stop if(dmin>64*2){ CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift) CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) } } if(dmin>64*4){ CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) if(s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) } if(s->me.dia_size==-1) dmin= RENAME(funny_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else if(s->me.dia_size<-1) dmin= RENAME(sab_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else if(s->me.dia_size<2) dmin= RENAME(small_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else dmin= RENAME(var_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); *mx_ptr= best[0]; *my_ptr= best[1]; // printf("%d %d %d \n", best[0], best[1], dmin); return dmin;}//try to merge with above FIXME (needs PSNR test)static int RENAME(epzs_motion_search2)(MpegEncContext * s, int *mx_ptr, int *my_ptr, int P[10][2], int pred_x, int pred_y, uint8_t *src_data[3], uint8_t *ref_data[3], int stride, int uvstride, int16_t (*last_mv)[2], int ref_mv_scale, uint8_t * const mv_penalty){ int best[2]={0, 0}; int d, dmin; const int shift= 1+s->quarter_sample; uint32_t *map= s->me.map; int map_generation; const int penalty_factor= s->me.penalty_factor; const int size=0; //FIXME pass as arg const int h=8; const int ref_mv_stride= s->mb_stride; const int ref_mv_xy= s->mb_x + s->mb_y *ref_mv_stride; me_cmp_func cmp, chroma_cmp; LOAD_COMMON cmp= s->dsp.me_cmp[size]; chroma_cmp= s->dsp.me_cmp[size+1]; map_generation= update_map_generation(s); dmin = 1000000;//printf("%d %d %d %d //",xmin, ymin, xmax, ymax); /* first line */ if (s->first_slice_line) { CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) }else{ CHECK_MV(P_MV1[0]>>shift, P_MV1[1]>>shift) //FIXME try some early stop if(dmin>64*2){ CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift) CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift) CHECK_MV(P_TOP[0]>>shift, P_TOP[1]>>shift) CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift) CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16) } } if(dmin>64*4){ CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16) if(s->mb_y+1<s->end_mb_y) //FIXME replace at least with last_slice_line CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16, (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16) } if(s->me.dia_size==-1) dmin= RENAME(funny_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else if(s->me.dia_size<-1) dmin= RENAME(sab_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else if(s->me.dia_size<2) dmin= RENAME(small_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); else dmin= RENAME(var_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride, pred_x, pred_y, penalty_factor, shift, map, map_generation, size, h, mv_penalty); *mx_ptr= best[0]; *my_ptr= best[1]; // printf("%d %d %d \n", best[0], best[1], dmin); return dmin;}#endif /* !CMP_DIRECT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -