summaryrefslogtreecommitdiff
path: root/libavcodec/motion_est.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2004-04-25 02:09:47 +0000
committerMichael Niedermayer <michaelni@gmx.at>2004-04-25 02:09:47 +0000
commitf20f8a8b0b666be498ac50be21c6f5485e083498 (patch)
treee1d8e6f0a1eae9f8075cd94efd72971116e8d268 /libavcodec/motion_est.c
parent7e56cd927b5842fa74ec8b5fddf6ac2b6a40145c (diff)
support reusing mb types and field select values of the source file, but use motion vectors just as additional predictors
minor cleanup segfault fix Originally committed as revision 3060 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/motion_est.c')
-rw-r--r--libavcodec/motion_est.c111
1 files changed, 80 insertions, 31 deletions
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 9ccbf078d3..f194a4d600 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -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;