]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h264.c
vertically aligning as per Michael's suggestion
[ffmpeg] / libavcodec / h264.c
index e3337fd1bae822944326eb7f9c851af40b87faf9..6e163937026869038da8d5c13014f1d486b3afc8 100644 (file)
@@ -86,11 +86,11 @@ static av_always_inline uint32_t pack16to32(int a, int b){
 #endif
 }
 
-const uint8_t ff_rem6[52]={
+static const uint8_t rem6[52]={
 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,
 };
 
-const uint8_t ff_div6[52]={
+static const uint8_t div6[52]={
 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
 };
 
@@ -182,19 +182,19 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){
         left_type[0] = h->slice_table[left_xy[0] ] < 255 ? s->current_picture.mb_type[left_xy[0]] : 0;
         left_type[1] = h->slice_table[left_xy[1] ] < 255 ? s->current_picture.mb_type[left_xy[1]] : 0;
 
-        if(FRAME_MBAFF && !IS_INTRA(mb_type)){
+        if(MB_MBAFF && !IS_INTRA(mb_type)){
             int list;
             for(list=0; list<h->list_count; list++){
+                //These values where changed for ease of performing MC, we need to change them back
+                //FIXME maybe we can make MC and loop filter use the same values or prevent
+                //the MC code from changing ref_cache and rather use a temporary array.
                 if(USES_LIST(mb_type,list)){
                     int8_t *ref = &s->current_picture.ref_index[list][h->mb2b8_xy[mb_xy]];
                     *(uint32_t*)&h->ref_cache[list][scan8[ 0]] =
-                    *(uint32_t*)&h->ref_cache[list][scan8[ 2]] = pack16to32(ref[0],ref[1])*0x0101;
+                    *(uint32_t*)&h->ref_cache[list][scan8[ 2]] = (pack16to32(ref[0],ref[1])&0x00FF00FF)*0x0101;
                     ref += h->b8_stride;
                     *(uint32_t*)&h->ref_cache[list][scan8[ 8]] =
-                    *(uint32_t*)&h->ref_cache[list][scan8[10]] = pack16to32(ref[0],ref[1])*0x0101;
-                }else{
-                    fill_rectangle(&h-> mv_cache[list][scan8[ 0]], 4, 4, 8, 0, 4);
-                    fill_rectangle(&h->ref_cache[list][scan8[ 0]], 4, 4, 8, (uint8_t)LIST_NOT_USED, 1);
+                    *(uint32_t*)&h->ref_cache[list][scan8[10]] = (pack16to32(ref[0],ref[1])&0x00FF00FF)*0x0101;
                 }
             }
         }
@@ -204,30 +204,49 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){
         topright_type= h->slice_table[topright_xy] == h->slice_num ? s->current_picture.mb_type[topright_xy]: 0;
         left_type[0] = h->slice_table[left_xy[0] ] == h->slice_num ? s->current_picture.mb_type[left_xy[0]] : 0;
         left_type[1] = h->slice_table[left_xy[1] ] == h->slice_num ? s->current_picture.mb_type[left_xy[1]] : 0;
-    }
 
     if(IS_INTRA(mb_type)){
+        int type_mask= h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1;
         h->topleft_samples_available=
         h->top_samples_available=
         h->left_samples_available= 0xFFFF;
         h->topright_samples_available= 0xEEEA;
 
-        if(!IS_INTRA(top_type) && (top_type==0 || h->pps.constrained_intra_pred)){
+        if(!(top_type & type_mask)){
             h->topleft_samples_available= 0xB3FF;
             h->top_samples_available= 0x33FF;
             h->topright_samples_available= 0x26EA;
         }
-        for(i=0; i<2; i++){
-            if(!IS_INTRA(left_type[i]) && (left_type[i]==0 || h->pps.constrained_intra_pred)){
+        if(IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[0])){
+            if(IS_INTERLACED(mb_type)){
+                if(!(left_type[0] & type_mask)){
+                    h->topleft_samples_available&= 0xDFFF;
+                    h->left_samples_available&= 0x5FFF;
+                }
+                if(!(left_type[1] & type_mask)){
+                    h->topleft_samples_available&= 0xFF5F;
+                    h->left_samples_available&= 0xFF5F;
+                }
+            }else{
+                int left_typei = h->slice_table[left_xy[0] + s->mb_stride ] == h->slice_num
+                                ? s->current_picture.mb_type[left_xy[0] + s->mb_stride] : 0;
+                assert(left_xy[0] == left_xy[1]);
+                if(!((left_typei & type_mask) && (left_type[0] & type_mask))){
+                    h->topleft_samples_available&= 0xDF5F;
+                    h->left_samples_available&= 0x5F5F;
+                }
+            }
+        }else{
+            if(!(left_type[0] & type_mask)){
                 h->topleft_samples_available&= 0xDF5F;
                 h->left_samples_available&= 0x5F5F;
             }
         }
 
-        if(!IS_INTRA(topleft_type) && (topleft_type==0 || h->pps.constrained_intra_pred))
+        if(!(topleft_type & type_mask))
             h->topleft_samples_available&= 0x7FFF;
 
-        if(!IS_INTRA(topright_type) && (topright_type==0 || h->pps.constrained_intra_pred))
+        if(!(topright_type & type_mask))
             h->topright_samples_available&= 0xFBFF;
 
         if(IS_INTRA4x4(mb_type)){
@@ -238,7 +257,7 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){
                 h->intra4x4_pred_mode_cache[7+8*0]= h->intra4x4_pred_mode[top_xy][3];
             }else{
                 int pred;
-                if(!top_type || (IS_INTER(top_type) && h->pps.constrained_intra_pred))
+                if(!(top_type & type_mask))
                     pred= -1;
                 else{
                     pred= 2;
@@ -254,7 +273,7 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){
                     h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[1+2*i]];
                 }else{
                     int pred;
-                    if(!left_type[i] || (IS_INTER(left_type[i]) && h->pps.constrained_intra_pred))
+                    if(!(left_type[i] & type_mask))
                         pred= -1;
                     else{
                         pred= 2;
@@ -265,6 +284,7 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){
             }
         }
     }
+    }
 
 
 /*
@@ -391,7 +411,7 @@ static void fill_caches(H264Context *h, int mb_type, int for_deblock){
                 }
             }
 
-            if((for_deblock || (IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred)) && !FRAME_MBAFF)
+            if(for_deblock || ((IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred) && !FRAME_MBAFF))
                 continue;
 
             if(USES_LIST(topleft_type, list)){
@@ -565,8 +585,10 @@ static inline int check_intra4x4_pred_mode(H264Context *h){
         }
     }
 
-    if(!(h->left_samples_available&0x8000)){
+    if((h->left_samples_available&0x8888)!=0x8888){
+        static const int mask[4]={0x8000,0x2000,0x80,0x20};
         for(i=0; i<4; i++){
+            if(!(h->left_samples_available&mask[i])){
             int status= left[ h->intra4x4_pred_mode_cache[scan8[0] + 8*i] ];
             if(status<0){
                 av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra4x4 mode %d at %d %d\n", status, s->mb_x, s->mb_y);
@@ -574,6 +596,7 @@ static inline int check_intra4x4_pred_mode(H264Context *h){
             } else if(status){
                 h->intra4x4_pred_mode_cache[scan8[0] + 8*i]= status;
             }
+            }
         }
     }
 
@@ -601,8 +624,11 @@ static inline int check_intra_pred_mode(H264Context *h, int mode){
         }
     }
 
-    if(!(h->left_samples_available&0x8000)){
+    if((h->left_samples_available&0x8080) != 0x8080){
         mode= left[ mode ];
+        if(h->left_samples_available&0x8080){ //mad cow disease mode, aka MBAFF + constrained_intra_pred
+            mode= ALZHEIMER_DC_L0T_PRED8x8 + (!(h->left_samples_available&0x8000)) + 2*(mode == DC_128_PRED8x8);
+        }
         if(mode<0){
             av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y);
             return -1;
@@ -868,68 +894,96 @@ static inline void pred_pskip_motion(H264Context * const h, int * const mx, int
     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);
-        }
+        h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i);
     }
-    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];
+}
+
+static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){
+    MpegEncContext * const s = &h->s;
+    Picture * const ref1 = &h->ref_list[1][0];
+    int j, old_ref, rfield;
+    int start= mbafi ? 16                      : 0;
+    int end  = mbafi ? 16+2*h->ref_count[list] : h->ref_count[list];
+    int interl= mbafi || s->picture_structure != PICT_FRAME;
+
+    /* bogus; fills in for missing frames */
+    memset(map[list], 0, sizeof(map[list]));
+
+    for(rfield=0; rfield<2; rfield++){
+        for(old_ref=0; old_ref<ref1->ref_count[colfield][list]; old_ref++){
+            int poc = ref1->ref_poc[colfield][list][old_ref];
+
+            if     (!interl)
+                poc |= 3;
+            else if( interl && (poc&3) == 3) //FIXME store all MBAFF references so this isnt needed
+                poc= (poc&~3) + rfield + 1;
+
+            for(j=start; j<end; j++){
+                if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){
+                    int cur_ref= mbafi ? (j-16)^field : j;
+                    map[list][2*old_ref + (rfield^field) + 16] = cur_ref;
+                    if(rfield == field)
+                        map[list][old_ref] = cur_ref;
+                    break;
+                }
+            }
         }
     }
 }
+
 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 sidx= s->picture_structure&1;
-    int ref1sidx= ref1->reference&1;
+    int list, j, field;
+    int sidx= (s->picture_structure&1)^1;
+    int ref1sidx= (ref1->reference&1)^1;
+
     for(list=0; list<2; list++){
         cur->ref_count[sidx][list] = h->ref_count[list];
         for(j=0; j<h->ref_count[list]; j++)
             cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3);
     }
