* Motion estimation template.
*/
+#include "mpegvideo.h"
+
//Let us hope gcc will remove the unused vars ...(gcc 3.2.2 seems to do it ...)
#define LOAD_COMMON\
uint32_t av_unused * const score_map= c->score_map;\
COPY3_IF_LT(dmin, d, bx, hx, by, hy)\
}
-#if 0
-static int hpel_motion_search)(MpegEncContext * s,
- int *mx_ptr, int *my_ptr, int dmin,
- uint8_t *ref_data[3],
- int size)
-{
- const int xx = 16 * s->mb_x + 8*(n&1);
- const int yy = 16 * s->mb_y + 8*(n>>1);
- const int mx = *mx_ptr;
- const int my = *my_ptr;
- const int penalty_factor= c->sub_penalty_factor;
-
- LOAD_COMMON
-
- // INIT;
- //FIXME factorize
- me_cmp_func cmp, chroma_cmp, cmp_sub, chroma_cmp_sub;
-
- if(s->no_rounding /*FIXME b_type*/){
- hpel_put= &s->dsp.put_no_rnd_pixels_tab[size];
- chroma_hpel_put= &s->dsp.put_no_rnd_pixels_tab[size+1];
- }else{
- hpel_put=& s->dsp.put_pixels_tab[size];
- chroma_hpel_put= &s->dsp.put_pixels_tab[size+1];
- }
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
- cmp_sub= s->dsp.me_sub_cmp[size];
- chroma_cmp_sub= s->dsp.me_sub_cmp[size+1];
-
- if(c->skip){ //FIXME somehow move up (benchmark)
- *mx_ptr = 0;
- *my_ptr = 0;
- return dmin;
- }
-
- if(c->avctx->me_cmp != c->avctx->me_sub_cmp){
- CMP_HPEL(dmin, 0, 0, mx, my, size);
- if(mx || my)
- dmin += (mv_penalty[2*mx - pred_x] + mv_penalty[2*my - pred_y])*penalty_factor;
- }
-
- if (mx > xmin && mx < xmax &&
- my > ymin && my < ymax) {
- int bx=2*mx, by=2*my;
- int d= dmin;
-
- CHECK_HALF_MV(1, 1, mx-1, my-1)
- CHECK_HALF_MV(0, 1, mx , my-1)
- CHECK_HALF_MV(1, 1, mx , my-1)
- CHECK_HALF_MV(1, 0, mx-1, my )
- CHECK_HALF_MV(1, 0, mx , my )
- CHECK_HALF_MV(1, 1, mx-1, my )
- CHECK_HALF_MV(0, 1, mx , my )
- CHECK_HALF_MV(1, 1, mx , my )
-
- assert(bx >= xmin*2 || bx <= xmax*2 || by >= ymin*2 || by <= ymax*2);
-
- *mx_ptr = bx;
- *my_ptr = by;
- }else{
- *mx_ptr =2*mx;
- *my_ptr =2*my;
- }
-
- return dmin;
-}
-
-#else
static int hpel_motion_search(MpegEncContext * s,
int *mx_ptr, int *my_ptr, int dmin,
int src_index, int ref_index,
//FIXME factorize
- cmp_sub= s->dsp.me_sub_cmp[size];
- chroma_cmp_sub= s->dsp.me_sub_cmp[size+1];
+ cmp_sub = s->mecc.me_sub_cmp[size];
+ chroma_cmp_sub = s->mecc.me_sub_cmp[size + 1];
if(c->skip){ //FIXME move out of hpel?
*mx_ptr = 0;
const int b= score_map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)]
+ (mv_penalty[bx - pred_x] + mv_penalty[by+2 - pred_y])*c->penalty_factor;
- int key;
- int map_generation= c->map_generation;
+ unsigned key;
+ unsigned map_generation= c->map_generation;
#ifndef NDEBUG
uint32_t *map= c->map;
#endif
return dmin;
}
-#endif
static int no_sub_motion_search(MpegEncContext * s,
int *mx_ptr, int *my_ptr, int dmin,
return dmin;
}
-inline int ff_get_mb_score(MpegEncContext * s, int mx, int my, int src_index,
- int ref_index, int size, int h, int add_rate)
+static inline int get_mb_score(MpegEncContext *s, int mx, int my,
+ int src_index, int ref_index, int size,
+ int h, int add_rate)
{
-// const int check_luma= s->dsp.me_sub_cmp != s->dsp.mb_cmp;
MotionEstContext * const c= &s->me;
const int penalty_factor= c->mb_penalty_factor;
const int flags= c->mb_flags;
//FIXME factorize
- cmp_sub= s->dsp.mb_cmp[size];
- chroma_cmp_sub= s->dsp.mb_cmp[size+1];
+ cmp_sub = s->mecc.mb_cmp[size];
+ chroma_cmp_sub = s->mecc.mb_cmp[size + 1];
// assert(!c->skip);
// assert(c->avctx->me_sub_cmp != c->avctx->mb_cmp);
return d;
}
+int ff_get_mb_score(MpegEncContext *s, int mx, int my, int src_index,
+ int ref_index, int size, int h, int add_rate)
+{
+ return get_mb_score(s, mx, my, src_index, ref_index, size, h, add_rate);
+}
+
#define CHECK_QUARTER_MV(dx, dy, x, y)\
{\
const int hx= 4*(x)+(dx);\
const int mx = *mx_ptr;
const int my = *my_ptr;
const int penalty_factor= c->sub_penalty_factor;
- const int map_generation= c->map_generation;
+ const unsigned map_generation = c->map_generation;
const int subpel_quality= c->avctx->me_subpel_quality;
uint32_t *map= c->map;
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
int flags= c->sub_flags;
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1]; //factorize FIXME
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1]; // FIXME: factorize
//FIXME factorize
- cmp_sub= s->dsp.me_sub_cmp[size];
- chroma_cmp_sub= s->dsp.me_sub_cmp[size+1];
+ cmp_sub = s->mecc.me_sub_cmp[size];
+ chroma_cmp_sub = s->mecc.me_sub_cmp[size + 1];
if(c->skip){ //FIXME somehow move up (benchmark)
*mx_ptr = 0;
int best_pos[8][2];
memset(best, 64, sizeof(int)*8);
-#if 1
if(s->me.dia_size>=2){
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)];
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;
#define CHECK_MV(x,y)\
{\
- const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
+ const unsigned 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_MV_DIR(x,y,new_dir)\
{\
- const int key= ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
+ const unsigned 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;\
int next_dir=-1;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.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 unsigned 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);
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)
int dia_size;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1];
for(dia_size=1; dia_size<=4; dia_size++){
int dir;
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
int x,y,d;
const int dec= dia_size & (dia_size-1);
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1];
for(;dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
do{
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
int x,y,i,d;
int dia_size= c->dia_size&0xFF;
const int dec= dia_size & (dia_size-1);
static const int hex[8][2]={{-2, 0}, {-1,-1}, { 0,-2}, { 1,-1},
{ 2, 0}, { 1, 1}, { 0, 2}, {-1, 1}};
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1];
for(; dia_size; dia_size= dec ? dia_size-1 : dia_size>>1){
do{
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
int x,y,x2,y2, i, j, d;
const int dia_size= c->dia_size&0xFE;
static const int hex[16][2]={{-4,-2}, {-4,-1}, {-4, 0}, {-4, 1}, {-4, 2},
{-2, 3}, { 0, 4}, { 2, 3},
{-2,-3}, { 0,-4}, { 2,-3},};
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1];
x= best[0];
y= best[1];
me_cmp_func cmpf, chroma_cmpf;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
int x,y, d;
const int dia_size= c->dia_size&0xFF;
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1];
for(y=FFMAX(-dia_size, ymin); y<=FFMIN(dia_size,ymax); y++){
for(x=FFMAX(-dia_size, xmin); x<=FFMIN(dia_size,xmax); x++){
#define SAB_CHECK_MV(ax,ay)\
{\
- const int key= ((ay)<<ME_MAP_MV_BITS) + (ax) + map_generation;\
+ const unsigned 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;\
\
int i, j;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1];
/*Note j<MAX_SAB_SIZE is needed if MAX_SAB_SIZE < ME_MAP_SIZE as j can
become larger due to MVs overflowing their ME_MAP_MV_BITS bits space in map
int dia_size;
LOAD_COMMON
LOAD_COMMON2
- int map_generation= c->map_generation;
+ unsigned map_generation = c->map_generation;
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1];
for(dia_size=1; dia_size<=c->dia_size; dia_size++){
int dir, start, end;
int d; ///< the score (cmp + penalty) of any given mv
int dmin; /**< the best value of d, i.e. the score
corresponding to the mv stored in best[]. */
- int map_generation;
+ unsigned map_generation;
int penalty_factor;
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
if(c->pre_pass){
penalty_factor= c->pre_penalty_factor;
- cmpf= s->dsp.me_pre_cmp[size];
- chroma_cmpf= s->dsp.me_pre_cmp[size+1];
+ cmpf = s->mecc.me_pre_cmp[size];
+ chroma_cmpf = s->mecc.me_pre_cmp[size + 1];
}else{
penalty_factor= c->penalty_factor;
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1];
}
map_generation= update_map_generation(c);
score_map[0]= dmin;
//FIXME precalc first term below?
- if((s->pict_type == AV_PICTURE_TYPE_B && !(c->flags & FLAG_DIRECT)) || s->flags&CODEC_FLAG_MV0)
+ if ((s->pict_type == AV_PICTURE_TYPE_B && !(c->flags & FLAG_DIRECT)) ||
+ s->mpv_flags & FF_MPV_FLAG_MV0)
dmin += (mv_penalty[pred_x] + mv_penalty[pred_y])*penalty_factor;
/* first line */
*mx_ptr= best[0];
*my_ptr= best[1];
-// printf("%d %d %d \n", best[0], best[1], dmin);
return dmin;
}
//this function is dedicated to the braindamaged gcc
-inline int ff_epzs_motion_search(MpegEncContext * s, int *mx_ptr, int *my_ptr,
- int P[10][2], int src_index, int ref_index, int16_t (*last_mv)[2],
- int ref_mv_scale, int size, int h)
+int ff_epzs_motion_search(MpegEncContext *s, int *mx_ptr, int *my_ptr,
+ int P[10][2], int src_index, int ref_index,
+ int16_t (*last_mv)[2], int ref_mv_scale,
+ int size, int h)
{
MotionEstContext * const c= &s->me;
//FIXME convert other functions in the same way if faster
MotionEstContext * const c= &s->me;
int best[2]={0, 0};
int d, dmin;
- int map_generation;
+ unsigned map_generation;
const int penalty_factor= c->penalty_factor;
const int size=1;
const int h=8;
int flags= c->flags;
LOAD_COMMON2
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1];
map_generation= update_map_generation(c);
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)
*mx_ptr= best[0];
*my_ptr= best[1];
-// printf("%d %d %d \n", best[0], best[1], dmin);
return dmin;
}
MotionEstContext * const c= &s->me;
int best[2]={0, 0};
int d, dmin;
- int map_generation;
+ unsigned map_generation;
const int penalty_factor= c->penalty_factor;
const int size=0; //FIXME pass as arg
const int h=8;
int flags= c->flags;
LOAD_COMMON2
- cmpf= s->dsp.me_cmp[size];
- chroma_cmpf= s->dsp.me_cmp[size+1];
+ cmpf = s->mecc.me_cmp[size];
+ chroma_cmpf = s->mecc.me_cmp[size + 1];
map_generation= update_map_generation(c);
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)
*mx_ptr= best[0];
*my_ptr= best[1];
-// printf("%d %d %d \n", best[0], best[1], dmin);
return dmin;
}