📄 motion_est_template.c
字号:
if(map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)] == (my<<ME_MAP_MV_BITS) + mx + map_generation && 0){ //FIXME tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)]; }else{ tl= cmp(s, mx-1, my-1, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);//FIXME wrong if chroma me is different } cxy= 2*tl + (cx + cy)/4 - (cx2 + cy2) - 2*c; assert(16*cx2 + 4*cx + 32*c == 32*r); assert(16*cx2 - 4*cx + 32*c == 32*l); assert(16*cy2 + 4*cy + 32*c == 32*b); assert(16*cy2 - 4*cy + 32*c == 32*t); assert(16*cxy + 16*cy2 + 16*cx2 - 4*cy - 4*cx + 32*c == 32*tl); for(ny= -3; ny <= 3; ny++){ for(nx= -3; nx <= 3; nx++){ //FIXME this could overflow (unlikely though) int score= ny*nx*cxy + nx*nx*cx2 + ny*ny*cy2 + nx*cx + ny*cy + 32*c; //FIXME factor int i; if((nx&3)==0 && (ny&3)==0) continue; score += 32*(mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor;// if(nx&1) score-=32*c->penalty_factor; // if(ny&1) score-=32*c->penalty_factor; for(i=0; i<8; i++){ if(score < best[i]){ memmove(&best[i+1], &best[i], sizeof(int)*(7-i)); memmove(&best_pos[i+1][0], &best_pos[i][0], sizeof(int)*2*(7-i)); best[i]= score; best_pos[i][0]= nx + 4*mx; best_pos[i][1]= ny + 4*my; break; } } } } } for(i=0; i<subpel_quality; i++){ nx= best_pos[i][0]; ny= best_pos[i][1]; CHECK_QUARTER_MV(nx&3, ny&3, nx>>2, ny>>2) }#if 0 const int tl= score_map[(index-(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)]; const int bl= score_map[(index+(1<<ME_MAP_SHIFT)-1)&(ME_MAP_SIZE-1)]; const int tr= score_map[(index-(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)]; const int br= score_map[(index+(1<<ME_MAP_SHIFT)+1)&(ME_MAP_SIZE-1)];// if(l < r && l < t && l < b && l < tl && l < bl && l < tr && l < br && bl < tl){ if(tl<br){// nx= FFMAX(4*mx - bx, bx - 4*mx);// ny= FFMAX(4*my - by, by - 4*my); static int stats[7][7], count; count++; stats[4*mx - bx + 3][4*my - by + 3]++; if(256*256*256*64 % count ==0){ for(i=0; i<49; i++){ if((i%7)==0) printf("\n"); printf("%6d ", stats[0][i]); } printf("\n"); } }#endif#else CHECK_QUARTER_MV(2, 2, mx-1, my-1) CHECK_QUARTER_MV(0, 2, mx , my-1) CHECK_QUARTER_MV(2, 2, mx , my-1) CHECK_QUARTER_MV(2, 0, mx , my ) CHECK_QUARTER_MV(2, 2, mx , my ) CHECK_QUARTER_MV(0, 2, mx , my ) CHECK_QUARTER_MV(2, 2, mx-1, my ) CHECK_QUARTER_MV(2, 0, mx-1, my ) nx= bx; ny= by; for(i=0; i<8; i++){ int ox[8]= {0, 1, 1, 1, 0,-1,-1,-1}; int oy[8]= {1, 1, 0,-1,-1,-1, 0, 1}; CHECK_QUARTER_MV((nx + ox[i])&3, (ny + oy[i])&3, (nx + ox[i])>>2, (ny + oy[i])>>2) }#endif#if 0 //outer ring CHECK_QUARTER_MV(1, 3, mx-1, my-1) CHECK_QUARTER_MV(1, 2, mx-1, my-1) CHECK_QUARTER_MV(1, 1, mx-1, my-1) CHECK_QUARTER_MV(2, 1, mx-1, my-1) CHECK_QUARTER_MV(3, 1, mx-1, my-1) CHECK_QUARTER_MV(0, 1, mx , my-1) CHECK_QUARTER_MV(1, 1, mx , my-1) CHECK_QUARTER_MV(2, 1, mx , my-1) CHECK_QUARTER_MV(3, 1, mx , my-1) CHECK_QUARTER_MV(3, 2, mx , my-1) CHECK_QUARTER_MV(3, 3, mx , my-1) CHECK_QUARTER_MV(3, 0, mx , my ) CHECK_QUARTER_MV(3, 1, mx , my ) CHECK_QUARTER_MV(3, 2, mx , my ) CHECK_QUARTER_MV(3, 3, mx , my ) CHECK_QUARTER_MV(2, 3, mx , my ) CHECK_QUARTER_MV(1, 3, mx , my ) CHECK_QUARTER_MV(0, 3, mx , my ) CHECK_QUARTER_MV(3, 3, mx-1, my ) CHECK_QUARTER_MV(2, 3, mx-1, my ) CHECK_QUARTER_MV(1, 3, mx-1, my ) CHECK_QUARTER_MV(1, 2, mx-1, my ) CHECK_QUARTER_MV(1, 1, mx-1, my ) CHECK_QUARTER_MV(1, 0, mx-1, my )#endif assert(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4); *mx_ptr = bx; *my_ptr = by; }else{ *mx_ptr =4*mx; *my_ptr =4*my; } return dmin;}#define CHECK_MV(x,y)\{\ const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\ const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\ assert((x) >= xmin);\ assert((x) <= xmax);\ assert((y) >= ymin);\ assert((y) <= ymax);\/*printf("check_mv %d %d\n", x, y);*/\ if(map[index]!=key){\ d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\ map[index]= key;\ score_map[index]= d;\ d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\/*printf("score:%d\n", d);*/\ COPY3_IF_LT(dmin, d, best[0], x, best[1], y)\ }\}#define CHECK_CLIPED_MV(ax,ay)\{\ const int x= ax;\ const int y= ay;\ const int x2= FFMAX(xmin, FFMIN(x, xmax));\ const int y2= FFMAX(ymin, FFMIN(y, ymax));\ CHECK_MV(x2, y2)\}#define CHECK_MV_DIR(x,y,new_dir)\{\ const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\ const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\/*printf("check_mv_dir %d %d %d\n", x, y, new_dir);*/\ if(map[index]!=key){\ d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\ map[index]= key;\ score_map[index]= d;\ d += (mv_penalty[((x)<<shift)-pred_x] + mv_penalty[((y)<<shift)-pred_y])*penalty_factor;\/*printf("score:%d\n", d);*/\ if(d<dmin){\ best[0]=x;\ best[1]=y;\ dmin=d;\ next_dir= new_dir;\ }\ }\}#define check(x,y,S,v)\if( (x)<(xmin<<(S)) ) printf("%d %d %d %d %d xmin" #v, xmin, (x), (y), s->mb_x, s->mb_y);\if( (x)>(xmax<<(S)) ) printf("%d %d %d %d %d xmax" #v, xmax, (x), (y), s->mb_x, s->mb_y);\if( (y)<(ymin<<(S)) ) printf("%d %d %d %d %d ymin" #v, ymin, (x), (y), s->mb_x, s->mb_y);\if( (y)>(ymax<<(S)) ) printf("%d %d %d %d %d ymax" #v, ymax, (x), (y), s->mb_x, s->mb_y);\#define LOAD_COMMON2\ uint32_t *map= c->map;\ const int qpel= flags&FLAG_QPEL;\ const int shift= 1+qpel;\static always_inline int small_diamond_search(MpegEncContext * s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags){ MotionEstContext * const c= &s->me; me_cmp_func cmpf, chroma_cmpf; int next_dir=-1; LOAD_COMMON LOAD_COMMON2 int map_generation= c->map_generation; cmpf= s->dsp.me_cmp[size]; chroma_cmpf= s->dsp.me_cmp[size+1]; { /* ensure that the best point is in the MAP as h/qpel refinement needs it */ const int key= (best[1]<<ME_MAP_MV_BITS) + best[0] + map_generation; const int index= ((best[1]<<ME_MAP_SHIFT) + best[0])&(ME_MAP_SIZE-1); if(map[index]!=key){ //this will be executed only very rarey score_map[index]= cmp(s, best[0], best[1], 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags); map[index]= key; } } for(;;){ int d; const int dir= next_dir; const int x= best[0]; const int y= best[1]; next_dir=-1;//printf("%d", dir); if(dir!=2 && x>xmin) CHECK_MV_DIR(x-1, y , 0) if(dir!=3 && y>ymin) CHECK_MV_DIR(x , y-1, 1) if(dir!=0 && x<xmax) CHECK_MV_DIR(x+1, y , 2) if(dir!=1 && y<ymax) CHECK_MV_DIR(x , y+1, 3) if(next_dir==-1){ return dmin; } }}static int funny_diamond_search(MpegEncContext * s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags){ MotionEstContext * const c= &s->me; me_cmp_func cmpf, chroma_cmpf; int dia_size; LOAD_COMMON LOAD_COMMON2 int map_generation= c->map_generation; cmpf= s->dsp.me_cmp[size]; chroma_cmpf= s->dsp.me_cmp[size+1]; for(dia_size=1; dia_size<=4; dia_size++){ int dir; const int x= best[0]; const int y= best[1]; if(dia_size&(dia_size-1)) continue; if( x + dia_size > xmax || x - dia_size < xmin || y + dia_size > ymax || y - dia_size < ymin) continue; for(dir= 0; dir<dia_size; dir+=2){ int d; CHECK_MV(x + dir , y + dia_size - dir); CHECK_MV(x + dia_size - dir, y - dir ); CHECK_MV(x - dir , y - dia_size + dir); 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]);if(dy>dx){ dx^=dy; dy^=dx; dx^=dy;}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("%8d ", stats[i]); } printf("\n");}}#endif } return dmin;}#define SAB_CHECK_MV(ax,ay)\{\ const int key= ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\ const int index= (((ay)<<ME_MAP_SHIFT) + (ax))&(ME_MAP_SIZE-1);\/*printf("sab check %d %d\n", ax, ay);*/\ if(map[index]!=key){\ d= cmp(s, ax, ay, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\ map[index]= key;\ score_map[index]= d;\ d += (mv_penalty[((ax)<<shift)-pred_x] + mv_penalty[((ay)<<shift)-pred_y])*penalty_factor;\/*printf("score: %d\n", d);*/\ if(d < minima[minima_count-1].height){\ int j=0;\ \ while(d >= minima[j].height) j++;\\ memmove(&minima [j+1], &minima [j], (minima_count - j - 1)*sizeof(Minima));\\ minima[j].checked= 0;\ minima[j].height= d;\ minima[j].x= ax;\ minima[j].y= ay;\ \ i=-1;\ continue;\ }\ }\}#define MAX_SAB_SIZE ME_MAP_SIZEstatic int sab_diamond_search(MpegEncContext * s, int *best, int dmin, int src_index, int ref_index, int const penalty_factor, int size, int h, int flags){ MotionEstContext * const c= &s->me; me_cmp_func cmpf, chroma_cmpf; Minima minima[MAX_SAB_SIZE]; const int minima_count= ABS(c->dia_size); int i, j; LOAD_COMMON LOAD_COMMON2 int map_generation= c->map_generation; cmpf= s->dsp.me_cmp[size]; chroma_cmpf= s->dsp.me_cmp[size+1]; for(j=i=0; i<ME_MAP_SIZE; i++){ uint32_t key= map[i]; key += (1<<(ME_MAP_MV_BITS-1)) + (1<<(2*ME_MAP_MV_BITS-1)); if((key&((-1)<<(2*ME_MAP_MV_BITS))) != map_generation) continue; assert(j<MAX_SAB_SIZE); //max j = number of predictors minima[j].height= score_map[i]; minima[j].x= key & ((1<<ME_MAP_MV_BITS)-1); key>>=ME_MAP_MV_BITS; minima[j].y= key & ((1<<ME_MAP_MV_BITS)-1); minima[j].x-= (1<<(ME_MAP_MV_BITS-1)); minima[j].y-= (1<<(ME_MAP_MV_BITS-1)); minima[j].checked=0; if(minima[j].x || minima[j].y) minima[j].height+= (mv_penalty[((minima[j].x)<<shift)-pred_x] + mv_penalty[((minima[j].y)<<shift)-pred_y])*penalty_factor; j++; } qsort(minima, j, sizeof(Minima), minima_cmp); for(; j<minima_count; j++){ minima[j].height=256*256*256*64; minima[j].checked=0; minima[j].x= minima[j].y=0; } for(i=0; i<minima_count; i++){ const int x= minima[i].x; const int y= minima[i].y;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -