]> git.sesse.net Git - x264/blobdiff - encoder/cabac.c
Forgot rbsp_trailing_bits in AUD NAL
[x264] / encoder / cabac.c
index ce218247db9c828d8fb241894c7c8ae755113472..91e0983f96557043e4b689c2d821502331f2fce8 100644 (file)
@@ -25,7 +25,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "../core/common.h"
+#include "common/common.h"
 #include "macroblock.h"
 
 static const uint8_t block_idx_x[16] =
@@ -44,6 +44,38 @@ static const uint8_t block_idx_xy[4][4] =
     { 5, 7, 13, 15}
 };
 
+static inline void x264_cabac_mb_type_intra( x264_t *h, int i_mb_type,
+                    int ctx0, int ctx1, int ctx2, int ctx3, int ctx4, int ctx5 )
+{
+    if( i_mb_type == I_4x4 )
+    {
+        x264_cabac_encode_decision( &h->cabac, ctx0, 0 );
+    }
+    else if( i_mb_type == I_PCM )
+    {
+        x264_cabac_encode_decision( &h->cabac, ctx0, 1 );
+        x264_cabac_encode_terminal( &h->cabac,       1 );
+    }
+    else
+    {
+        x264_cabac_encode_decision( &h->cabac, ctx0, 1 );
+        x264_cabac_encode_terminal( &h->cabac,       0 );
+
+        x264_cabac_encode_decision( &h->cabac, ctx1, ( h->mb.i_cbp_luma == 0 ? 0 : 1 ));
+        if( h->mb.i_cbp_chroma == 0 )
+        {
+            x264_cabac_encode_decision( &h->cabac, ctx2, 0 );
+        }
+        else
+        {
+            x264_cabac_encode_decision( &h->cabac, ctx2, 1 );
+            x264_cabac_encode_decision( &h->cabac, ctx3, ( h->mb.i_cbp_chroma == 1 ? 0 : 1 ) );
+        }
+        x264_cabac_encode_decision( &h->cabac, ctx4, ( (h->mb.i_intra16x16_pred_mode / 2) ? 1 : 0 ));
+        x264_cabac_encode_decision( &h->cabac, ctx5, ( (h->mb.i_intra16x16_pred_mode % 2) ? 1 : 0 ));
+    }
+}
+
 static void x264_cabac_mb_type( x264_t *h )
 {
     const int i_mb_type = h->mb.i_type;
@@ -60,33 +92,7 @@ static void x264_cabac_mb_type( x264_t *h )
             ctx++;
         }
 
-        if( i_mb_type == I_4x4 )
-        {
-            x264_cabac_encode_decision( &h->cabac, 3 + ctx, 0 );
-        }
-        else if( i_mb_type == I_PCM )
-        {
-            x264_cabac_encode_decision( &h->cabac, 3 + ctx, 1 );
-            x264_cabac_encode_terminal( &h->cabac, 1 );
-        }
-        else    /* I_16x16 */
-        {
-            x264_cabac_encode_decision( &h->cabac, 3 + ctx, 1 );
-            x264_cabac_encode_terminal( &h->cabac, 0 );
-
-            x264_cabac_encode_decision( &h->cabac, 3 + 3, ( h->mb.i_cbp_luma == 0 ? 0 : 1 ));
-            if( h->mb.i_cbp_chroma == 0 )
-            {
-                x264_cabac_encode_decision( &h->cabac, 3 + 4, 0 );
-            }
-            else
-            {
-                x264_cabac_encode_decision( &h->cabac, 3 + 4, 1 );
-                x264_cabac_encode_decision( &h->cabac, 3 + 5, ( h->mb.i_cbp_chroma == 1 ? 0 : 1 ) );
-            }
-            x264_cabac_encode_decision( &h->cabac, 3 + 6, ( (h->mb.i_intra16x16_pred_mode / 2) ? 1 : 0 ));
-            x264_cabac_encode_decision( &h->cabac, 3 + 7, ( (h->mb.i_intra16x16_pred_mode % 2) ? 1 : 0 ));
-        }
+        x264_cabac_mb_type_intra( h, i_mb_type, 3+ctx, 3+3, 3+4, 3+5, 3+6, 3+7 );
     }
     else if( h->sh.i_type == SLICE_TYPE_P )
     {
@@ -118,42 +124,13 @@ static void x264_cabac_mb_type( x264_t *h )
             x264_cabac_encode_decision( &h->cabac, 15, 0 );
             x264_cabac_encode_decision( &h->cabac, 16, 1 );
         }
