]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/motion_est.c
Ministry of English Composition, reporting for duty (and the word is "skipped", not...
[ffmpeg] / libavcodec / motion_est.c
index 13f7deb8d88caa07b7ec3f60889a73da1f4634e8..8fbbdf5d22d063b2e0f0ceaae6bb538472f96c1c 100644 (file)
@@ -219,25 +219,6 @@ static always_inline int cmp(MpegEncContext *s, const int x, const int y, const
 
 #include "motion_est_template.c"
 
-static inline int get_penalty_factor(MpegEncContext *s, int type){
-    switch(type&0xFF){
-    default:
-    case FF_CMP_SAD:
-        return s->lambda>>FF_LAMBDA_SHIFT;
-    case FF_CMP_DCT:
-        return (3*s->lambda)>>(FF_LAMBDA_SHIFT+1);
-    case FF_CMP_SATD:
-        return (2*s->lambda)>>FF_LAMBDA_SHIFT;
-    case FF_CMP_RD:
-    case FF_CMP_PSNR:
-    case FF_CMP_SSE:
-    case FF_CMP_NSSE:
-        return s->lambda2>>FF_LAMBDA_SHIFT;
-    case FF_CMP_BIT:
-        return 1;
-    }
-}
-
 static int zero_cmp(void *s, uint8_t *a, uint8_t *b, int stride, int h){
     return 0;
 }
@@ -287,14 +268,20 @@ void ff_init_me(MpegEncContext *s){
     }
 
     // 8x8 fullpel search would need a 4x4 chroma compare, which we dont have yet, and even if we had the motion estimation code doesnt expect it
-    if((c->avctx->me_cmp&FF_CMP_CHROMA) && !s->dsp.me_cmp[2]){
-        s->dsp.me_cmp[2]= zero_cmp;
+    if(s->codec_id != CODEC_ID_SNOW){
+        if((c->avctx->me_cmp&FF_CMP_CHROMA) && !s->dsp.me_cmp[2]){
+            s->dsp.me_cmp[2]= zero_cmp;
+        }
+        if((c->avctx->me_sub_cmp&FF_CMP_CHROMA) && !s->dsp.me_sub_cmp[2]){
+            s->dsp.me_sub_cmp[2]= zero_cmp;
+        }
+        c->hpel_put[2][0]= c->hpel_put[2][1]=
+        c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel;
     }
-    if((c->avctx->me_sub_cmp&FF_CMP_CHROMA) && !s->dsp.me_sub_cmp[2]){
-        s->dsp.me_sub_cmp[2]= zero_cmp;
+
+    if(s->codec_id == CODEC_ID_H261){
+        c->sub_motion_search= no_sub_motion_search;
     }
-    c->hpel_put[2][0]= c->hpel_put[2][1]=
-    c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel;
 
     c->temp= c->scratchpad;
 }
@@ -330,6 +317,7 @@ static inline void no_motion_search(MpegEncContext * s,
     *my_ptr = 16 * s->mb_y;
 }
 
+#if 0  /* the use of these functions is inside #if 0 */
 static int full_motion_search(MpegEncContext * s,
                               int *mx_ptr, int *my_ptr, int range,
                               int xmin, int ymin, int xmax, int ymax, uint8_t *ref_picture)
@@ -550,7 +538,7 @@ static int phods_motion_search(MpegEncContext * s,
     *my_ptr = my;
     return dminy;
 }
-
+#endif /* 0 */
 
 #define Z_THRESHOLD 256
 
@@ -708,6 +696,12 @@ static inline void get_limits(MpegEncContext *s, int x, int y)
         c->ymin = - y - 16;
         c->xmax = - x + s->mb_width *16;
         c->ymax = - y + s->mb_height*16;
+    } else if (s->out_format == FMT_H261){
+        // Search range of H261 is different from other codec standards
+        c->xmin = (x > 15) ? - 15 : 0;
+        c->ymin = (y > 15) ? - 15 : 0;
+        c->xmax = (x < s->mb_width * 16 - 16) ? 15 : 0;              
+        c->ymax = (y < s->mb_height * 16 - 16) ? 15 : 0;
     } else {
         c->xmin = - x;
         c->ymin = - y;
@@ -737,7 +731,6 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
     int dmin_sum=0, mx4_sum=0, my4_sum=0;
     int same=1;
     const int stride= c->stride;
-    const int uvstride= c->uvstride;
     uint8_t *mv_penalty= c->current_mv_penalty;
 
     init_mv4_ref(c);
@@ -888,7 +881,6 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
     uint8_t * const mv_penalty= c->current_mv_penalty;
     int same=1;
     const int stride= 2*s->linesize;
-    const int uvstride= 2*s->uvlinesize;
     int dmin_sum= 0;
     const int mot_stride= s->mb_stride;
     const int xy= s->mb_x + s->mb_y*mot_stride;
@@ -1024,7 +1016,7 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
     
     if(p_type && USES_LIST(mb_type, 1)){
         av_log(c->avctx, AV_LOG_ERROR, "backward motion vector in P frame\n");
-        return INT_MAX;
+        return INT_MAX/2;
     }
     assert(IS_INTRA(mb_type) || USES_LIST(mb_type,0) || USES_LIST(mb_type,1));
     
@@ -1042,7 +1034,7 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
         
         if(!(s->flags & CODEC_FLAG_INTERLACED_ME)){
             av_log(c->avctx, AV_LOG_ERROR, "Interlaced macroblock selected but interlaced motion estimation disabled\n");
-            return INT_MAX;
+            return INT_MAX/2;
         }
 
         if(USES_LIST(mb_type, 0)){
@@ -1103,7 +1095,7 @@ static inline int check_input_motion(MpegEncContext * s, int mb_x, int mb_y, int
     }else if(IS_8X8(mb_type)){
         if(!(s->flags & CODEC_FLAG_4MV)){
             av_log(c->avctx, AV_LOG_ERROR, "4MV macroblock selected but 4MV encoding disabled\n");
-            return INT_MAX;
+            return INT_MAX/2;
         }
         cmpf= s->dsp.sse[1];
         chroma_cmpf= s->dsp.sse[1];
@@ -1161,9 +1153,9 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
     assert(s->linesize == c->stride);
     assert(s->uvlinesize == c->uvstride);
 
-    c->penalty_factor    = get_penalty_factor(s, c->avctx->me_cmp);
-    c->sub_penalty_factor= get_penalty_factor(s, c->avctx->me_sub_cmp);
-    c->mb_penalty_factor = get_penalty_factor(s, c->avctx->mb_cmp);
+    c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
+    c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
+    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
     c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;
 
     get_limits(s, 16*mb_x, 16*mb_y);
@@ -1256,7 +1248,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             }
 
         }
-        dmin = epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift);       
+        dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16);       
 
         break;
     }
