📄 motion_est_template.c
字号:
const int b2= nx*nx*(br + bl - 2*b) + 4*nx*(br-bl) + 32*b; int score= ny*ny*(b2 + t2 - 2*c2) + 4*ny*(b2 - t2) + 32*c2; int i; if((nx&3)==0 && (ny&3)==0) continue; score += 1024*(mv_penalty[4*mx + nx - pred_x] + mv_penalty[4*my + ny - pred_y])*penalty_factor; // if(nx&1) score-=1024*s->me.penalty_factor;// if(ny&1) score-=1024*s->me.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; } } } } }else{ int tl; const int cx = 4*(r - l); const int cx2= r + l - 2*c; const int cy = 4*(b - t); const int cy2= b + t - 2*c; int cxy; 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{ CMP(tl, mx-1, my-1, size); //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++){ 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*s->me.penalty_factor; // if(ny&1) score-=32*s->me.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;}static int RENAME(qpel_get_mb_score)(MpegEncContext * s, int mx, int my, int pred_x, int pred_y, Picture *ref_picture, uint8_t * const mv_penalty){ const int size= 0; const int xx = 16 * s->mb_x; const int yy = 16 * s->mb_y; const int penalty_factor= s->me.mb_penalty_factor; const int xmin= -256*256, ymin= -256*256, xmax= 256*256, ymax= 256*256; //assume that the caller checked these const __attribute__((unused)) int unu2= xmin + xmax +ymin + ymax; //no unused warning shit me_cmp_func cmp_sub, chroma_cmp_sub; int d; LOAD_COMMON(xx, yy); //FIXME factorize cmp_sub= s->dsp.mb_cmp[size]; chroma_cmp_sub= s->dsp.mb_cmp[size+1]; assert(!s->me.skip); assert(s->avctx->me_sub_cmp != s->avctx->mb_cmp); CMP_QPEL(d, mx&3, my&3, mx>>2, my>>2, size); //FIXME check cbp before adding penalty for (0,0) vector if(mx || my || size>0) d += (mv_penalty[mx - pred_x] + mv_penalty[my - pred_y])*penalty_factor; return d;}#endif /* CMP_QPEL */#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);\/*printf("check_mv %d %d\n", x, y);*/\ if(map[index]!=key){\ CMP(d, x, y, size);\ 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= FFMAX(xmin, FFMIN(ax, xmax));\ const int y= FFMAX(ymin, FFMIN(ay, ymax));\ CHECK_MV(x, y)\}#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){\ CMP(d, x, y, size);\ 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);\static inline int RENAME(small_diamond_search)(MpegEncContext * s, int *best, int dmin, Picture *ref_picture, int const pred_x, int const pred_y, int const penalty_factor, int const xmin, int const ymin, int const xmax, int const ymax, int const shift, uint32_t *map, int map_generation, int size, uint8_t * const mv_penalty ){ me_cmp_func cmp, chroma_cmp; int next_dir=-1; LOAD_COMMON(s->mb_x*16, s->mb_y*16); cmp= s->dsp.me_cmp[size]; chroma_cmp= 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 CMP(score_map[index], best[0], best[1], size); 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 inline int RENAME(funny_diamond_search)(MpegEncContext * s, int *best, int dmin, Picture *ref_picture, int const pred_x, int const pred_y, int const penalty_factor, int const xmin, int const ymin, int const xmax, int const ymax, int const shift, uint32_t *map, int map_generation, int size, uint8_t * const mv_penalty ){ me_cmp_func cmp, chroma_cmp; int dia_size; LOAD_COMMON(s->mb_x*16, s->mb_y*16); cmp= s->dsp.me_cmp[size]; chroma_cmp= 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){\ CMP(d, ax, ay, size);\ 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));\
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -