|
|
|
@@ -973,6 +973,119 @@ static int interlaced_search(MpegEncContext *s, int ref_index, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int p_type){ |
|
|
|
MotionEstContext * const c= &s->me; |
|
|
|
Picture *p= s->current_picture_ptr; |
|
|
|
int mb_xy= mb_x + mb_y*s->mb_stride; |
|
|
|
int xy= 2*mb_x + 2*mb_y*s->b8_stride; |
|
|
|
int mb_type= s->current_picture.mb_type[mb_xy]; |
|
|
|
int flags= c->flags; |
|
|
|
int shift= (flags&FLAG_QPEL) + 1; |
|
|
|
int mask= (1<<shift)-1; |
|
|
|
int x, y; |
|
|
|
int d=0; |
|
|
|
me_cmp_func cmpf= s->dsp.sse[0]; |
|
|
|
me_cmp_func chroma_cmpf= s->dsp.sse[1]; |
|
|
|
|
|
|
|
assert(p_type==0 || !USES_LIST(mb_type, 1)); |
|
|
|
assert(IS_INTRA(mb_type) || USES_LIST(mb_type,0) || USES_LIST(mb_type,1)); |
|
|
|
|
|
|
|
if(IS_INTERLACED(mb_type)){ |
|
|
|
int xy2= xy + s->b8_stride; |
|
|
|
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA; |
|
|
|
c->stride<<=1; |
|
|
|
c->uvstride<<=1; |
|
|
|
c->ref[1][0] = c->ref[0][0] + s->linesize; |
|
|
|
c->ref[3][0] = c->ref[2][0] + s->linesize; |
|
|
|
c->src[1][0] = c->src[0][0] + s->linesize; |
|
|
|
if(c->flags & FLAG_CHROMA){ |
|
|
|
c->ref[1][1] = c->ref[0][1] + s->uvlinesize; |
|
|
|
c->ref[1][2] = c->ref[0][2] + s->uvlinesize; |
|
|
|
c->ref[3][1] = c->ref[2][1] + s->uvlinesize; |
|
|
|
c->ref[3][2] = c->ref[2][2] + s->uvlinesize; |
|
|
|
c->src[1][1] = c->src[0][1] + s->uvlinesize; |
|
|
|
c->src[1][2] = c->src[0][2] + s->uvlinesize; |
|
|
|
} |
|
|
|
if(USES_LIST(mb_type, 0)){ |
|
|
|
int field_select0= p->ref_index[0][xy ]; |
|
|
|
int field_select1= p->ref_index[0][xy2]; |
|
|
|
assert(field_select0==0 ||field_select0==1); |
|
|
|
assert(field_select1==0 ||field_select1==1); |
|
|
|
if(p_type){ |
|
|
|
s->p_field_select_table[0][mb_xy]= field_select0; |
|
|
|
s->p_field_select_table[1][mb_xy]= field_select1; |
|
|
|
*(uint32_t*)s->p_field_mv_table[0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ]; |
|
|
|
*(uint32_t*)s->p_field_mv_table[1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2]; |
|
|
|
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER_I; |
|
|
|
}else{ |
|
|
|
s->b_field_select_table[0][0][mb_xy]= field_select0; |
|
|
|
s->b_field_select_table[0][1][mb_xy]= field_select1; |
|
|
|
*(uint32_t*)s->b_field_mv_table[0][0][field_select0][mb_xy]= *(uint32_t*)p->motion_val[0][xy ]; |
|
|
|
*(uint32_t*)s->b_field_mv_table[0][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[0][xy2]; |
|
|
|
s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_FORWARD_I; |
|
|
|
} |
|
|
|
|
|
|
|
x= p->motion_val[0][xy ][0]; |
|
|
|
y= p->motion_val[0][xy ][1]; |
|
|
|
d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0, 0, cmpf, chroma_cmpf, flags); |
|
|
|
x= p->motion_val[0][xy2][0]; |
|
|
|
y= p->motion_val[0][xy2][1]; |
|
|
|
d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1, 1, cmpf, chroma_cmpf, flags); |
|
|
|
} |
|
|
|
if(USES_LIST(mb_type, 1)){ |
|
|
|
int field_select0= p->ref_index[1][xy ]; |
|
|
|
int field_select1= p->ref_index[1][xy2]; |
|
|
|
assert(field_select0==0 ||field_select0==1); |
|
|
|
assert(field_select1==0 ||field_select1==1); |
|
|
|
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 ]; |
|
|
|
*(uint32_t*)s->b_field_mv_table[1][1][field_select1][mb_xy]= *(uint32_t*)p->motion_val[1][xy2]; |
|
|
|
if(USES_LIST(mb_type, 0)){ |
|
|
|
s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BIDIR_I; |
|
|
|
}else{ |
|
|
|
s->mb_type[mb_xy]= CANDIDATE_MB_TYPE_BACKWARD_I; |
|
|
|
} |
|
|
|
|
|
|
|
x= p->motion_val[1][xy ][0]; |
|
|
|
y= p->motion_val[1][xy ][1]; |
|
|
|
d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select0+2, 0, cmpf, chroma_cmpf, flags); |
|
|
|
x= p->motion_val[1][xy2][0]; |
|
|
|
y= p->motion_val[1][xy2][1]; |
|
|
|
d+= cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 8, field_select1+2, 1, cmpf, chroma_cmpf, flags); |
|
|
|
//FIXME bidir scores |
|
|
|
} |
|
|
|
c->stride>>=1; |
|
|
|
c->uvstride>>=1; |
|
|
|
}else{ |
|
|
|
if(USES_LIST(mb_type, 0)){ |
|
|
|
if(p_type){ |
|
|
|
*(uint32_t*)s->p_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy]; |
|
|
|
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTER; |
|
|
|
}else if(USES_LIST(mb_type, 1)){ |
|
|
|
*(uint32_t*)s->b_bidir_forw_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy]; |
|
|
|
*(uint32_t*)s->b_bidir_back_mv_table[mb_xy]= *(uint32_t*)p->motion_val[1][xy]; |
|
|
|
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BIDIR; |
|
|
|
}else{ |
|
|
|
*(uint32_t*)s->b_forw_mv_table[mb_xy]= *(uint32_t*)p->motion_val[0][xy]; |
|
|
|
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_FORWARD; |
|
|
|
} |
|
|
|
x= p->motion_val[0][xy][0]; |
|
|
|
y= p->motion_val[0][xy][1]; |
|
|
|
d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 0, 0, cmpf, chroma_cmpf, flags); |
|
|
|
}else if(USES_LIST(mb_type, 1)){ |
|
|
|
*(uint32_t*)s->b_back_mv_table[mb_xy]= *(uint32_t*)p->motion_val[1][xy]; |
|
|
|
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_BACKWARD; |
|
|
|
|
|
|
|
x= p->motion_val[1][xy][0]; |
|
|
|
y= p->motion_val[1][xy][1]; |
|
|
|
d = cmp(s, x>>shift, y>>shift, x&mask, y&mask, 0, 16, 2, 0, cmpf, chroma_cmpf, flags); |
|
|
|
}else |
|
|
|
s->mb_type[mb_xy]=CANDIDATE_MB_TYPE_INTRA; |
|
|
|
} |
|
|
|
return d; |
|
|
|
} |
|
|
|
|
|
|
|
void ff_estimate_p_frame_motion(MpegEncContext * s, |
|
|
|
int mb_x, int mb_y) |
|
|
|
{ |
|
|
|
@@ -999,6 +1112,28 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, |
|
|
|
get_limits(s, 16*mb_x, 16*mb_y); |
|
|
|
s->me.skip=0; |
|
|
|
|
|
|
|
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); |
|
|
|
}else{ |
|
|
|
s->scene_change_score+= s->qscale; |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
switch(s->me_method) { |
|
|
|
case ME_ZERO: |
|
|
|
default: |
|
|
|
@@ -1555,6 +1690,28 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, |
|
|
|
init_mc(s, 0, s->me.flags); |
|
|
|
|
|
|
|
s->me.skip=0; |
|
|
|
if(s->avctx->me_threshold){ |
|
|
|
int vard= (check_input_motion(s, mb_x, mb_y, 0)+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; |
|
|
|
s->current_picture.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) { |
|
|
|
s->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc); |
|
|
|
}else{ |
|
|
|
s->scene_change_score+= s->qscale; |
|
|
|
}*/ |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (s->codec_id == CODEC_ID_MPEG4) |
|
|
|
dmin= direct_search(s, mb_x, mb_y); |
|
|
|
else |
|
|
|
|