@@ -1308,7 +1300,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
             if(s->flags&CODEC_FLAG_MV0)
                 if(mx || my)
-                    mb_type |= CANDIDATE_MB_TYPE_SKIPED; //FIXME check difference
+                    mb_type |= CANDIDATE_MB_TYPE_SKIPPED; //FIXME check difference
         }else{
             mx <<=shift;
             my <<=shift;
@@ -1332,7 +1324,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
 
         dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
         if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
-            dmin= get_mb_score(s, mx, my, 0, 0);
+            dmin= ff_get_mb_score(s, mx, my, 0, 0, 0, 16, 1);
 
         if((s->flags&CODEC_FLAG_4MV)
            && !c->skip && varc>50 && vard>10){
@@ -1424,7 +1416,7 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
     
     assert(s->quarter_sample==0 || s->quarter_sample==1);
 
-    c->pre_penalty_factor    = get_penalty_factor(s, c->avctx->me_pre_cmp);
+    c->pre_penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_pre_cmp);
     c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;
 
     get_limits(s, 16*mb_x, 16*mb_y);
@@ -1457,7 +1449,7 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s,
         c->pred_y = P_MEDIAN[1];
     }
 
-    dmin = epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift);       
+    dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16);       
 
     s->p_mv_table[xy][0] = mx<<shift;
     s->p_mv_table[xy][1] = my<<shift;
