]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/motion_est.c
Fixes:
[ffmpeg] / libavcodec / motion_est.c
index 7c20272c0acc31b6fd810bf128c1a271fdfc2af0..9ee75f7e9d1290e2908b5ae22a488a4bfc192f2c 100644 (file)
@@ -4,19 +4,21 @@
  * Copyright (c) 2002-2004 Michael Niedermayer
  *
  *
- * This library is free software; you can redistribute it and/or
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
  *
- * This library is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  *
  * new Motion Estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at>
  */
@@ -365,7 +367,7 @@ static int full_motion_search(MpegEncContext * s,
 #if 0
     if (*mx_ptr < -(2 * range) || *mx_ptr >= (2 * range) ||
         *my_ptr < -(2 * range) || *my_ptr >= (2 * range)) {
-        fprintf(stderr, "error %d %d\n", *mx_ptr, *my_ptr);
+        av_log(NULL, AV_LOG_ERROR, "error %d %d\n", *mx_ptr, *my_ptr);
     }
 #endif
     return dmin;
@@ -901,6 +903,8 @@ static int interlaced_search(MpegEncContext *s, int ref_index,
             int16_t (*mv_table)[2]= mv_tables[block][field_select];
 
             if(user_field_select){
+                assert(field_select==0 || field_select==1);
+                assert(field_select_tables[block][xy]==0 || field_select_tables[block][xy]==1);
                 if(field_select_tables[block][xy] != field_select)
                     continue;
             }
@@ -1179,7 +1183,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             if (vard <= 64<<8 || vard < varc) { //FIXME
                 c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
             }else{
-                c->scene_change_score+= s->qscale;
+                c->scene_change_score+= s->qscale * s->avctx->scenechange_factor;
             }
             return;
         }
@@ -1270,7 +1274,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
         if (vard <= 64<<8 || vard < varc)
             c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
         else
-            c->scene_change_score+= s->qscale;
+            c->scene_change_score+= s->qscale * s->avctx->scenechange_factor;
 
         if(mb_type == CANDIDATE_MB_TYPE_INTER){
             c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);
@@ -1291,7 +1295,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
         if (vard <= 64<<8 || vard < varc)
             c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
         else
-            c->scene_change_score+= s->qscale;
+            c->scene_change_score+= s->qscale * s->avctx->scenechange_factor;
 
         if (vard*2 + 200*256 > varc)
             mb_type|= CANDIDATE_MB_TYPE_INTRA;
@@ -1397,7 +1401,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
         if (vard <= 64<<8 || vard < varc) { //FIXME
             c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
         }else{
-            c->scene_change_score+= s->qscale;
+            c->scene_change_score+= s->qscale * s->avctx->scenechange_factor;
         }
     }
 
@@ -1636,6 +1640,12 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y)
     const int ymin= c->ymin<<shift;
     const int xmax= c->xmax<<shift;
     const int ymax= c->ymax<<shift;
+    uint8_t map[8][8][8][8];
+
+    memset(map,0,sizeof(map));
+#define BIDIR_MAP(fx,fy,bx,by) \
+    map[(motion_fx+fx)&7][(motion_fy+fy)&7][(motion_bx+bx)&7][(motion_by+by)&7]
+    BIDIR_MAP(0,0,0,0) = 1;
 
     fbmin= check_bidir_mv(s, motion_fx, motion_fy,
                           motion_bx, motion_by,
@@ -1646,8 +1656,10 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y)
     if(s->avctx->bidir_refine){
         int score, end;
 #define CHECK_BIDIR(fx,fy,bx,by)\
-    if(  (fx<=0 || motion_fx+fx<=xmax) && (fy<=0 || motion_fy+fy<=ymax) && (bx<=0 || motion_bx+bx<=xmax) && (by<=0 || motion_by+by<=ymax)\
+    if( !BIDIR_MAP(fx,fy,bx,by)\
+       &&(fx<=0 || motion_fx+fx<=xmax) && (fy<=0 || motion_fy+fy<=ymax) && (bx<=0 || motion_bx+bx<=xmax) && (by<=0 || motion_by+by<=ymax)\
        &&(fx>=0 || motion_fx+fx>=xmin) && (fy>=0 || motion_fy+fy>=ymin) && (bx>=0 || motion_bx+bx>=xmin) && (by>=0 || motion_by+by>=ymin)){\
+        BIDIR_MAP(fx,fy,bx,by) = 1;\
         score= check_bidir_mv(s, motion_fx+fx, motion_fy+fy, motion_bx+bx, motion_by+by, pred_fx, pred_fy, pred_bx, pred_by, 0, 16);\
         if(score < fbmin){\
             fbmin= score;\
@@ -1660,7 +1672,7 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y)
     }
 #define CHECK_BIDIR2(a,b,c,d)\
 CHECK_BIDIR(a,b,c,d)\
-CHECK_BIDIR(-a,-b,-c,-d)
+CHECK_BIDIR(-(a),-(b),-(c),-(d))
 
 #define CHECK_BIDIRR(a,b,c,d)\
 CHECK_BIDIR2(a,b,c,d)\
@@ -1696,6 +1708,11 @@ CHECK_BIDIR2(d,a,b,c)
         }while(!end);
     }
 
+    s->b_bidir_forw_mv_table[xy][0]= motion_fx;
+    s->b_bidir_forw_mv_table[xy][1]= motion_fy;
+    s->b_bidir_back_mv_table[xy][0]= motion_bx;
+    s->b_bidir_back_mv_table[xy][1]= motion_by;
+
     return fbmin;
 }
 
@@ -1830,7 +1847,7 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
 /*            if (vard <= 64<<8 || vard < varc) {
                 c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);
             }else{
-                c->scene_change_score+= s->qscale;
+                c->scene_change_score+= s->qscale * s->avctx->scenechange_factor;
             }*/
             return;
         }