+
     if(s->picture_structure == PICT_FRAME){
-        memcpy(cur->ref_count[0], cur->ref_count[1], sizeof(cur->ref_count[0]));
-        memcpy(cur->ref_poc  [0], cur->ref_poc  [1], sizeof(cur->ref_poc  [0]));
+        memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0]));
+        memcpy(cur->ref_poc  [1], cur->ref_poc  [0], sizeof(cur->ref_poc  [0]));
     }
+
+    cur->mbaff= FRAME_MBAFF;
+
     if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred)
         return;
+
     for(list=0; list<2; list++){
-        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))
-                poc= (poc&~3) + s->picture_structure;
-            h->map_col_to_list0[list][i] = 0; /* bogus; fills in for missing frames */
-            for(j=0; j<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[list][i] = j;
-                    break;
-                }
-        }
-    }
-    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;
-            }
-        }
+        fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0);
+        for(field=0; field<2; field++)
+            fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1);
     }
 }
 
@@ -948,15 +1002,13 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){
 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)
 
     if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL
-        if(h->ref_list[1][0].reference == PICT_FRAME){   // AFL/AFR/FR/FL -> AFL
-            if(!IS_INTERLACED(*mb_type)){                //     AFR/FR    -> AFL
-                int cur_poc = s->current_picture_ptr->poc;
-                int *col_poc = h->ref_list[1]->field_poc;
-                int col_parity = FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc);
-                mb_xy= s->mb_x + ((s->mb_y&~1) + col_parity)*s->mb_stride;
-                b8_stride = 0;
-            }
-        }else if(!(s->picture_structure & h->ref_list[1][0].reference)){// FL -> FL & differ parity
+        if(!IS_INTERLACED(*mb_type)){                    //     AFR/FR    -> AFL/FL
+            int cur_poc = s->current_picture_ptr->poc;
+            int *col_poc = h->ref_list[1]->field_poc;
+            int col_parity = FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc);
+            mb_xy= s->mb_x + ((s->mb_y&~1) + col_parity)*s->mb_stride;
+            b8_stride = 0;
+        }else if(!(s->picture_structure & h->ref_list[1][0].reference) && !h->ref_list[1][0].mbaff){// FL -> FL & differ parity
             int fieldoff= 2*(h->ref_list[1][0].reference)-3;
             mb_xy += s->mb_stride*fieldoff;
         }