-        else if( i_mb_type == I_4x4 )
-        {
-            /* prefix */
-            x264_cabac_encode_decision( &h->cabac, 14, 1 );
-
-            x264_cabac_encode_decision( &h->cabac, 17, 0 );
-        }
-        else if( i_mb_type == I_PCM )
-        {
-            /* prefix */
-            x264_cabac_encode_decision( &h->cabac, 14, 1 );
-
-            x264_cabac_encode_decision( &h->cabac, 17, 1 );
-            x264_cabac_encode_terminal( &h->cabac, 1 ); /*ctxIdx == 276 */
-        }
-        else /* intra 16x16 */
+        else /* intra */
         {
             /* prefix */
             x264_cabac_encode_decision( &h->cabac, 14, 1 );
 
             /* suffix */
-            x264_cabac_encode_decision( &h->cabac, 17, 1 );
-            x264_cabac_encode_terminal( &h->cabac, 0 ); /*ctxIdx == 276 */
-
-            x264_cabac_encode_decision( &h->cabac, 17+1, ( h->mb.i_cbp_luma == 0 ? 0 : 1 ));
-            if( h->mb.i_cbp_chroma == 0 )
-            {
-                x264_cabac_encode_decision( &h->cabac, 17+2, 0 );
-            }
-            else
-            {
-                x264_cabac_encode_decision( &h->cabac, 17+2, 1 );
-                x264_cabac_encode_decision( &h->cabac, 17+2, ( h->mb.i_cbp_chroma == 1 ? 0 : 1 ) );
-            }
-            x264_cabac_encode_decision( &h->cabac, 17+3, ( (h->mb.i_intra16x16_pred_mode / 2) ? 1 : 0 ));
-            x264_cabac_encode_decision( &h->cabac, 17+3, ( (h->mb.i_intra16x16_pred_mode % 2) ? 1 : 0 ));
+            x264_cabac_mb_type_intra( h, i_mb_type, 17+0, 17+1, 17+2, 17+2, 17+3, 17+3 );
         }
     }
     else if( h->sh.i_type == SLICE_TYPE_B )
@@ -193,35 +170,8 @@ static void x264_cabac_mb_type( x264_t *h )
             x264_cabac_encode_decision( &h->cabac, 27+5,   0 );
             x264_cabac_encode_decision( &h->cabac, 27+5,   1 );
 
-            /* Suffix */
-            if( i_mb_type == I_4x4 )
-            {
-                x264_cabac_encode_decision( &h->cabac, 32, 0 );
-            }
-            else if( i_mb_type == I_PCM )
-            {
-                x264_cabac_encode_decision( &h->cabac, 32, 1 );
-                x264_cabac_encode_terminal( &h->cabac,     1 );
-            }
-            else
-            {
-                x264_cabac_encode_decision( &h->cabac, 32, 1 );
-                x264_cabac_encode_terminal( &h->cabac,     0 );
-
-                /* TODO */
-                x264_cabac_encode_decision( &h->cabac, 32+1, ( h->mb.i_cbp_luma == 0 ? 0 : 1 ));
-                if( h->mb.i_cbp_chroma == 0 )
-                {
-                    x264_cabac_encode_decision( &h->cabac, 32+2, 0 );
-                }
-                else
-                {
-                    x264_cabac_encode_decision( &h->cabac, 32+2, 1 );
-                    x264_cabac_encode_decision( &h->cabac, 32+2, ( h->mb.i_cbp_chroma == 1 ? 0 : 1 ) );
-                }
-                x264_cabac_encode_decision( &h->cabac, 32+3, ( (h->mb.i_intra16x16_pred_mode / 2) ? 1 : 0 ));
-                x264_cabac_encode_decision( &h->cabac, 32+3, ( (h->mb.i_intra16x16_pred_mode % 2) ? 1 : 0 ));
-            }
+            /* suffix */
+            x264_cabac_mb_type_intra( h, i_mb_type, 32+0, 32+1, 32+2, 32+2, 32+3, 32+3 );
         }
         else
         {
@@ -279,7 +229,7 @@ static void x264_cabac_mb_type( x264_t *h )
                         idx++;
                     break;
                 default:
-                    fprintf( stderr, "error in B mb type\n" );
+                    x264_log(h, X264_LOG_ERROR, "error in B mb type\n" );
                     return;
             }
 
@@ -294,7 +244,7 @@ static void x264_cabac_mb_type( x264_t *h )
     }
     else
     {
-        fprintf( stderr, "unknown SLICE_TYPE unsupported in x264_macroblock_write_cabac\n" );
+        x264_log(h, X264_LOG_ERROR, "unknown SLICE_TYPE unsupported in x264_macroblock_write_cabac\n" );
     }
 }
 
@@ -612,9 +562,9 @@ static inline void x264_cabac_mb_ref( x264_t *h, int i_list, int idx )
     int i_ref  = h->mb.cache.ref[i_list][i8];
     int ctx  = 0;
 
-    if( i_refa > 0 )
+    if( i_refa > 0 && !h->mb.cache.skip[i8 - 1])
         ctx++;
-    if( i_refb > 0 )
+    if( i_refb > 0 && !h->mb.cache.skip[i8 - 8])
         ctx += 2;
 
     while( i_ref > 0 )
@@ -706,6 +656,47 @@ static inline void  x264_cabac_mb_mvd( x264_t *h, int i_list, int idx, int width
     x264_macroblock_cache_mvd( h, block_idx_x[idx], block_idx_y[idx], width, height, i_list, mdx, mdy );
 }
 
