diff motion_est.c @ 1968:19c2344e800a libavcodec

support reusing mb types and field select values of the source file, but use motion vectors just as additional predictors minor cleanup segfault fix
author michael
date Sun, 25 Apr 2004 02:09:47 +0000
parents 2fd0c3f311bf
children 38e77ac19836
line wrap: on
line diff
--- a/motion_est.c	Sat Apr 24 19:30:49 2004 +0000
+++ b/motion_est.c	Sun Apr 25 02:09:47 2004 +0000
@@ -859,7 +859,7 @@
 }
 
 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 @@
             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 @@
         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 @@
             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 @@
             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 @@
 {
     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 @@
     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 @@
             }
             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 @@
         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 @@
             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 @@
         }
         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 @@
     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 @@
             }*/
             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 @@
 //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;