]> git.sesse.net Git - x264/blobdiff - encoder/cabac.c
Fix and enable I_PCM macroblock support
[x264] / encoder / cabac.c
index 93b26d8cf79e202dd4cce8856e929b1192d371fa..53ada9819151b466243d66fb855055edf5c2e80f 100644 (file)
@@ -1,10 +1,10 @@
 /*****************************************************************************
  * cabac.c: h264 encoder library
  *****************************************************************************
- * Copyright (C) 2003 Laurent Aimar
- * $Id: cabac.c,v 1.1 2004/06/03 19:27:08 fenrir Exp $
+ * Copyright (C) 2003-2008 x264 project
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
+ *          Loren Merritt <lorenm@u.washington.edu>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  *****************************************************************************/
 
 #include "common/common.h"
@@ -307,7 +307,7 @@ static void x264_cabac_mb_qp_delta( x264_t *h, x264_cabac_t *cb )
     /* Avoid writing a delta quant if we have an empty i16x16 block, e.g. in a completely flat background area */
     if( h->mb.i_type == I_16x16 && !h->mb.cbp[h->mb.i_mb_xy] )
     {
-#ifndef RD_SKIP_BS
+#ifndef RDO_SKIP_BS
         h->mb.i_qp = h->mb.i_last_qp;
 #endif
         i_dqp = 0;
@@ -543,14 +543,12 @@ static int x264_cabac_mb_cbf_ctxidxinc( x264_t *h, int i_cat, int i_idx )
         if( h->mb.i_neighbour & MB_LEFT )
         {
             i_mba_xy = h->mb.i_mb_xy - 1;
-            if( h->mb.i_mb_type_left == I_16x16 )
-                i_nza = h->mb.cbp[i_mba_xy] & 0x100;
+            i_nza = h->mb.cbp[i_mba_xy] & 0x100;
         }
         if( h->mb.i_neighbour & MB_TOP )
         {
             i_mbb_xy = h->mb.i_mb_top_xy;
-            if( h->mb.i_mb_type_top == I_16x16 )
-                i_nzb = h->mb.cbp[i_mbb_xy] & 0x100;
+            i_nzb = h->mb.cbp[i_mbb_xy] & 0x100;
         }
     }
     else if( i_cat == DCT_LUMA_AC || i_cat == DCT_LUMA_4x4 )
@@ -785,36 +783,35 @@ void x264_macroblock_write_cabac( x264_t *h, x264_cabac_t *cb )
     /* Write the MB type */
     x264_cabac_mb_type( h, cb );
 
-    /* PCM special block type UNTESTED */
+#ifndef RDO_SKIP_BS
     if( i_mb_type == I_PCM )
     {
-#ifdef RDO_SKIP_BS
-        cb->f8_bits_encoded += (384*8) << 8;
-#else
-        if( cb->p + 385 >= cb->p_end )
-            return; //FIXME throw an error
-        /* Luma */
-        for( i = 0; i < 16; i++ )
-        {
-            memcpy( cb->p, h->fenc->plane[0] + i*h->mb.pic.i_stride[0], 16 );
-            cb->p += 16;
-        }
-        /* Cb */
+        i_mb_pos_tex = x264_cabac_pos( cb );
+        h->stat.frame.i_hdr_bits += i_mb_pos_tex - i_mb_pos_start;
+
+        memcpy( cb->p, h->mb.pic.p_fenc[0], 256 );
+        cb->p += 256;
         for( i = 0; i < 8; i++ )
-        {
-            memcpy( cb->p, h->fenc->plane[1] + i*h->mb.pic.i_stride[1], 8 );
-            cb->p += 8;
-        }
-        /* Cr */
+            memcpy( cb->p + i*8, h->mb.pic.p_fenc[1] + i*FENC_STRIDE, 8 );
+        cb->p += 64;
         for( i = 0; i < 8; i++ )
-        {
-            memcpy( cb->p, h->fenc->plane[2] + i*h->mb.pic.i_stride[2], 8 );
-            cb->p += 8;
-        }
-        x264_cabac_encode_init( cb, cb->p, cb->p_end );
-#endif
+            memcpy( cb->p + i*8, h->mb.pic.p_fenc[2] + i*FENC_STRIDE, 8 );
+        cb->p += 64;
+
+        cb->i_low   = 0;
+        cb->i_range = 0x01FE;
+        cb->i_queue = -1;
+        cb->i_bytes_outstanding = 0;
+
+        /* if PCM is chosen, we need to store reconstructed frame data */
+        h->mc.copy[PIXEL_16x16]( h->mb.pic.p_fdec[0], FDEC_STRIDE, h->mb.pic.p_fenc[0], FENC_STRIDE, 16 );
+        h->mc.copy[PIXEL_8x8]  ( h->mb.pic.p_fdec[1], FDEC_STRIDE, h->mb.pic.p_fenc[1], FENC_STRIDE, 8 );
+        h->mc.copy[PIXEL_8x8]  ( h->mb.pic.p_fdec[2], FDEC_STRIDE, h->mb.pic.p_fenc[2], FENC_STRIDE, 8 );
+
+        h->stat.frame.i_itex_bits += x264_cabac_pos( cb ) - i_mb_pos_tex;
         return;
     }
+#endif
 
     if( IS_INTRA( i_mb_type ) )
     {