changeset 2402:f9d4e1eddbc5 libavcodec

- correct several errors on the deblocking accross slice boundaries. - add support for deblocking_filter_idc==2 which means no deblocking accross slice. - correct MMCO with multiple slices. 5 more streams from H264 conformance suite are now correctly decoded. patch by (Loic <lll+ffmpeg >< m4x dot org>)
author michael
date Fri, 31 Dec 2004 00:07:17 +0000
parents 46898a9fd6dc
children 6d53608cf2cf
files h264.c
diffstat 1 files changed, 45 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/h264.c	Thu Dec 30 18:05:54 2004 +0000
+++ b/h264.c	Fri Dec 31 00:07:17 2004 +0000
@@ -947,7 +947,7 @@
         const int top_ref=      h->ref_cache[list][ scan8[0] - 8 ];
         const int16_t * const B= h->mv_cache[list][ scan8[0] - 8 ];
 
-        tprintf("pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d", top_ref, B[0], B[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf("pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n", top_ref, B[0], B[1], h->s.mb_x, h->s.mb_y, n, list);
         
         if(top_ref == ref){
             *mx= B[0];
@@ -958,7 +958,7 @@
         const int left_ref=     h->ref_cache[list][ scan8[8] - 1 ];
         const int16_t * const A= h->mv_cache[list][ scan8[8] - 1 ];
         
-        tprintf("pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d", left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf("pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n", left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
 
         if(left_ref == ref){
             *mx= A[0];
@@ -982,7 +982,7 @@
         const int left_ref=      h->ref_cache[list][ scan8[0] - 1 ];
         const int16_t * const A=  h->mv_cache[list][ scan8[0] - 1 ];
         
-        tprintf("pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d", left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf("pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n", left_ref, A[0], A[1], h->s.mb_x, h->s.mb_y, n, list);
 
         if(left_ref == ref){
             *mx= A[0];
@@ -995,7 +995,7 @@
 
         diagonal_ref= fetch_diagonal_mv(h, &C, scan8[4], list, 2);
         
-        tprintf("pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d", diagonal_ref, C[0], C[1], h->s.mb_x, h->s.mb_y, n, list);
+        tprintf("pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n", diagonal_ref, C[0], C[1], h->s.mb_x, h->s.mb_y, n, list);
 
         if(diagonal_ref == ref){ 
             *mx= C[0];
@@ -2495,7 +2495,6 @@
 
     MPV_frame_start(s, s->avctx);
     ff_er_frame_start(s);
-    h->mmco_index=0;
 
     assert(s->linesize && s->uvlinesize);
 
@@ -3088,7 +3087,7 @@
         } 
     }else{
         if(get_bits1(&s->gb)){ // adaptive_ref_pic_marking_mode_flag
-            for(i= h->mmco_index; i<MAX_MMCO_COUNT; i++) { 
+            for(i= 0; i<MAX_MMCO_COUNT; i++) { 
                 MMCOOpcode opcode= get_ue_golomb(&s->gb);;
 
                 h->mmco[i].opcode= opcode;
@@ -3389,6 +3388,7 @@
         av_log(s->avctx, AV_LOG_ERROR, "QP %d out of range\n", s->qscale);
         return -1;
     }
+    h->chroma_qp = get_chroma_qp(h, s->qscale);
     //FIXME qscale / qp ... stuff
     if(h->slice_type == SP_TYPE){
         get_bits1(&s->gb); /* sp_for_switch_flag */
@@ -5280,8 +5280,11 @@
         if( ( dir == 0 && mb_x == 0 ) || ( dir == 1 && mb_y == 0 ) ) {
             start = 1;
         }
-        /* FIXME test slice boundary */
-        if( h->deblocking_filter == 2 ) {
+        if( 0 == start && 2 == h->deblocking_filter) {
+            const int mbn_xy = dir == 0 ? mb_xy -1 : mb_xy - s->mb_stride;
+            if (h->slice_table[mbn_xy] != h->slice_table[mb_xy]) {
+                start = 1;
+            }
         }
 
         /* Calculate bS */
@@ -5296,20 +5299,49 @@
                 bS[0] = bS[1] = bS[2] = bS[3] = ( edge == 0 ? 4 : 3 );
             } else {
                 int i;
+                const int slice_boundary = (h->slice_table[mbn_xy] != h->slice_table[mb_xy]);
                 for( i = 0; i < 4; i++ ) {
                     int x = dir == 0 ? edge : i;
                     int y = dir == 0 ? i    : edge;
                     int b_idx= 8 + 4 + x + 8*y;
                     int bn_idx= b_idx - (dir ? 8:1);
+                    uint8_t left_non_zero_count;
+                    if (slice_boundary) {
+                        // must not use non_zero_count_cache, it is not valid
+                        // across slice boundaries
+                        if (0 == dir) {
+                            left_non_zero_count = h->non_zero_count[mbn_xy][6-i];
+                        } else {
+                            left_non_zero_count = h->non_zero_count[mbn_xy][i];
+                        }
+                    } else {
+                        left_non_zero_count = h->non_zero_count_cache[bn_idx];
+                    }
 
                     if( h->non_zero_count_cache[b_idx] != 0 ||
-                        h->non_zero_count_cache[bn_idx] != 0 ) {
+                        left_non_zero_count != 0 ) {
                         bS[i] = 2;
                     }
                     else if( h->slice_type == P_TYPE ) {
-                        if( h->ref_cache[0][b_idx] != h->ref_cache[0][bn_idx] ||
-                            ABS( h->mv_cache[0][b_idx][0] - h->mv_cache[0][bn_idx][0] ) >= 4 ||
-                            ABS( h->mv_cache[0][b_idx][1] - h->mv_cache[0][bn_idx][1] ) >= 4 )
+                        int16_t left_mv[2];
+                        int8_t  left_ref;
+                        if (slice_boundary) {
+                            // must not use ref_cache and mv_cache, they are not 
+                            // valid across slice boundaries
+                            if (dir == 0) {
+                                left_ref = s->current_picture.ref_index[0][h->mb2b8_xy[mbn_xy] + (i>>1) * h->b8_stride + 1];
+                                *(uint32_t*)left_mv = *(uint32_t*)s->current_picture.motion_val[0][h->mb2b_xy[mbn_xy]+i*h->b_stride+3];
+                            } else {
+                                left_ref = s->current_picture.ref_index[0][h->mb2b8_xy[mbn_xy] + (i>>1) + h->b8_stride];
+                                *(uint32_t*)left_mv = *(uint32_t*)s->current_picture.motion_val[0][h->mb2b_xy[mbn_xy]+3*h->b_stride+i];
+                            }
+                        } else {
+                            left_ref = h->ref_cache[0][bn_idx];
+                            *(uint32_t*)left_mv = *(uint32_t*)h->mv_cache[0][bn_idx];
+                        }
+                        if( h->ref_cache[0][b_idx] != left_ref ||
+                            ABS( h->mv_cache[0][b_idx][0] - left_mv[0] ) >= 4 ||
+                            ABS( h->mv_cache[0][b_idx][1] - left_mv[1] ) >= 4 )
                             bS[i] = 1;
                         else
                             bS[i] = 0;
@@ -5867,7 +5899,7 @@
         bit_length= 8*dst_length - decode_rbsp_trailing(ptr + dst_length - 1);
 
         if(s->avctx->debug&FF_DEBUG_STARTCODE){
-            av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d at %d length %d\n", h->nal_unit_type, buf_index, dst_length);
+            av_log(h->s.avctx, AV_LOG_DEBUG, "NAL %d at %d/%d length %d\n", h->nal_unit_type, buf_index, buf_size, dst_length);
         }
         
         if (h->is_avc && (nalsize != consumed))