+static inline void x264_cabac_mb8x8_mvd( x264_t *h, int i_list )
+{
+    int i;
+    for( i = 0; i < 4; i++ )
+    {
+        if( !x264_mb_partition_listX_table[i_list][ h->mb.i_sub_partition[i] ] )
+        {
+            continue;
+        }
+
+        switch( h->mb.i_sub_partition[i] )
+        {
+            case D_L0_8x8:
+            case D_L1_8x8:
+            case D_BI_8x8:
+                x264_cabac_mb_mvd( h, i_list, 4*i, 2, 2 );
+                break;
+            case D_L0_8x4:
+            case D_L1_8x4:
+            case D_BI_8x4:
+                x264_cabac_mb_mvd( h, i_list, 4*i+0, 2, 1 );
+                x264_cabac_mb_mvd( h, i_list, 4*i+2, 2, 1 );
+                break;
+            case D_L0_4x8:
+            case D_L1_4x8:
+            case D_BI_4x8:
+                x264_cabac_mb_mvd( h, i_list, 4*i+0, 1, 2 );
+                x264_cabac_mb_mvd( h, i_list, 4*i+1, 1, 2 );
+                break;
+            case D_L0_4x4:
+            case D_L1_4x4:
+            case D_BI_4x4:
+                x264_cabac_mb_mvd( h, i_list, 4*i+0, 1, 1 );
+                x264_cabac_mb_mvd( h, i_list, 4*i+1, 1, 1 );
+                x264_cabac_mb_mvd( h, i_list, 4*i+2, 1, 1 );
+                x264_cabac_mb_mvd( h, i_list, 4*i+3, 1, 1 );
+                break;
+        }
+    }
+}
+
 static int x264_cabac_mb_cbf_ctxidxinc( x264_t *h, int i_cat, int i_idx )
 {
     /* TODO: clean up/optimize */
@@ -964,6 +955,7 @@ void x264_macroblock_write_cabac( x264_t *h, bs_t *s )
     const int i_mb_pos_start = bs_pos( s );
     int       i_mb_pos_tex;
 
+    int i_list;
     int i;
 
     /* Write the MB type */
@@ -1060,40 +1052,36 @@ void x264_macroblock_write_cabac( x264_t *h, bs_t *s )
             x264_cabac_mb_ref( h, 0, 12 );
         }
 
-        for( i = 0; i < 4; i++ )
+        x264_cabac_mb8x8_mvd( h, 0 );
+    }
+    else if( i_mb_type == B_8x8 )
+    {
+        /* sub mb type */
+        x264_cabac_mb_sub_b_partition( h, h->mb.i_sub_partition[0] );
+        x264_cabac_mb_sub_b_partition( h, h->mb.i_sub_partition[1] );
+        x264_cabac_mb_sub_b_partition( h, h->mb.i_sub_partition[2] );
+        x264_cabac_mb_sub_b_partition( h, h->mb.i_sub_partition[3] );
+
+        /* ref */
+        for( i_list = 0; i_list < 2; i_list++ )
         {
-            switch( h->mb.i_sub_partition[i] )
+            if( ( i_list ? h->sh.i_num_ref_idx_l1_active : h->sh.i_num_ref_idx_l0_active ) == 1 )
+                continue;
+            for( i = 0; i < 4; i++ )
             {
-                case D_L0_8x8:
-                    x264_cabac_mb_mvd( h, 0, 4*i, 2, 2 );
-                    break;
-                case D_L0_8x4:
-                    x264_cabac_mb_mvd( h, 0, 4*i+0, 2, 1 );
-                    x264_cabac_mb_mvd( h, 0, 4*i+2, 2, 1 );
-                    break;
-                case D_L0_4x8:
-                    x264_cabac_mb_mvd( h, 0, 4*i+0, 1, 2 );
-                    x264_cabac_mb_mvd( h, 0, 4*i+1, 1, 2 );
-                    break;
-                case D_L0_4x4:
-                    x264_cabac_mb_mvd( h, 0, 4*i+0, 1, 1 );
-                    x264_cabac_mb_mvd( h, 0, 4*i+1, 1, 1 );
-                    x264_cabac_mb_mvd( h, 0, 4*i+2, 1, 1 );
-                    x264_cabac_mb_mvd( h, 0, 4*i+3, 1, 1 );
-                    break;
+                if( x264_mb_partition_listX_table[i_list][ h->mb.i_sub_partition[i] ] )
+                {
+                    x264_cabac_mb_ref( h, i_list, 4*i );
+                }
             }
         }
-    }
-    else if( i_mb_type == B_8x8 )
-    {
-        /* TODO */
-        fprintf( stderr, "Arggg B_8x8\n" );
-        return;
+
+        x264_cabac_mb8x8_mvd( h, 0 );
+        x264_cabac_mb8x8_mvd( h, 1 );
     }
     else if( i_mb_type != B_DIRECT )
     {
         /* All B mode */
-        int i_list;
         int b_list[2][2];
 
         /* init ref list utilisations */