changeset 7898:a33287a39a55 libavcodec

Make MBAFF temporal direct mode closer to the spec. Fixes at least: CAMANL2_TOSHIBA_B CVMANL2_TOSHIBA_B camp_mot_mbaff0_full
author michael
date Sun, 21 Sep 2008 02:39:09 +0000
parents 004f3c69fe7b
children d63895a8eabb
files h264.c h264.h
diffstat 2 files changed, 44 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/h264.c	Sun Sep 21 02:23:51 2008 +0000
+++ b/h264.c	Sun Sep 21 02:39:09 2008 +0000
@@ -894,34 +894,39 @@
     return;
 }
 
+static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){
+    int poc0 = h->ref_list[0][i].poc;
+    int td = av_clip(poc1 - poc0, -128, 127);
+    if(td == 0 || h->ref_list[0][i].long_ref){
+        return 256;
+    }else{
+        int tb = av_clip(poc - poc0, -128, 127);
+        int tx = (16384 + (FFABS(td) >> 1)) / td;
+        return av_clip((tb*tx + 32) >> 6, -1024, 1023);
+    }
+}
+
 static inline void direct_dist_scale_factor(H264Context * const h){
     MpegEncContext * const s = &h->s;
     const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ];
     const int poc1 = h->ref_list[1][0].poc;
-    int i;
+    int i, field;
+    for(field=0; field<2; field++){
+        const int poc  = h->s.current_picture_ptr->field_poc[field];
+        const int poc1 = h->ref_list[1][0].field_poc[field];
+        for(i=0; i < 2*h->ref_count[0]; i++)
+            h->dist_scale_factor_field[field][i^field] = get_scale_factor(h, poc, poc1, i+16);
+    }
+
     for(i=0; i<h->ref_count[0]; i++){
-        int poc0 = h->ref_list[0][i].poc;
-        int td = av_clip(poc1 - poc0, -128, 127);
-        if(td == 0 || h->ref_list[0][i].long_ref){
-            h->dist_scale_factor[i] = 256;
-        }else{
-            int tb = av_clip(poc - poc0, -128, 127);
-            int tx = (16384 + (FFABS(td) >> 1)) / td;
-            h->dist_scale_factor[i] = av_clip((tb*tx + 32) >> 6, -1024, 1023);
-        }
-    }
-    if(FRAME_MBAFF){
-        for(i=0; i<h->ref_count[0]; i++){
-            h->dist_scale_factor_field[2*i] =
-            h->dist_scale_factor_field[2*i+1] = h->dist_scale_factor[i];
-        }
+        h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i);
     }
 }
 static inline void direct_ref_list_init(H264Context * const h){
     MpegEncContext * const s = &h->s;
     Picture * const ref1 = &h->ref_list[1][0];
     Picture * const cur = s->current_picture_ptr;
-    int list, i, j;
+    int list, i, j, field, rfield;
     int sidx= s->picture_structure&1;
     int ref1sidx= ref1->reference&1;
     for(list=0; list<2; list++){
@@ -936,6 +941,23 @@
     if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred)
         return;
     for(list=0; list<2; list++){
+        for(field=0; field<2; field++){
+            for(i=0; i<ref1->ref_count[field][list]; i++){
+                for(rfield=0; rfield<2; rfield++){
+                    int poc = ref1->ref_poc[field][list][i];
+                    if((poc&3) == 3)
+                        poc= (poc&~3) + rfield + 1;
+
+                    h->map_col_to_list0_field[field][list][2*i+rfield] = 0; /* bogus; fills in for missing frames */
+                    for(j=16; j<16+2*h->ref_count[list]; j++)
+                        if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){
+                            h->map_col_to_list0_field[field][list][2*i+rfield] = j-16;
+                            break;
+                        }
+                }
+            }
+        }
+
         for(i=0; i<ref1->ref_count[ref1sidx][list]; i++){
             int poc = ref1->ref_poc[ref1sidx][list][i];
             if(((poc&3) == 3) != (s->picture_structure == PICT_FRAME))
@@ -948,15 +970,6 @@
                 }
         }
     }
-    if(FRAME_MBAFF){
-        for(list=0; list<2; list++){
-            for(i=0; i<ref1->ref_count[ref1sidx][list]; i++){
-                j = h->map_col_to_list0[list][i];
-                h->map_col_to_list0_field[list][2*i] = 2*j;
-                h->map_col_to_list0_field[list][2*i+1] = 2*j+1;
-            }
-        }
-    }
 }
 
 static inline void pred_direct_motion(H264Context * const h, int *mb_type){
@@ -1170,9 +1183,9 @@
         const int *dist_scale_factor = h->dist_scale_factor;
 
         if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){
-            map_col_to_list0[0] = h->map_col_to_list0_field[0];
-            map_col_to_list0[1] = h->map_col_to_list0_field[1];
-            dist_scale_factor = h->dist_scale_factor_field;
+            map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0];
+            map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1];
+            dist_scale_factor   =h->dist_scale_factor_field[s->mb_y&1];
         }
         if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){
             /* FIXME assumes direct_8x8_inference == 1 */
--- a/h264.h	Sun Sep 21 02:23:51 2008 +0000
+++ b/h264.h	Sun Sep 21 02:39:09 2008 +0000
@@ -331,9 +331,9 @@
 
     int direct_spatial_mv_pred;
     int dist_scale_factor[16];
-    int dist_scale_factor_field[32];
+    int dist_scale_factor_field[2][32];
     int map_col_to_list0[2][16];
-    int map_col_to_list0_field[2][32];
+    int map_col_to_list0_field[2][2][32];
 
     /**
      * num_ref_idx_l0/1_active_minus1 + 1