@@ -1142,16 +1194,19 @@ single_col:
     }else{ /* direct temporal mv pred */
         const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]};
         const int *dist_scale_factor = h->dist_scale_factor;
+        int ref_offset= 0;
 
         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(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0]))
+            ref_offset += 16;
+
         if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){
             /* FIXME assumes direct_8x8_inference == 1 */
             int y_shift  = 2*!IS_INTERLACED(*mb_type);
-            int ref_shift= FRAME_MBAFF ? y_shift : 1;
 
             for(i8=0; i8<4; i8++){
                 const int x8 = i8&1;
@@ -1173,9 +1228,9 @@ single_col:
 
                 ref0 = l1ref0[x8 + y8*b8_stride];
                 if(ref0 >= 0)
-                    ref0 = map_col_to_list0[0][ref0*2>>ref_shift];
+                    ref0 = map_col_to_list0[0][ref0 + ref_offset];
                 else{
-                    ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride]*2>>ref_shift];
+                    ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset];
                     l1mv= l1mv1;
                 }
                 scale = dist_scale_factor[ref0];
@@ -1202,8 +1257,8 @@ single_col:
             if(IS_INTRA(mb_type_col[0])){
                 ref=mv0=mv1=0;
             }else{
-                const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0]]
-                                                : map_col_to_list0[1][l1ref1[0]];
+                const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset]
+                                                : map_col_to_list0[1][l1ref1[0] + ref_offset];
                 const int scale = dist_scale_factor[ref0];
                 const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];
                 int mv_l0[2];
