changeset 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 2b0fc6b25ab8
children 56cb752222cc
files avcodec.h motion_est.c mpegvideo.h
diffstat 3 files changed, 91 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/avcodec.h	Sat Apr 24 19:30:49 2004 +0000
+++ b/avcodec.h	Sun Apr 25 02:09:47 2004 +0000
@@ -17,7 +17,7 @@
 
 #define FFMPEG_VERSION_INT     0x000408
 #define FFMPEG_VERSION         "0.4.8"
-#define LIBAVCODEC_BUILD       4709
+#define LIBAVCODEC_BUILD       4710
 
 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
 #define LIBAVCODEC_VERSION     FFMPEG_VERSION
@@ -1570,12 +1570,20 @@
     void *thread_opaque;
 
     /**
-     * Motion estimation threshold.
+     * Motion estimation threshold. under which no motion estimation is 
+     * performed, but instead the user specified motion vectors are used
      * 
      * - encoding: set by user
-     * - decoding: set by user
+     * - decoding: unused
      */
      int me_threshold;
+
+    /**
+     * Macroblock threshold. under which the user specified macroblock types will be used
+     * - encoding: set by user
+     * - decoding: unused
+     */
+     int mb_threshold;
 } AVCodecContext;
 
 
--- 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;
 
--- a/mpegvideo.h	Sat Apr 24 19:30:49 2004 +0000
+++ b/mpegvideo.h	Sun Apr 25 02:09:47 2004 +0000
@@ -229,7 +229,6 @@
 /*    cmp, chroma_cmp;*/
     op_pixels_func (*hpel_put)[4];
     op_pixels_func (*hpel_avg)[4];
-    op_pixels_func (*chroma_hpel_put)[4];
     qpel_mc_func (*qpel_put)[16];
     qpel_mc_func (*qpel_avg)[16];
     uint8_t (*mv_penalty)[MAX_MV*2+1];  ///< amount of bits needed to encode a MV