@@ -1477,9 +1469,9 @@ static int ff_estimate_motion_b(MpegEncContext * s,
     uint8_t * const mv_penalty= c->mv_penalty[f_code] + MAX_MV;
     int mv_scale;
         
-    c->penalty_factor    = get_penalty_factor(s, c->avctx->me_cmp);
-    c->sub_penalty_factor= get_penalty_factor(s, c->avctx->me_sub_cmp);
-    c->mb_penalty_factor = get_penalty_factor(s, c->avctx->mb_cmp);
+    c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
+    c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
+    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);
     c->current_mv_penalty= mv_penalty;
 
     get_limits(s, 16*mb_x, 16*mb_y);
@@ -1540,7 +1532,7 @@ static int ff_estimate_motion_b(MpegEncContext * s,
             mv_scale= ((s->pb_time - s->pp_time)<<16) / (s->pp_time<<shift);
         }
         
-        dmin = epzs_motion_search(s, &mx, &my, P, 0, ref_index, s->p_mv_table, mv_scale);
+        dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, ref_index, s->p_mv_table, mv_scale, 0, 16);
  
         break;
     }
@@ -1548,7 +1540,7 @@ static int ff_estimate_motion_b(MpegEncContext * s,
     dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, ref_index, 0, 16);
                                    
     if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
-        dmin= get_mb_score(s, mx, my, 0, ref_index);
+        dmin= ff_get_mb_score(s, mx, my, 0, ref_index, 0, 16, 1);
 
 //printf("%d %d %d %d//", s->mb_x, s->mb_y, mx, my);
 //    s->mb_type[mb_y*s->mb_width + mb_x]= mb_type;
@@ -1731,14 +1723,14 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
         P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
     }
  
-    dmin = epzs_motion_search(s, &mx, &my, P, 0, 0, mv_table, 1<<(16-shift));
+    dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, mv_table, 1<<(16-shift), 0, 16);
     if(c->sub_flags&FLAG_QPEL) 
         dmin = qpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
     else
         dmin = hpel_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
     
     if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)
-        dmin= get_mb_score(s, mx, my, 0, 0);
+        dmin= ff_get_mb_score(s, mx, my, 0, 0, 0, 16, 1);
     
     get_limits(s, 16*mb_x, 16*mb_y); //restore c->?min/max, maybe not needed
 
@@ -1899,7 +1891,7 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type)
 {
     if(s->me_method>=ME_EPZS){
         int score[8];
-        int i, y;
+        int i, y, range= s->avctx->me_range;
         uint8_t * fcode_tab= s->fcode_tab;
         int best_fcode=-1;
         int best_score=-10000000;
@@ -1911,10 +1903,18 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type)
             int xy= y*s->mb_stride;
             for(x=0; x<s->mb_width; x++){
                 if(s->mb_type[xy] & type){
-                    int fcode= FFMAX(fcode_tab[mv_table[xy][0] + MAX_MV],
-                                     fcode_tab[mv_table[xy][1] + MAX_MV]);
+                    int mx= mv_table[xy][0];
+                    int my= mv_table[xy][1];
+                    int fcode= FFMAX(fcode_tab[mx + MAX_MV],
+                                     fcode_tab[my + MAX_MV]);
                     int j;
                     
+                    if(range){
+                        if(mx >= range || mx < -range || 
+                           my >= range || my < -range)
+                            continue;
+                    }
+                    
                     for(j=0; j<fcode && j<8; j++){
                         if(s->pict_type==B_TYPE || s->current_picture.mc_mb_var[xy] < s->current_picture.mb_var[xy])
                             score[j]-= 170;