|
|
|
@ -859,7 +859,7 @@ static inline void init_interlaced_ref(MpegEncContext *s, int ref_index){ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int interlaced_search(MpegEncContext *s, int ref_index,
|
|
|
|
|
int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my) |
|
|
|
|
int16_t (*mv_tables[2][2])[2], uint8_t *field_select_tables[2], int mx, int my, int user_field_select) |
|
|
|
|
{ |
|
|
|
|
MotionEstContext * const c= &s->me; |
|
|
|
|
const int size=0; |
|
|
|
@ -889,6 +889,11 @@ static int interlaced_search(MpegEncContext *s, int ref_index, |
|
|
|
|
int dmin, mx_i, my_i; |
|
|
|
|
int16_t (*mv_table)[2]= mv_tables[block][field_select]; |
|
|
|
|
|
|
|
|
|
if(user_field_select){ |
|
|
|
|
if(field_select_tables[block][xy] != field_select) |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
P_LEFT[0] = mv_table[xy - 1][0]; |
|
|
|
|
P_LEFT[1] = mv_table[xy - 1][1]; |
|
|
|
|
if(P_LEFT[0] > (c->xmax<<1)) P_LEFT[0] = (c->xmax<<1); |
|
|
|
@ -996,7 +1001,6 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int |
|
|
|
|
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA; |
|
|
|
|
c->stride<<=1; |
|
|
|
|
c->uvstride<<=1; |
|
|
|
|
init_interlaced_ref(s, 2); |
|
|
|
|
|
|
|
|
|
assert(s->flags & CODEC_FLAG_INTERLACED_ME); |
|
|
|
|
|
|
|
|
@ -1005,6 +1009,8 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int |
|
|
|
|
int field_select1= p->ref_index[0][xy2]; |
|
|
|
|
assert(field_select0==0 ||field_select0==1); |
|
|
|
|
assert(field_select1==0 ||field_select1==1); |
|
|
|
|
init_interlaced_ref(s, 0); |
|
|
|
|
|
|
|
|
|
if(p_type){ |
|
|
|
|
s->p_field_select_table[0][mb_xy]= field_select0; |
|
|
|
|
s->p_field_select_table[1][mb_xy]= field_select1; |
|
|
|
@ -1031,6 +1037,8 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int |
|
|
|
|
int field_select1= p->ref_index[1][xy2]; |
|
|
|
|
assert(field_select0==0 ||field_select0==1); |
|
|
|
|
assert(field_select1==0 ||field_select1==1); |
|
|
|
|
init_interlaced_ref(s, 2); |
|
|
|
|
|
|
|
|
|
s->b_field_select_table[1][0][mb_xy]= field_select0; |
|
|
|
|
s->b_field_select_table[1][1][mb_xy]= field_select1; |
|
|
|
|
*(uint32_t*)s->b_field_mv_table[1][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[1][xy ]; |
|
|
|
@ -1097,7 +1105,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, |
|
|
|
|
{ |
|
|
|
|
MotionEstContext * const c= &s->me; |
|
|
|
|
uint8_t *pix, *ppix; |
|
|
|
|
int sum, varc, vard, mx, my, dmin, xx, yy; |
|
|
|
|
int sum, varc, vard, mx, my, dmin; |
|
|
|
|
int P[10][2]; |
|
|
|
|
const int shift= 1+s->quarter_sample; |
|
|
|
|
int mb_type=0; |
|
|
|
@ -1117,18 +1125,20 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, |
|
|
|
|
get_limits(s, 16*mb_x, 16*mb_y); |
|
|
|
|
s->me.skip=0; |
|
|
|
|
|
|
|
|
|
/* intra / predictive decision */ |
|
|
|
|
pix = c->src[0][0]; |
|
|
|
|
sum = s->dsp.pix_sum(pix, s->linesize); |
|
|
|
|
varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; |
|
|
|
|
|
|
|
|
|
pic->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8; |
|
|
|
|
pic->mb_var [s->mb_stride * mb_y + mb_x] = varc; |
|
|
|
|
s->mb_var_sum_temp += varc; |
|
|
|
|
|
|
|
|
|
if(s->avctx->me_threshold){ |
|
|
|
|
vard= (check_input_motion(s, mb_x, mb_y, 1)+128)>>8; |
|
|
|
|
|
|
|
|
|
if(vard<s->avctx->me_threshold){ |
|
|
|
|
pix = c->src[0][0]; |
|
|
|
|
sum = s->dsp.pix_sum(pix, s->linesize); |
|
|
|
|
varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; |
|
|
|
|
|
|
|
|
|
pic->mb_var [s->mb_stride * mb_y + mb_x] = varc; |
|
|
|
|
pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = vard; |
|
|
|
|
pic->mb_mean [s->mb_stride * mb_y + mb_x] = (sum+128)>>8; |
|
|
|
|
s->mb_var_sum_temp += varc; |
|
|
|
|
s->mc_mb_var_sum_temp += vard; |
|
|
|
|
if (vard <= 64 || vard < varc) { //FIXME
|
|
|
|
|
s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); |
|
|
|
@ -1137,6 +1147,8 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if(vard<s->avctx->mb_threshold) |
|
|
|
|
mb_type= s->mb_type[mb_x + mb_y*s->mb_stride]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch(s->me_method) { |
|
|
|
@ -1205,33 +1217,41 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* intra / predictive decision */ |
|
|
|
|
xx = mb_x * 16; |
|
|
|
|
yy = mb_y * 16; |
|
|
|
|
|
|
|
|
|
pix = c->src[0][0]; |
|
|
|
|
/* At this point (mx,my) are full-pell and the relative displacement */ |
|
|
|
|
ppix = c->ref[0][0] + (my * s->linesize) + mx; |
|
|
|
|
|
|
|
|
|
sum = s->dsp.pix_sum(pix, s->linesize); |
|
|
|
|
|
|
|
|
|
varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; |
|
|
|
|
|
|
|
|
|
vard = (s->dsp.sse[0](NULL, pix, ppix, s->linesize, 16)+128)>>8; |
|
|
|
|
|
|
|
|
|
//printf("%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout);
|
|
|
|
|
pic->mb_var [s->mb_stride * mb_y + mb_x] = varc; |
|
|
|
|
pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = vard; |
|
|
|
|
pic->mb_mean [s->mb_stride * mb_y + mb_x] = (sum+128)>>8; |
|
|
|
|
// pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin;
|
|
|
|
|
s->mb_var_sum_temp += varc; |
|
|
|
|
s->mc_mb_var_sum_temp += vard; |
|
|
|
|
//printf("E%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout);
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n", |
|
|
|
|
varc, s->avg_mb_var, sum, vard, mx - xx, my - yy); |
|
|
|
|
#endif |
|
|
|
|
if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){ |
|
|
|
|
if(mb_type){ |
|
|
|
|
if (vard <= 64 || vard < varc) |
|
|
|
|
s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); |
|
|
|
|
else |
|
|
|
|
s->scene_change_score+= s->qscale; |
|
|
|
|
|
|
|
|
|
if(mb_type == CANDIDATE_MB_TYPE_INTER){ |
|
|
|
|
s->me.sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16); |
|
|
|
|
set_p_mv_tables(s, mx, my, 1); |
|
|
|
|
}else{ |
|
|
|
|
mx <<=shift; |
|
|
|
|
my <<=shift; |
|
|
|
|
} |
|
|
|
|
if(mb_type == CANDIDATE_MB_TYPE_INTER4V){ |
|
|
|
|
h263_mv4_search(s, mx, my, shift); |
|
|
|
|
|
|
|
|
|
set_p_mv_tables(s, mx, my, 0); |
|
|
|
|
} |
|
|
|
|
if(mb_type == CANDIDATE_MB_TYPE_INTER_I){ |
|
|
|
|
interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 1); |
|
|
|
|
} |
|
|
|
|
}else if(s->avctx->mb_decision > FF_MB_DECISION_SIMPLE){ |
|
|
|
|
if (vard <= 64 || vard < varc) |
|
|
|
|
s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); |
|
|
|
|
else |
|
|
|
@ -1259,7 +1279,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, |
|
|
|
|
set_p_mv_tables(s, mx, my, 1); |
|
|
|
|
if((s->flags&CODEC_FLAG_INTERLACED_ME) |
|
|
|
|
&& !s->me.skip){ //FIXME varc/d checks
|
|
|
|
|
if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my) < INT_MAX) |
|
|
|
|
if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX) |
|
|
|
|
mb_type |= CANDIDATE_MB_TYPE_INTER_I; |
|
|
|
|
} |
|
|
|
|
}else{ |
|
|
|
@ -1280,7 +1300,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, |
|
|
|
|
} |
|
|
|
|
if((s->flags&CODEC_FLAG_INTERLACED_ME) |
|
|
|
|
&& !s->me.skip){ //FIXME varc/d checks
|
|
|
|
|
int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my); |
|
|
|
|
int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0); |
|
|
|
|
if(dmin_i < dmin){ |
|
|
|
|
mb_type = CANDIDATE_MB_TYPE_INTER_I; |
|
|
|
|
dmin= dmin_i; |
|
|
|
@ -1690,7 +1710,9 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, |
|
|
|
|
const int penalty_factor= s->me.mb_penalty_factor; |
|
|
|
|
int fmin, bmin, dmin, fbmin, bimin, fimin; |
|
|
|
|
int type=0; |
|
|
|
|
const int xy = mb_y*s->mb_stride + mb_x; |
|
|
|
|
init_ref(s, s->new_picture.data, s->last_picture.data, s->next_picture.data, 16*mb_x, 16*mb_y, 2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s->me.skip=0; |
|
|
|
|
if(s->avctx->me_threshold){ |
|
|
|
@ -1713,6 +1735,35 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, |
|
|
|
|
}*/ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if(vard<s->avctx->mb_threshold){ |
|
|
|
|
type= s->mb_type[mb_y*s->mb_stride + mb_x]; |
|
|
|
|
if(type == CANDIDATE_MB_TYPE_DIRECT){ |
|
|
|
|
direct_search(s, mb_x, mb_y); |
|
|
|
|
} |
|
|
|
|
if(type == CANDIDATE_MB_TYPE_FORWARD || type == CANDIDATE_MB_TYPE_BIDIR){ |
|
|
|
|
s->me.skip=0; |
|
|
|
|
ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code); |
|
|
|
|
} |
|
|
|
|
if(type == CANDIDATE_MB_TYPE_BACKWARD || type == CANDIDATE_MB_TYPE_BIDIR){ |
|
|
|
|
s->me.skip=0; |
|
|
|
|
ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code); |
|
|
|
|
} |
|
|
|
|
if(type == CANDIDATE_MB_TYPE_FORWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){ |
|
|
|
|
s->me.skip=0; |
|
|
|
|
s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; |
|
|
|
|
interlaced_search(s, 0, |
|
|
|
|
s->b_field_mv_table[0], s->b_field_select_table[0], |
|
|
|
|
s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 1); |
|
|
|
|
} |
|
|
|
|
if(type == CANDIDATE_MB_TYPE_BACKWARD_I || type == CANDIDATE_MB_TYPE_BIDIR_I){ |
|
|
|
|
s->me.skip=0; |
|
|
|
|
s->me.current_mv_penalty= s->me.mv_penalty[s->b_code] + MAX_MV; |
|
|
|
|
interlaced_search(s, 2, |
|
|
|
|
s->b_field_mv_table[1], s->b_field_select_table[1], |
|
|
|
|
s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 1); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (s->codec_id == CODEC_ID_MPEG4) |
|
|
|
@ -1732,18 +1783,16 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, |
|
|
|
|
//printf("%d %d %d %d\n", dmin, fmin, bmin, fbmin);
|
|
|
|
|
|
|
|
|
|
if(s->flags & CODEC_FLAG_INTERLACED_ME){ |
|
|
|
|
const int xy = mb_y*s->mb_stride + mb_x; |
|
|
|
|
|
|
|
|
|
//FIXME mb type penalty
|
|
|
|
|
s->me.skip=0; |
|
|
|
|
s->me.current_mv_penalty= s->me.mv_penalty[s->f_code] + MAX_MV; |
|
|
|
|
fimin= interlaced_search(s, 0, |
|
|
|
|
s->b_field_mv_table[0], s->b_field_select_table[0], |
|
|
|
|
s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); |
|
|
|
|
s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 0); |
|
|
|
|
s->me.current_mv_penalty= s->me.mv_penalty[s->b_code] + MAX_MV; |
|
|
|
|
bimin= interlaced_search(s, 2, |
|
|
|
|
s->b_field_mv_table[1], s->b_field_select_table[1], |
|
|
|
|
s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1]); |
|
|
|
|
s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 0); |
|
|
|
|
}else |
|
|
|
|
fimin= bimin= INT_MAX; |
|
|
|
|
|
|
|
|
|