Merge decode_cabac_mb_type_b() into calling code.
[ffmpeg.git] / libavcodec / h264_cabac.c
index 0c2a246..76fff71 100644 (file)
@@ -706,21 +706,15 @@ void ff_h264_init_cabac_states(H264Context *h) {
 
 static int decode_cabac_field_decoding_flag(H264Context *h) {
     MpegEncContext * const s = &h->s;
-    const int mb_x = s->mb_x;
-    const int mb_y = s->mb_y & ~1;
-    const int mba_xy = mb_x - 1 +  mb_y   *s->mb_stride;
-    const int mbb_xy = mb_x     + (mb_y-2)*s->mb_stride;
+    const long mba_xy = h->mb_xy - 1L;
+    const long mbb_xy = h->mb_xy - 2L*s->mb_stride;
 
-    unsigned int ctx = 0;
+    unsigned long ctx = 0;
 
-    if( h->slice_table[mba_xy] == h->slice_num && IS_INTERLACED( s->current_picture.mb_type[mba_xy] ) ) {
-        ctx += 1;
-    }
-    if( h->slice_table[mbb_xy] == h->slice_num && IS_INTERLACED( s->current_picture.mb_type[mbb_xy] ) ) {
-        ctx += 1;
-    }
+    ctx += (s->current_picture.mb_type[mba_xy]>>7)&(h->slice_table[mba_xy] == h->slice_num);
+    ctx += (s->current_picture.mb_type[mbb_xy]>>7)&(h->slice_table[mbb_xy] == h->slice_num);
 
-    return get_cabac_noinline( &h->cabac, &h->cabac_state[70 + ctx] );
+    return get_cabac_noinline( &h->cabac, &(h->cabac_state+70)[ctx] );
 }
 
 static int decode_cabac_intra_mb_type(H264Context *h, int ctx_base, int intra_slice) {
@@ -756,44 +750,6 @@ static int decode_cabac_intra_mb_type(H264Context *h, int ctx_base, int intra_sl
     return mb_type;
 }
 
-static int decode_cabac_mb_type_b( H264Context *h ) {
-    MpegEncContext * const s = &h->s;
-
-        const int mba_xy = h->left_mb_xy[0];
-        const int mbb_xy = h->top_mb_xy;
-        int ctx = 0;
-        int bits;
-        assert(h->slice_type_nos == FF_B_TYPE);
-
-        if( h->slice_table[mba_xy] == h->slice_num && !IS_DIRECT( s->current_picture.mb_type[mba_xy] ) )
-            ctx++;
-        if( h->slice_table[mbb_xy] == h->slice_num && !IS_DIRECT( s->current_picture.mb_type[mbb_xy] ) )
-            ctx++;
-
-        if( !get_cabac_noinline( &h->cabac, &h->cabac_state[27+ctx] ) )
-            return 0; /* B_Direct_16x16 */
-
-        if( !get_cabac_noinline( &h->cabac, &h->cabac_state[27+3] ) ) {
-            return 1 + get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ); /* B_L[01]_16x16 */
-        }
-
-        bits = get_cabac_noinline( &h->cabac, &h->cabac_state[27+4] ) << 3;
-        bits|= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ) << 2;
-        bits|= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ) << 1;
-        bits|= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] );
-        if( bits < 8 )
-            return bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */
-        else if( bits == 13 ) {
-            return decode_cabac_intra_mb_type(h, 32, 0) + 23;
-        } else if( bits == 14 )
-            return 11; /* B_L1_L0_8x16 */
-        else if( bits == 15 )
-            return 22; /* B_8x8 */
-
-        bits= ( bits<<1 ) | get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] );
-        return bits - 4; /* B_L0_Bi_* through B_Bi_Bi_* */
-}
-
 static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) {
     MpegEncContext * const s = &h->s;
     int mba_xy, mbb_xy;
@@ -873,8 +829,8 @@ static int decode_cabac_mb_chroma_pre_mode( H264Context *h) {
 static int decode_cabac_mb_cbp_luma( H264Context *h) {
     int cbp_b, cbp_a, ctx, cbp = 0;
 
-    cbp_a = h->slice_table[h->left_mb_xy[0]] == h->slice_num ? h->left_cbp : -1;
-    cbp_b = h->slice_table[h->top_mb_xy]     == h->slice_num ? h->top_cbp  : -1;
+    cbp_a = h->left_cbp;
+    cbp_b = h->top_cbp;
 
     ctx = !(cbp_a & 0x02) + 2 * !(cbp_b & 0x04);
     cbp |= get_cabac_noinline(&h->cabac, &h->cabac_state[73 + ctx]);
@@ -904,22 +860,7 @@ static int decode_cabac_mb_cbp_chroma( H264Context *h) {
     if( cbp_b == 2 ) ctx += 2;
     return 1 + get_cabac_noinline( &h->cabac, &h->cabac_state[77 + ctx] );
 }
-static int decode_cabac_mb_dqp( H264Context *h) {
-    int   ctx= h->last_qscale_diff != 0;
-    int   val = 0;
-
-    while( get_cabac_noinline( &h->cabac, &h->cabac_state[60 + ctx] ) ) {
-        ctx= 2+(ctx>>1);
-        val++;
-        if(val > 102) //prevent infinite loop
-            return INT_MIN;
-    }
 
-    if( val&0x01 )
-        return   (val + 1)>>1 ;
-    else
-        return -((val + 1)>>1);
-}
 static int decode_cabac_p_mb_sub_type( H264Context *h ) {
     if( get_cabac( &h->cabac, &h->cabac_state[21] ) )
         return 0;   /* 8x8 */
@@ -946,10 +887,6 @@ static int decode_cabac_b_mb_sub_type( H264Context *h ) {
     return type;
 }
 
-static inline int decode_cabac_mb_transform_size( H264Context *h ) {
-    return get_cabac_noinline( &h->cabac, &h->cabac_state[399 + h->neighbor_transform_size] );
-}
-
 static int decode_cabac_mb_ref( H264Context *h, int list, int n ) {
     int refa = h->ref_cache[list][scan8[n] - 1];
     int refb = h->ref_cache[list][scan8[n] - 8];
@@ -957,9 +894,9 @@ static int decode_cabac_mb_ref( H264Context *h, int list, int n ) {
     int ctx  = 0;
 
     if( h->slice_type_nos == FF_B_TYPE) {
-        if( refa > 0 && !h->direct_cache[scan8[n] - 1] )
+        if( refa > 0 && !(h->direct_cache[scan8[n] - 1]&(MB_TYPE_DIRECT2>>1)) )
             ctx++;
-        if( refb > 0 && !h->direct_cache[scan8[n] - 8] )
+        if( refb > 0 && !(h->direct_cache[scan8[n] - 8]&(MB_TYPE_DIRECT2>>1)) )
             ctx += 2;
     } else {
         if( refa > 0 )
@@ -1326,14 +1263,42 @@ int ff_h264_decode_mb_cabac(H264Context *h) {
     compute_mb_neighbors(h);
 
     if( h->slice_type_nos == FF_B_TYPE ) {
-        mb_type = decode_cabac_mb_type_b( h );
-        if( mb_type < 23 ){
-            partition_count= b_mb_type_info[mb_type].partition_count;
-            mb_type=         b_mb_type_info[mb_type].type;
+        const int mba_xy = h->left_mb_xy[0];
+        const int mbb_xy = h->top_mb_xy;
+        int ctx = 0;
+        assert(h->slice_type_nos == FF_B_TYPE);
+
+        if( h->slice_table[mba_xy] == h->slice_num && !IS_DIRECT( s->current_picture.mb_type[mba_xy] ) )
+            ctx++;
+        if( h->slice_table[mbb_xy] == h->slice_num && !IS_DIRECT( s->current_picture.mb_type[mbb_xy] ) )
+            ctx++;
+
+        if( !get_cabac_noinline( &h->cabac, &h->cabac_state[27+ctx] ) ){
+            mb_type= 0; /* B_Direct_16x16 */
+        }else if( !get_cabac_noinline( &h->cabac, &h->cabac_state[27+3] ) ) {
+            mb_type= 1 + get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ); /* B_L[01]_16x16 */
         }else{
-            mb_type -= 23;
-            goto decode_intra_mb;
+            int bits;
+            bits = get_cabac_noinline( &h->cabac, &h->cabac_state[27+4] ) << 3;
+            bits|= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ) << 2;
+            bits|= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] ) << 1;
+            bits|= get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] );
+            if( bits < 8 ){
+                mb_type= bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */
+            }else if( bits == 13 ){
+                mb_type= decode_cabac_intra_mb_type(h, 32, 0);
+                goto decode_intra_mb;
+            }else if( bits == 14 ){
+                mb_type= 11; /* B_L1_L0_8x16 */
+            }else if( bits == 15 ){
+                mb_type= 22; /* B_8x8 */
+            }else{
+                bits= ( bits<<1 ) | get_cabac_noinline( &h->cabac, &h->cabac_state[27+5] );
+                mb_type= bits - 4; /* B_L0_Bi_* through B_Bi_Bi_* */
+            }
         }
+            partition_count= b_mb_type_info[mb_type].partition_count;
+            mb_type=         b_mb_type_info[mb_type].type;
     } else if( h->slice_type_nos == FF_P_TYPE ) {
         if( get_cabac_noinline( &h->cabac, &h->cabac_state[14] ) == 0 ) {
             /* P-type */
@@ -1408,7 +1373,7 @@ decode_intra_mb:
     if( IS_INTRA( mb_type ) ) {
         int i, pred_mode;
         if( IS_INTRA4x4( mb_type ) ) {
-            if( dct8x8_allowed && decode_cabac_mb_transform_size( h ) ) {
+            if( dct8x8_allowed && get_cabac_noinline( &h->cabac, &h->cabac_state[399 + h->neighbor_transform_size] ) ) {
                 mb_type |= MB_TYPE_8x8DCT;
                 for( i = 0; i < 16; i+=4 ) {
                     int pred = pred_intra_mode( h, i );
@@ -1453,11 +1418,8 @@ decode_intra_mb:
                 h->ref_cache[1][scan8[4]] =
                 h->ref_cache[0][scan8[12]] =
                 h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
-                if( h->ref_count[0] > 1 || h->ref_count[1] > 1 ) {
                     for( i = 0; i < 4; i++ )
-                        if( IS_DIRECT(h->sub_mb_type[i]) )
-                            fill_rectangle( &h->direct_cache[scan8[4*i]], 2, 2, 8, 1, 1 );
-                }
+                        fill_rectangle( &h->direct_cache[scan8[4*i]], 2, 2, 8, (h->sub_mb_type[i]>>1)&0xFF, 1 );
             }
         } else {
             for( i = 0; i < 4; i++ ) {
@@ -1673,15 +1635,13 @@ decode_intra_mb:
     h->cbp_table[mb_xy] = h->cbp = cbp;
 
     if( dct8x8_allowed && (cbp&15) && !IS_INTRA( mb_type ) ) {
-        if( decode_cabac_mb_transform_size( h ) )
-            mb_type |= MB_TYPE_8x8DCT;
+        mb_type |= MB_TYPE_8x8DCT * get_cabac_noinline( &h->cabac, &h->cabac_state[399 + h->neighbor_transform_size] );
     }
     s->current_picture.mb_type[mb_xy]= mb_type;
 
     if( cbp || IS_INTRA16x16( mb_type ) ) {
         const uint8_t *scan, *scan8x8, *dc_scan;
         const uint32_t *qmul;
-        int dqp;
 
         if(IS_INTERLACED(mb_type)){
             scan8x8= s->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
@@ -1693,18 +1653,34 @@ decode_intra_mb:
             dc_scan= luma_dc_zigzag_scan;
         }
 
-        h->last_qscale_diff = dqp = decode_cabac_mb_dqp( h );
-        if( dqp == INT_MIN ){
-            av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y);
-            return -1;
-        }
-        s->qscale += dqp;
-        if(((unsigned)s->qscale) > 51){
-            if(s->qscale<0) s->qscale+= 52;
-            else            s->qscale-= 52;
-        }
-        h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
-        h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+        // decode_cabac_mb_dqp
+        if(get_cabac_noinline( &h->cabac, &h->cabac_state[60 + (h->last_qscale_diff != 0)])){
+            int val = 1;
+            int ctx= 2;
+
+            while( get_cabac_noinline( &h->cabac, &h->cabac_state[60 + ctx] ) ) {
+                ctx= 3;
+                val++;
+                if(val > 102){ //prevent infinite loop
+                    av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y);
+                    return -1;
+                }
+            }
+
+            if( val&0x01 )
+                val=   (val + 1)>>1 ;
+            else
+                val= -((val + 1)>>1);
+            h->last_qscale_diff = val;
+            s->qscale += val;
+            if(((unsigned)s->qscale) > 51){
+                if(s->qscale<0) s->qscale+= 52;
+                else            s->qscale-= 52;
+            }
+            h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
+            h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
+        }else
+            h->last_qscale_diff=0;
 
         if( IS_INTRA16x16( mb_type ) ) {
             int i;