@@ -1234,11 +1289,11 @@ single_col:
                     continue;
                 }
 
-                ref0 = l1ref0[x8 + y8*b8_stride];
+                ref0 = l1ref0[x8 + y8*b8_stride] + ref_offset;
                 if(ref0 >= 0)
                     ref0 = map_col_to_list0[0][ref0];
                 else{
-                    ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride]];
+                    ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset];
                     l1mv= l1mv1;
                 }
                 scale = dist_scale_factor[ref0];
@@ -1979,12 +2034,6 @@ static void free_tables(H264Context *h){
     av_freep(&h->mb2b_xy);
     av_freep(&h->mb2b8_xy);
 
-    for(i = 0; i < MAX_SPS_COUNT; i++)
-        av_freep(h->sps_buffers + i);
-
-    for(i = 0; i < MAX_PPS_COUNT; i++)
-        av_freep(h->pps_buffers + i);
-
     for(i = 0; i < h->s.avctx->thread_count; i++) {
         hx = h->thread_context[i];
         if(!hx) continue;
@@ -2007,8 +2056,8 @@ static void init_dequant8_coeff_table(H264Context *h){
         }
 
         for(q=0; q<52; q++){
-            int shift = ff_div6[q];
-            int idx = ff_rem6[q];
+            int shift = div6[q];
+            int idx = rem6[q];
             for(x=0; x<64; x++)
                 h->dequant8_coeff[i][q][transpose ? (x>>3)|((x&7)<<3) : x] =
                     ((uint32_t)dequant8_coeff_init[idx][ dequant8_coeff_init_scan[((x>>1)&12) | (x&3)] ] *
@@ -2032,8 +2081,8 @@ static void init_dequant4_coeff_table(H264Context *h){
             continue;
 
         for(q=0; q<52; q++){
-            int shift = ff_div6[q] + 2;
-            int idx = ff_rem6[q];
+            int shift = div6[q] + 2;
+            int idx = rem6[q];
             for(x=0; x<16; x++)
                 h->dequant4_coeff[i][q][transpose ? (x>>2)|((x<<2)&0xF) : x] =
                     ((uint32_t)dequant4_coeff_init[idx][(x&1) + ((x>>2)&1)] *
@@ -2189,6 +2238,7 @@ static av_cold int decode_init(AVCodecContext *avctx){
 
     h->thread_context[0] = h;
     h->outputed_poc = INT_MIN;
+    h->prev_poc_msb= 1<<16;
     return 0;
 }
 
@@ -2341,7 +2391,7 @@ static inline void xchg_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_c
         deblock_top  = h->slice_table[mb_xy] == h->slice_table[h->top_mb_xy];
     } else {
         deblock_left = (s->mb_x > 0);
-        deblock_top =  (s->mb_y > 0);
+        deblock_top =  (s->mb_y > !!MB_FIELD);
     }
 
     src_y  -=   linesize + 1;
@@ -2395,7 +2445,6 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
     int linesize, uvlinesize /*dct_offset*/;
     int i;
     int *block_offset = &h->block_offset[0];
-    const unsigned int bottom = mb_y & 1;
     const int transform_bypass = (s->qscale == 0 && h->sps.transform_bypass), is_h264 = (simple || s->codec_id == CODEC_ID_H264);
     void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
     void (*idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride);
@@ -2426,7 +2475,6 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
                     fill_rectangle(ref, 4, 4, 8, (16+*ref)^(s->mb_y&1), 1);
                 }else{
                     for(i=0; i<16; i+=4){
-                        //FIXME can refs be smaller than 8x8 when !direct_8x8_inference ?
                         int ref = h->ref_cache[list][scan8[i]];
                         if(ref >= 0)
                             fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2, 8, (16+ref)^(s->mb_y&1), 1);
@@ -2894,9 +2942,6 @@ static int decode_ref_pic_list_reordering(H264Context *h){
         }
     }
 
-    if(h->slice_type_nos==FF_B_TYPE && !h->direct_spatial_mv_pred)
-        direct_dist_scale_factor(h);
-    direct_ref_list_init(h);
     return 0;
 }
 
@@ -2910,10 +2955,12 @@ static void fill_mbaff_ref_list(H264Context *h){
             for(j=0; j<3; j++)
                 field[0].linesize[j] <<= 1;
             field[0].reference = PICT_TOP_FIELD;
+            field[0].poc= field[0].field_poc[0];
             field[1] = field[0];
             for(j=0; j<3; j++)
                 field[1].data[j] += frame->linesize[j];
             field[1].reference = PICT_BOTTOM_FIELD;
+            field[1].poc= field[1].field_poc[1];
 
             h->luma_weight[list][16+2*i] = h->luma_weight[list][16+2*i+1] = h->luma_weight[list][i];
             h->luma_offset[list][16+2*i] = h->luma_offset[list][16+2*i+1] = h->luma_offset[list][i];
@@ -3872,6 +3919,15 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
     if(h->slice_type_nos!=FF_I_TYPE && decode_ref_pic_list_reordering(h) < 0)
         return -1;
 
+    if(h->slice_type_nos!=FF_I_TYPE){
+        s->last_picture_ptr= &h->ref_list[0][0];
+        ff_copy_picture(&s->last_picture, s->last_picture_ptr);
+    }
+    if(h->slice_type_nos==FF_B_TYPE){
+        s->next_picture_ptr= &h->ref_list[1][0];
+        ff_copy_picture(&s->next_picture, s->next_picture_ptr);
+    }
+
     if(   (h->pps.weighted_pred          && h->slice_type_nos == FF_P_TYPE )
        ||  (h->pps.weighted_bipred_idc==1 && h->slice_type_nos== FF_B_TYPE ) )
         pred_weight_table(h);
@@ -3886,6 +3942,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
     if(FRAME_MBAFF)
         fill_mbaff_ref_list(h);
 
+    if(h->slice_type_nos==FF_B_TYPE && !h->direct_spatial_mv_pred)
+        direct_dist_scale_factor(h);
+    direct_ref_list_init(h);
+
     if( h->slice_type_nos != FF_I_TYPE && h->pps.cabac ){
         tmp = get_ue_golomb(&s->gb);
         if(tmp > 2){
@@ -3965,20 +4025,25 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
         int *ref2frm= h->ref2frm[h->slice_num&15][j];
         ref2frm[0]=
         ref2frm[1]= -1;
-        for(i=0; i<48; i++)
+        for(i=0; i<16; i++)
             ref2frm[i+2]= 4*h->ref_list[j][i].frame_num
                           +(h->ref_list[j][i].reference&3);
+        ref2frm[18+0]=
+        ref2frm[18+1]= -1;
+        for(i=16; i<48; i++)
+            ref2frm[i+4]= 4*h->ref_list[j][i].frame_num
+                          +(h->ref_list[j][i].reference&3);
     }
 
     h->emu_edge_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16;
     h->emu_edge_height= (FRAME_MBAFF || FIELD_PICTURE) ? 0 : h->emu_edge_width;
 
     if(s->avctx->debug&FF_DEBUG_PICT_INFO){
-        av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",
+        av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",
                h->slice_num,
                (s->picture_structure==PICT_FRAME ? "F" : s->picture_structure==PICT_TOP_FIELD ? "T" : "B"),
                first_mb_in_slice,
-               av_get_pict_type_char(h->slice_type),
+               av_get_pict_type_char(h->slice_type), h->slice_type_fixed ? " fix" : "", h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",
                pps_id, h->frame_num,
                s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1],
                h->ref_count[0], h->ref_count[1],
@@ -6321,8 +6386,10 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
                 if( IS_INTRA( s->current_picture.mb_type[mbn_xy] ) )
                     bS[i] = 4;
                 else if( h->non_zero_count_cache[12+8*(i>>1)] != 0 ||
-                         /* FIXME: with 8x8dct + cavlc, should check cbp instead of nnz */
-                         h->non_zero_count[mbn_xy][MB_FIELD ? i&3 : (i>>2)+(mb_y&1)*2] )
+                         ((!h->pps.cabac && IS_8x8DCT(s->current_picture.mb_type[mbn_xy])) ?
+                            (h->cbp_table[mbn_xy] & ((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2))
+                                                                       :
+                            h->non_zero_count[mbn_xy][MB_FIELD ? i&3 : (i>>2)+(mb_y&1)*2]))
                     bS[i] = 2;
                 else
                     bS[i] = 1;
@@ -6356,8 +6423,8 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
         int edge;
         const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy;
         const int mbm_type = s->current_picture.mb_type[mbm_xy];
-        int (*ref2frm) [48+2] = h->ref2frm[ h->slice_num          &15 ];
-        int (*ref2frmm)[48+2] = h->ref2frm[ h->slice_table[mbm_xy]&15 ];
+        int (*ref2frm) [64] = h->ref2frm[ h->slice_num          &15 ][0] + (MB_MBAFF ? 20 : 2);
+        int (*ref2frmm)[64] = h->ref2frm[ h->slice_table[mbm_xy]&15 ][0] + (MB_MBAFF ? 20 : 2);
         int start = h->slice_table[mbm_xy] == 255 ? 1 : 0;
 
         const int edges = (mb_type & (MB_TYPE_16x16|MB_TYPE_SKIP))
@@ -6426,7 +6493,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
             /* mbn_xy: neighbor macroblock */
             const int mbn_xy = edge > 0 ? mb_xy : mbm_xy;
             const int mbn_type = s->current_picture.mb_type[mbn_xy];
-            int (*ref2frmn)[48+2] = edge > 0 ? ref2frm : ref2frmm;
+            int (*ref2frmn)[64] = edge > 0 ? ref2frm : ref2frmm;
             int16_t bS[4];
             int qp;
 
@@ -6466,7 +6533,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
                     int v = 0;
 
                     for( l = 0; !v && l < 1 + (h->slice_type_nos == FF_B_TYPE); l++ ) {
-                        v |= ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[l][h->ref_cache[l][bn_idx]+2] ||
+                        v |= ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[l][h->ref_cache[l][bn_idx]] ||
                              FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 ||
                              FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= mvy_limit;
                     }
@@ -6475,7 +6542,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
                         v=0;
                         for( l = 0; !v && l < 2; l++ ) {
                             int ln= 1-l;
-                            v |= ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[ln][h->ref_cache[ln][bn_idx]+2] ||
+                            v |= ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[ln][h->ref_cache[ln][bn_idx]] ||
                                 FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[ln][bn_idx][0] ) >= 4 ||
                                 FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[ln][bn_idx][1] ) >= mvy_limit;
                         }
@@ -6501,7 +6568,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
                     {
                         bS[i] = 0;
                         for( l = 0; l < 1 + (h->slice_type_nos == FF_B_TYPE); l++ ) {
-                            if( ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[l][h->ref_cache[l][bn_idx]+2] ||
+                            if( ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[l][h->ref_cache[l][bn_idx]] ||
                                 FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 ||
                                 FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= mvy_limit ) {
                                 bS[i] = 1;
@@ -6513,7 +6580,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
                             bS[i] = 0;
                             for( l = 0; l < 2; l++ ) {
                                 int ln= 1-l;
-                                if( ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[ln][h->ref_cache[ln][bn_idx]+2] ||
+                                if( ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[ln][h->ref_cache[ln][bn_idx]] ||
                                     FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[ln][bn_idx][0] ) >= 4 ||
                                     FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[ln][bn_idx][1] ) >= mvy_limit ) {
                                     bS[i] = 1;
@@ -6932,9 +6999,6 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s
             decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]);  // Intra, Y
             decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[1],fallback[3]);  // Inter, Y
         }
-    } else if(fallback_sps) {
-        memcpy(scaling_matrix4, sps->scaling_matrix4, 6*16*sizeof(uint8_t));
-        memcpy(scaling_matrix8, sps->scaling_matrix8, 2*64*sizeof(uint8_t));
     }
 }
 
@@ -6981,6 +7045,10 @@ static inline int decode_seq_parameter_set(H264Context *h){
     sps->profile_idc= profile_idc;
     sps->level_idc= level_idc;
 
+    memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
+    memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8));
+    sps->scaling_matrix_present = 0;
+
     if(sps->profile_idc >= 100){ //high profile
         sps->chroma_format_idc= get_ue_golomb(&s->gb);
         if(sps->chroma_format_idc == 3)
@@ -6990,7 +7058,6 @@ static inline int decode_seq_parameter_set(H264Context *h){
         sps->transform_bypass = get_bits1(&s->gb);
         decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8);
     }else{
-        sps->scaling_matrix_present = 0;
         sps->chroma_format_idc= 1;
     }
 
@@ -7047,9 +7114,6 @@ static inline int decode_seq_parameter_set(H264Context *h){
     if(sps->mb_aff)
         av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n");
 #endif
-    if(!sps->direct_8x8_inference_flag && sps->mb_aff)
-        av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF + !direct_8x8_inference is not implemented\n");
-
     sps->crop= get_bits1(&s->gb);
     if(sps->crop){
         sps->crop_left  = get_ue_golomb(&s->gb);
@@ -7059,7 +7123,7 @@ static inline int decode_seq_parameter_set(H264Context *h){
         if(sps->crop_left || sps->crop_top){
             av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n");
         }
-        if(sps->crop_right >= 8 || sps->crop_bottom >= (8>> !h->sps.frame_mbs_only_flag)){
+        if(sps->crop_right >= 8 || sps->crop_bottom >= (8>> !sps->frame_mbs_only_flag)){
             av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n");
         }
     }else{
@@ -7173,8 +7237,8 @@ static inline int decode_picture_parameter_set(H264Context *h, int bit_length){
 
     pps->transform_8x8_mode= 0;
     h->dequant_coeff_pps= -1; //contents of sps/pps can change even if id doesn't, so reinit
-    memset(pps->scaling_matrix4, 16, 6*16*sizeof(uint8_t));
-    memset(pps->scaling_matrix8, 16, 2*64*sizeof(uint8_t));
+    memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4));
+    memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8));
 
     if(get_bits_count(&s->gb) < bit_length){
         pps->transform_8x8_mode= get_bits1(&s->gb);
@@ -7224,7 +7288,7 @@ static void execute_decode_slices(H264Context *h, int context_count){
     } else {
         for(i = 1; i < context_count; i++) {
             hx = h->thread_context[i];
-            hx->s.error_resilience = avctx->error_resilience;
+            hx->s.error_recognition = avctx->error_recognition;
             hx->s.error_count = 0;
         }
 
@@ -7458,7 +7522,7 @@ static int decode_frame(AVCodecContext *avctx,
 //FIXME factorize this with the output code below
         out = h->delayed_pic[0];
         out_idx = 0;
-        for(i=1; h->delayed_pic[i] && h->delayed_pic[i]->poc; i++)
+        for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc && !h->delayed_pic[i]->key_frame); i++)
             if(h->delayed_pic[i]->poc < out->poc){
                 out = h->delayed_pic[i];
                 out_idx = i;
@@ -7516,9 +7580,10 @@ static int decode_frame(AVCodecContext *avctx,
         h->got_avcC = 1;
     }
 
-    if(avctx->frame_number==0 && !h->is_avc && s->avctx->extradata_size){
+    if(!h->got_avcC && !h->is_avc && s->avctx->extradata_size){
         if(decode_nal_units(h, s->avctx->extradata, s->avctx->extradata_size) < 0)
             return -1;
+        h->got_avcC = 1;
     }
 
     buf_index=decode_nal_units(h, buf, buf_size);
@@ -7602,12 +7667,12 @@ static int decode_frame(AVCodecContext *avctx,
 
             out = h->delayed_pic[0];
             out_idx = 0;
-            for(i=1; h->delayed_pic[i] && h->delayed_pic[i]->poc; i++)
+            for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc && !h->delayed_pic[i]->key_frame); i++)
                 if(h->delayed_pic[i]->poc < out->poc){
                     out = h->delayed_pic[i];
                     out_idx = i;
                 }
-            cross_idr = !h->delayed_pic[0]->poc || !!h->delayed_pic[i];
+            cross_idr = !h->delayed_pic[0]->poc || !!h->delayed_pic[i] || h->delayed_pic[0]->key_frame;
 
             out_of_order = !cross_idr && out->poc < h->outputed_poc;
 
@@ -7849,10 +7914,18 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     H264Context *h = avctx->priv_data;
     MpegEncContext *s = &h->s;
+    int i;
 
     av_freep(&h->rbsp_buffer[0]);
     av_freep(&h->rbsp_buffer[1]);
     free_tables(h); //FIXME cleanup init stuff perhaps
+
+    for(i = 0; i < MAX_SPS_COUNT; i++)
+        av_freep(h->sps_buffers + i);
+
+    for(i = 0; i < MAX_PPS_COUNT; i++)
+        av_freep(h->pps_buffers + i);
+
     MPV_common_end(s);
 
 //    memset(h, 0, sizeof(H264Context));