]> git.sesse.net Git - vlc/commitdiff
* Chroma 4:2:2 and 4:4:4 support in the decoder.
authorChristophe Massiot <massiot@videolan.org>
Thu, 11 Oct 2001 13:19:27 +0000 (13:19 +0000)
committerChristophe Massiot <massiot@videolan.org>
Thu, 11 Oct 2001 13:19:27 +0000 (13:19 +0000)
* Fixed bugs in the C YUV transform with 4:2:2 format.

include/vdec_ext-plugins.h
plugins/yuv/transforms_common.h
plugins/yuv/transforms_yuv.h
src/video_decoder/video_decoder.c
src/video_decoder/video_decoder.h
src/video_decoder/video_parser.h
src/video_decoder/vpar_blocks.c
src/video_decoder/vpar_headers.c
src/video_decoder/vpar_pool.c
src/video_decoder/vpar_pool.h

index c908517cba1a00e8018b1015fb93f17d03118ed1..f536f882097821165aeea4e08bcbeb0a2515157c 100644 (file)
@@ -2,7 +2,7 @@
  * vdec_ext-plugins.h : structures from the video decoder exported to plug-ins
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vdec_ext-plugins.h,v 1.5 2001/09/25 11:46:13 massiot Exp $
+ * $Id: vdec_ext-plugins.h,v 1.6 2001/10/11 13:19:27 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -34,8 +34,6 @@ typedef struct idct_inner_s
                                         /* sparse IDCT or not, add or copy ? */
     int                     i_sparse_pos;                  /* position of the
                                                             * non-NULL coeff */
-    yuv_data_t *            p_dct_data;              /* pointer to the position
-                                                      * in the final picture */
 } idct_inner_t;
 
 typedef struct motion_inner_s
@@ -53,11 +51,14 @@ typedef struct macroblock_s
     int                     i_mb_modes;
 
     /* IDCT information */
-    idct_inner_t            p_idcts[6];
+    idct_inner_t            p_idcts[12];
     int                     i_coded_block_pattern;
                                                  /* which blocks are coded ? */
-    int                     i_lum_dct_stride, i_chrom_dct_stride;
-                                 /* nb of coeffs to jump when changing lines */
+    yuv_data_t *            p_y_data;
+    yuv_data_t *            p_u_data;
+    yuv_data_t *            p_v_data;
+                                                    /* pointers to the position
+                                                     * in the final picture  */
 
     /* Motion compensation information */
     motion_inner_t          p_motions[8];
index 938947ebd233f9ed34fa4eec5785c1577382e3c9..2d542707ec9791517edf056994b549264a85bf93 100644 (file)
@@ -2,7 +2,7 @@
  * transforms_common.h: YUV transformation macros for truecolor
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: transforms_common.h,v 1.2 2001/03/21 13:42:34 sam Exp $
+ * $Id: transforms_common.h,v 1.3 2001/10/11 13:19:27 massiot Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -95,7 +95,7 @@
  *****************************************************************************/
 #define SCALE_HEIGHT( CHROMA, BPP )                                           \
     /* If line is odd, rewind 4:2:0 U and V samples */                        \
-    if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) )                \
+    if( (CHROMA == 420) && !(i_y & 0x1) )                                     \
     {                                                                         \
         p_u -= i_chroma_width;                                                \
         p_v -= i_chroma_width;                                                \
             /* Height reduction: skip next source line */                     \
             p_y += i_width;                                                   \
             i_y++;                                                            \
-            if( (CHROMA == 420) || (CHROMA == 422) )                          \
+            if( CHROMA == 420 )                                               \
             {                                                                 \
                 if( i_y & 0x1 )                                               \
                 {                                                             \
                     p_v += i_chroma_width;                                    \
                 }                                                             \
             }                                                                 \
-            else if( CHROMA == 444 )                                          \
+            else if( (CHROMA == 422) || (CHROMA == 444) )                     \
             {                                                                 \
                 p_u += i_width;                                               \
                 p_v += i_width;                                               \
index 93b8c34d210e6a6157ea0d8b2b8e9ab3cb6fc594..b1fa9fe1cdb59e92c25367f5ea6404ce08befe3a 100644 (file)
@@ -2,7 +2,7 @@
  * transforms_yuv.h: C specific YUV transformation macros
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: transforms_yuv.h,v 1.2 2001/03/21 13:42:34 sam Exp $
+ * $Id: transforms_yuv.h,v 1.3 2001/10/11 13:19:27 massiot Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
 #define SCALE_HEIGHT_DITHER( CHROMA )                                         \
                                                                               \
     /* If line is odd, rewind 4:2:0 U and V samples */                        \
-    if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) )                \
+    if( (CHROMA == 420) && !(i_y & 0x1) )                                     \
     {                                                                         \
         p_u -= i_chroma_width;                                                \
         p_v -= i_chroma_width;                                                \
             /* Height reduction: skip next source line */                     \
             p_y += i_width;                                                   \
             i_y++;                                                            \
-            if( (CHROMA == 420) || (CHROMA == 422) )                          \
+            if( CHROMA == 420 )                                               \
             {                                                                 \
                 if( i_y & 0x1 )                                               \
                 {                                                             \
                     p_v += i_chroma_width;                                    \
                 }                                                             \
             }                                                                 \
-            else if( CHROMA == 444 )                                          \
+            else if( (CHROMA == 422) || (CHROMA == 444) )                     \
             {                                                                 \
                 p_u += i_width;                                               \
                 p_v += i_width;                                               \
index 7090411cda2c37c9bb16e9b8451d70f013f6ce07..452ff6099f0a75a7841ed5d350a60331b7656f4f 100644 (file)
@@ -2,7 +2,7 @@
  * video_decoder.c : video decoder thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_decoder.c,v 1.58 2001/09/05 16:07:50 massiot Exp $
+ * $Id: video_decoder.c,v 1.59 2001/10/11 13:19:27 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Michel Lespinasse <walken@zoy.org>
@@ -183,7 +183,8 @@ static __inline__ void MotionBlock( vdec_pool_t * p_pool,
                                     yuv_data_t * pp_dest[3], int i_dest_offset,
                                     yuv_data_t * pp_src[3], int i_src_offset,
                                     int i_stride, int i_height,
-                                    boolean_t b_second_half, boolean_t b_color )
+                                    boolean_t b_second_half,
+                                    int i_chroma_format )
 {
     int             i_xy_half;
     yuv_data_t *    p_src1;
@@ -199,28 +200,37 @@ static __inline__ void MotionBlock( vdec_pool_t * p_pool,
             ( pp_dest[0] + i_dest_offset + b_second_half * (i_stride << 3),
               p_src1, i_stride, i_height );
 
-    if( b_color )
+    if( i_chroma_format != CHROMA_NONE )
     {
         /* Expanded at compile-time. */
-        i_x_pred /= 2;
-        i_y_pred /= 2;
+        if( i_chroma_format != CHROMA_444 )
+        {
+            i_x_pred /= 2;
+            i_stride >>= 1;
+            i_src_offset >>= 1;
+            i_dest_offset >>= 1;
+        }
+        if( i_chroma_format == CHROMA_420 )
+        {
+            i_y_pred /= 2;
+            i_height >>= 1;
+        }
 
         i_xy_half = ((i_y_pred & 1) << 1) | (i_x_pred & 1);
-        i_stride >>= 1;
-        i_height >>= 1;
-        i_src_offset >>= 1;
-        i_src_offset += b_second_half * (i_stride << 2);
-        i_dest_offset >>= 1;
-        i_dest_offset += b_second_half * (i_stride << 2);
+
+        i_src_offset += b_second_half * (i_stride << 3);
+        i_dest_offset += b_second_half * (i_stride << 3);
 
         p_src1 = pp_src[1] + i_src_offset
                     + (i_x_pred >> 1) + (i_y_pred >> 1) * i_stride;
         p_src2 = pp_src[2] + i_src_offset
                     + (i_x_pred >> 1) + (i_y_pred >> 1) * i_stride;
 
-        p_pool->ppppf_motion[b_average][1][i_xy_half]
+        p_pool->ppppf_motion[b_average][(i_chroma_format != CHROMA_444)]
+                            [i_xy_half]
                 ( pp_dest[1] + i_dest_offset, p_src1, i_stride, i_height );
-        p_pool->ppppf_motion[b_average][1][i_xy_half]
+        p_pool->ppppf_motion[b_average][(i_chroma_format != CHROMA_444)]
+                            [i_xy_half]
                 ( pp_dest[2] + i_dest_offset, p_src2, i_stride, i_height );
     }
 }
@@ -229,12 +239,62 @@ static __inline__ void MotionBlock( vdec_pool_t * p_pool,
 /*****************************************************************************
  * DecodeMacroblock: decode a macroblock
  *****************************************************************************/
-#define DECLARE_DECODEMB( PSZ_NAME, B_COLOR )                               \
+#define DECODE_INTRA_BLOCK( i_b, p_dest, I_CHROMA )                         \
+    p_idct = &p_mb->p_idcts[i_b];                                           \
+    p_idct->pf_idct( p_idct->pi_block, p_dest,                              \
+                     i_b < 4 ? i_lum_dct_stride :                           \
+                         I_CHROMA == CHROMA_420 ?                           \
+                         p_vpar->picture.i_field_width >> 1 :               \
+                         i_chrom_dct_stride,                                \
+                     p_vdec->p_idct_data, p_idct->i_sparse_pos ); 
+
+#define DECODE_NONINTRA_BLOCK( i_b, p_dest, I_CHROMA )                      \
+    if( p_mb->i_coded_block_pattern & (1 << (3 + p_vpar->sequence.i_chroma_nb_blocks - i_b)) )                    \
+    {                                                                       \
+        DECODE_INTRA_BLOCK( i_b, p_dest, I_CHROMA );                        \
+    }
+    
+#define DECLARE_DECODEMB( PSZ_NAME, I_CHROMA )                              \
 void PSZ_NAME ( vdec_thread_t *p_vdec, macroblock_t * p_mb )                \
 {                                                                           \
-    int             i;                                                      \
+    int             i, i_lum_dct_offset, i_lum_dct_stride;                  \
+    /* This is to keep the compiler happy with CHROMA_420 and CHROMA_NONE */\
+    int             i_chrom_dct_offset __attribute__((unused));             \
+    int             i_chrom_dct_stride __attribute__((unused));             \
     idct_inner_t *  p_idct;                                                 \
     vdec_pool_t *   p_pool = p_vdec->p_pool;                                \
+    vpar_thread_t * p_vpar = p_pool->p_vpar;                                \
+                                                                            \
+    if( p_mb->i_mb_modes & DCT_TYPE_INTERLACED )                            \
+    {                                                                       \
+        i_lum_dct_offset = p_vpar->picture.i_field_width;                   \
+        i_lum_dct_stride = p_vpar->picture.i_field_width * 2;             \
+        if( I_CHROMA == CHROMA_422 )                                        \
+        {                                                                   \
+            i_chrom_dct_offset = p_vpar->picture.i_field_width >> 1;        \
+            i_chrom_dct_stride = p_vpar->picture.i_field_width;             \
+        }                                                                   \
+        else if( I_CHROMA == CHROMA_444 )                                   \
+        {                                                                   \
+            i_chrom_dct_offset = p_vpar->picture.i_field_width;             \
+            i_chrom_dct_stride = p_vpar->picture.i_field_width * 2;         \
+        }                                                                   \
+    }                                                                       \
+    else                                                                    \
+    {                                                                       \
+        i_lum_dct_offset = p_vpar->picture.i_field_width * 8;               \
+        i_lum_dct_stride = p_vpar->picture.i_field_width;                   \
+        if( I_CHROMA == CHROMA_422 )                                        \
+        {                                                                   \
+            i_chrom_dct_offset = p_vpar->picture.i_field_width * 4;         \
+            i_chrom_dct_stride = p_vpar->picture.i_field_width >> 1;        \
+        }                                                                   \
+        else if( I_CHROMA == CHROMA_444 )                                   \
+        {                                                                   \
+            i_chrom_dct_offset = p_vpar->picture.i_field_width * 8;         \
+            i_chrom_dct_stride = p_vpar->picture.i_field_width;             \
+        }                                                                   \
+    }                                                                       \
                                                                             \
     if( !(p_mb->i_mb_modes & MB_INTRA) )                                    \
     {                                                                       \
@@ -249,44 +309,81 @@ void PSZ_NAME ( vdec_thread_t *p_vdec, macroblock_t * p_mb )                \
                          p_mb->pp_dest, p_motion->i_dest_offset,            \
                          p_motion->pp_source, p_motion->i_src_offset,       \
                          p_motion->i_stride, p_motion->i_height,            \
-                         p_motion->b_second_half, B_COLOR );                \
+                         p_motion->b_second_half, I_CHROMA );               \
         }                                                                   \
                                                                             \
-        for( i = 0, p_idct = p_mb->p_idcts; i < 4 + 2 * B_COLOR;            \
-             i++, p_idct++ )                                                \
+        /*                                                                  \
+         * Inverse DCT (ISO/IEC 13818-2 section Annex A) and                \
+         * adding prediction and coefficient data (ISO/IEC                  \
+         * 13818-2 section 7.6.8)                                           \
+         */                                                                 \
+        DECODE_NONINTRA_BLOCK( 0, p_mb->p_y_data, I_CHROMA );               \
+        DECODE_NONINTRA_BLOCK( 1, p_mb->p_y_data + 8, I_CHROMA );           \
+        DECODE_NONINTRA_BLOCK( 2, p_mb->p_y_data + i_lum_dct_offset,        \
+                               I_CHROMA );                                  \
+        DECODE_NONINTRA_BLOCK( 3, p_mb->p_y_data + i_lum_dct_offset + 8,    \
+                               I_CHROMA );                                  \
+        if( I_CHROMA != CHROMA_NONE )                                       \
         {                                                                   \
-            if( p_mb->i_coded_block_pattern & (1 << (5 - i)) )              \
+            DECODE_NONINTRA_BLOCK( 4, p_mb->p_u_data, I_CHROMA );           \
+            DECODE_NONINTRA_BLOCK( 5, p_mb->p_v_data, I_CHROMA );           \
+            if( I_CHROMA != CHROMA_420 )                                    \
             {                                                               \
-                /*                                                          \
-                 * Inverse DCT (ISO/IEC 13818-2 section Annex A) and        \
-                 * adding prediction and coefficient data (ISO/IEC          \
-                 * 13818-2 section 7.6.8)                                   \
-                 */                                                         \
-                p_idct->pf_idct( p_idct->pi_block, p_idct->p_dct_data,      \
-                                 i < 4 ? p_mb->i_lum_dct_stride :           \
-                                         p_mb->i_chrom_dct_stride,          \
-                                 p_vdec->p_idct_data,                       \
-                                 p_idct->i_sparse_pos );                    \
+                DECODE_NONINTRA_BLOCK( 6, p_mb->p_u_data                    \
+                                           + i_chrom_dct_offset, I_CHROMA );\
+                DECODE_NONINTRA_BLOCK( 7, p_mb->p_v_data                    \
+                                           + i_chrom_dct_offset, I_CHROMA );\
+                if( I_CHROMA == CHROMA_444 )                                \
+                {                                                           \
+                    DECODE_NONINTRA_BLOCK( 8, p_mb->p_u_data + 8,           \
+                                           I_CHROMA );                      \
+                    DECODE_NONINTRA_BLOCK( 9, p_mb->p_v_data + 8,           \
+                                           I_CHROMA );                      \
+                    DECODE_NONINTRA_BLOCK( 10, p_mb->p_u_data + 8           \
+                                           + i_chrom_dct_offset, I_CHROMA );\
+                    DECODE_NONINTRA_BLOCK( 11, p_mb->p_v_data + 8           \
+                                           + i_chrom_dct_offset, I_CHROMA );\
+                }                                                           \
             }                                                               \
         }                                                                   \
     }                                                                       \
     else                                                                    \
     {                                                                       \
         /* Intra macroblock */                                              \
-        for( i = 0, p_idct = p_mb->p_idcts; i < 4 + 2 * B_COLOR;            \
-             i++, p_idct++ )                                                \
+        DECODE_INTRA_BLOCK( 0, p_mb->p_y_data, I_CHROMA );                  \
+        DECODE_INTRA_BLOCK( 1, p_mb->p_y_data + 8, I_CHROMA );              \
+        DECODE_INTRA_BLOCK( 2, p_mb->p_y_data + i_lum_dct_offset,           \
+                            I_CHROMA );                                     \
+        DECODE_INTRA_BLOCK( 3, p_mb->p_y_data + i_lum_dct_offset + 8,       \
+                            I_CHROMA );                                     \
+        if( I_CHROMA != CHROMA_NONE )                                       \
         {                                                                   \
-            p_idct->pf_idct( p_idct->pi_block, p_idct->p_dct_data,          \
-                             i < 4 ? p_mb->i_lum_dct_stride :               \
-                                     p_mb->i_chrom_dct_stride,              \
-                             p_vdec->p_idct_data,                           \
-                             p_idct->i_sparse_pos );                        \
+            DECODE_INTRA_BLOCK( 4, p_mb->p_u_data, I_CHROMA );              \
+            DECODE_INTRA_BLOCK( 5, p_mb->p_v_data, I_CHROMA );              \
+            if( I_CHROMA != CHROMA_420 )                                    \
+            {                                                               \
+                DECODE_INTRA_BLOCK( 6, p_mb->p_u_data                       \
+                                        + i_chrom_dct_offset, I_CHROMA );   \
+                DECODE_INTRA_BLOCK( 7, p_mb->p_v_data                       \
+                                        + i_chrom_dct_offset, I_CHROMA );   \
+                if( I_CHROMA == CHROMA_444 )                                \
+                {                                                           \
+                    DECODE_INTRA_BLOCK( 8, p_mb->p_u_data + 8, I_CHROMA );  \
+                    DECODE_INTRA_BLOCK( 9, p_mb->p_v_data + 8, I_CHROMA );  \
+                    DECODE_INTRA_BLOCK( 10, p_mb->p_u_data + 8              \
+                                           + i_chrom_dct_offset, I_CHROMA );\
+                    DECODE_INTRA_BLOCK( 11, p_mb->p_v_data + 8              \
+                                           + i_chrom_dct_offset, I_CHROMA );\
+                }                                                           \
+            }                                                               \
         }                                                                   \
     }                                                                       \
 }
 
-DECLARE_DECODEMB( vdec_DecodeMacroblockC, 1 );
-DECLARE_DECODEMB( vdec_DecodeMacroblockBW, 0 );
+DECLARE_DECODEMB( vdec_DecodeMacroblockBW, CHROMA_NONE );
+DECLARE_DECODEMB( vdec_DecodeMacroblock420, CHROMA_420 );
+DECLARE_DECODEMB( vdec_DecodeMacroblock422, CHROMA_422 );
+DECLARE_DECODEMB( vdec_DecodeMacroblock444, CHROMA_444 );
 
 #undef DECLARE_DECODEMB
 
index e30dbf6baec79862345e634962b0304f14f61529..985684ceff994e0ffb2524bf514eaa4e0a0440ca 100644 (file)
@@ -2,7 +2,7 @@
  * video_decoder.h : video decoder thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_decoder.h,v 1.5 2001/08/22 17:21:45 massiot Exp $
+ * $Id: video_decoder.h,v 1.6 2001/10/11 13:19:27 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
  *****************************************************************************/
 void            vdec_InitThread         ( struct vdec_thread_s * );
 void            vdec_EndThread          ( struct vdec_thread_s * );
-void            vdec_DecodeMacroblockC  ( struct vdec_thread_s *,
-                                          struct macroblock_s * );
 void            vdec_DecodeMacroblockBW ( struct vdec_thread_s *,
                                           struct macroblock_s * );
+void            vdec_DecodeMacroblock420( struct vdec_thread_s *,
+                                          struct macroblock_s * );
+void            vdec_DecodeMacroblock422( struct vdec_thread_s *,
+                                          struct macroblock_s * );
+void            vdec_DecodeMacroblock444( struct vdec_thread_s *,
+                                          struct macroblock_s * );
 struct vdec_thread_s * vdec_CreateThread( struct vdec_pool_s * );
 void            vdec_DestroyThread      ( struct vdec_thread_s * );
 
index 1e653ec4f02daaa378799a9148903280b011551b..a86784d2ba8d6024f3669ce765bc152b0466e3c1 100644 (file)
@@ -2,7 +2,7 @@
  * video_parser.h : video parser thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: video_parser.h,v 1.15 2001/10/01 16:44:07 massiot Exp $
+ * $Id: video_parser.h,v 1.16 2001/10/11 13:19:27 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Jean-Marc Dressler <polux@via.ecp.fr>
@@ -116,6 +116,8 @@ typedef struct sequence_s
     unsigned int        i_aspect_ratio;        /* height/width display ratio */
     unsigned int        i_matrix_coefficients;/* coeffs of the YUV transform */
     int                 i_chroma_format, i_scalable_mode;
+    int                 i_chroma_nb_blocks;
+    boolean_t           b_chroma_h_subsampled, b_chroma_v_subsampled;
     int                 i_frame_rate;  /* theoritical frame rate in fps*1001 */
     boolean_t           b_mpeg2;                                    /* guess */
     boolean_t           b_progressive;              /* progressive (ie.
@@ -202,6 +204,7 @@ typedef struct picture_parsing_s
 #define SC_TEMP     4
 
 /* Chroma types */
+#define CHROMA_NONE 0
 #define CHROMA_420 1
 #define CHROMA_422 2
 #define CHROMA_444 3
index 7b50e53f0f02a2eb0b36bdfbbb3375d15e465d90..c0836fafcf7221fc7a4ba446f9f15965c567c830 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_blocks.c : blocks parsing
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_blocks.c,v 1.12 2001/10/01 16:44:07 massiot Exp $
+ * $Id: vpar_blocks.c,v 1.13 2001/10/11 13:19:27 massiot Exp $
  *
  * Authors: Michel Lespinasse <walken@zoy.org>
  *          Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
@@ -179,14 +179,14 @@ static __inline__ int GetChromaDCDiff( vpar_thread_t * p_vpar )
 /*****************************************************************************
  * MPEG2IntraB14 : Decode an intra block according to ISO/IEC 13818-2 table B14
  *****************************************************************************/
-static void MPEG2IntraB14( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
+static void MPEG2IntraB14( vpar_thread_t * p_vpar, idct_inner_t * p_idct,
+                           u8 * pi_quant )
 {
     int         i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
     s32         i_sign;
     dct_lookup_t * p_tab;
 
     int         i_q_scale = p_vpar->mb.i_quantizer_scale;
-    u8 *        pi_quant = p_vpar->sequence.intra_quant.pi_matrix;
     dctelem_t * p_dest = p_idct->pi_block;
     u8 *        p_scan = p_vpar->picture.pi_scan;
 
@@ -327,14 +327,14 @@ store_coeff:
 /*****************************************************************************
  * MPEG2IntraB15 : Decode an intra block according to ISO/IEC 13818-2 table B15
  *****************************************************************************/
-static void MPEG2IntraB15( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
+static void MPEG2IntraB15( vpar_thread_t * p_vpar, idct_inner_t * p_idct,
+                           u8 * pi_quant )
 {
     int         i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
     s32         i_sign;
     dct_lookup_t * p_tab;
 
     int         i_q_scale = p_vpar->mb.i_quantizer_scale;
-    u8 *        pi_quant = p_vpar->sequence.intra_quant.pi_matrix;
     dctelem_t * p_dest = p_idct->pi_block;
     u8 *        p_scan = p_vpar->picture.pi_scan;
 
@@ -471,20 +471,16 @@ store_coeff:
 /*****************************************************************************
  * MPEG2NonIntra : Decode a non-intra MPEG-2 block
  *****************************************************************************/
-static void MPEG2NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
+static void MPEG2NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct,
+                           u8 * pi_quant )
 {
     int         i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
     s32         i_sign;
     dct_lookup_t * p_tab;
 
     int         i_q_scale = p_vpar->mb.i_quantizer_scale;
-    u8 *        pi_quant = p_vpar->sequence.nonintra_quant.pi_matrix;
     dctelem_t * p_dest = p_idct->pi_block;
     u8 *        p_scan = p_vpar->picture.pi_scan;
-static int meuh = 0;
-meuh++;
-    if( meuh == 3745 )
-        i_coeff = 0;
 
     i_coeff = -1;
     i_mismatch = 1;
@@ -644,14 +640,14 @@ coeff_2:
 /*****************************************************************************
  * MPEG1Intra : Decode an MPEG-1 intra block
  *****************************************************************************/
-static void MPEG1Intra( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
+static void MPEG1Intra( vpar_thread_t * p_vpar, idct_inner_t * p_idct,
+                        u8 * pi_quant )
 {
     int         i_coeff, i_code, i_pos, i_value, i_nc;
     s32         i_sign;
     dct_lookup_t * p_tab;
 
     int         i_q_scale = p_vpar->mb.i_quantizer_scale;
-    u8 *        pi_quant = p_vpar->sequence.intra_quant.pi_matrix;
     dctelem_t * p_dest = p_idct->pi_block;
     u8 *        p_scan = p_vpar->picture.pi_scan;
 
@@ -787,14 +783,14 @@ store_coeff:
 /*****************************************************************************
  * MPEG1NonIntra : Decode a non-intra MPEG-1 block
  *****************************************************************************/
-static void MPEG1NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
+static void MPEG1NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct,
+                           u8 * pi_quant )
 {
     int         i_coeff, i_code, i_pos, i_value, i_nc;
     s32         i_sign;
     dct_lookup_t * p_tab;
 
     int         i_q_scale = p_vpar->mb.i_quantizer_scale;
-    u8 *        pi_quant = p_vpar->sequence.nonintra_quant.pi_matrix;
     dctelem_t * p_dest = p_idct->pi_block;
     u8 *        p_scan = p_vpar->picture.pi_scan;
 
@@ -951,57 +947,48 @@ coeff_2:
 /*****************************************************************************
  * *MB : decode all blocks of the macroblock
  *****************************************************************************/
-#define DECODE_LUMABLOCK( i_b, p_dest, PF_MBFUNC )                          \
-    p_idct = &p_mb->p_idcts[i_b];                                           \
+#define DECODE_LUMABLOCK( I_B, PF_MBFUNC )                                  \
+    p_idct = &p_mb->p_idcts[I_B];                                           \
     memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) );                    \
-    p_idct->p_dct_data = p_dest;                                            \
     p_vpar->mb.pi_dc_dct_pred[0] += GetLumaDCDiff( p_vpar );                \
     p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[0]                      \
                          << (3 - p_vpar->picture.i_intra_dc_precision );    \
-    PF_MBFUNC( p_vpar, p_idct );
+    PF_MBFUNC( p_vpar, p_idct, p_vpar->sequence.intra_quant.pi_matrix );
+
+#define DECODE_CHROMABLOCK( I_B, PF_MBFUNC, I_CC )                          \
+    p_idct = &p_mb->p_idcts[I_B];                                           \
+    memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) );                    \
+    p_vpar->mb.pi_dc_dct_pred[I_CC] += GetChromaDCDiff( p_vpar );           \
+    p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[I_CC]                   \
+                         << (3 - p_vpar->picture.i_intra_dc_precision );    \
+    PF_MBFUNC( p_vpar, p_idct,                                              \
+               p_vpar->sequence.chroma_intra_quant.pi_matrix );
 
 #define DECLARE_INTRAMB( PSZ_NAME, PF_MBFUNC )                              \
 static __inline__ void PSZ_NAME( vpar_thread_t * p_vpar,                    \
                                  macroblock_t * p_mb )                      \
 {                                                                           \
-    int             i_dct_offset;                                           \
-    yuv_data_t *    p_lum_dest;                                             \
     idct_inner_t *  p_idct;                                                 \
+    int             i_b = 4;                                                \
                                                                             \
-    p_lum_dest = p_mb->pp_dest[0] + p_vpar->mb.i_offset;                    \
+    p_mb->p_y_data = p_mb->pp_dest[0] + p_vpar->mb.i_offset;                \
+    p_mb->p_u_data = p_mb->pp_dest[1] + (p_vpar->mb.i_offset                \
+                            >> p_vpar->sequence.b_chroma_h_subsampled);     \
+    p_mb->p_v_data = p_mb->pp_dest[2] + (p_vpar->mb.i_offset                \
+                            >> p_vpar->sequence.b_chroma_h_subsampled);     \
                                                                             \
-    if( p_mb->i_mb_modes & DCT_TYPE_INTERLACED )                            \
-    {                                                                       \
-        i_dct_offset = p_vpar->picture.i_field_width;                       \
-        p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width * 2;         \
-    }                                                                       \
-    else                                                                    \
+    DECODE_LUMABLOCK( 0, PF_MBFUNC );                                       \
+    DECODE_LUMABLOCK( 1, PF_MBFUNC );                                       \
+    DECODE_LUMABLOCK( 2, PF_MBFUNC );                                       \
+    DECODE_LUMABLOCK( 3, PF_MBFUNC );                                       \
+                                                                            \
+    do                                                                      \
     {                                                                       \
-        i_dct_offset = p_vpar->picture.i_field_width * 8;                   \
-        p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width;             \
+        DECODE_CHROMABLOCK( i_b, PF_MBFUNC, 1 );                            \
+        DECODE_CHROMABLOCK( i_b + 1, PF_MBFUNC, 2 );                        \
+        i_b += 2;                                                           \
     }                                                                       \
-    p_mb->i_chrom_dct_stride = p_vpar->picture.i_field_width >> 1;          \
-                                                                            \
-    DECODE_LUMABLOCK( 0, p_lum_dest, PF_MBFUNC );                           \
-    DECODE_LUMABLOCK( 1, p_lum_dest + 8, PF_MBFUNC );                       \
-    DECODE_LUMABLOCK( 2, p_lum_dest + i_dct_offset, PF_MBFUNC );            \
-    DECODE_LUMABLOCK( 3, p_lum_dest + i_dct_offset + 8, PF_MBFUNC );        \
-                                                                            \
-    p_idct = &p_mb->p_idcts[4];                                             \
-    memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) );                    \
-    p_idct->p_dct_data = p_mb->pp_dest[1] + (p_vpar->mb.i_offset >> 1);     \
-    p_vpar->mb.pi_dc_dct_pred[1] += GetChromaDCDiff( p_vpar );              \
-    p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[1]                      \
-                         << (3 - p_vpar->picture.i_intra_dc_precision );    \
-    PF_MBFUNC( p_vpar, p_idct );                                            \
-                                                                            \
-    p_idct = &p_mb->p_idcts[5];                                             \
-    memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) );                    \
-    p_idct->p_dct_data = p_mb->pp_dest[2] + (p_vpar->mb.i_offset >> 1);     \
-    p_vpar->mb.pi_dc_dct_pred[2] += GetChromaDCDiff( p_vpar );              \
-    p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[2]                      \
-                         << (3 - p_vpar->picture.i_intra_dc_precision );    \
-    PF_MBFUNC( p_vpar, p_idct );                                            \
+    while( i_b < 4 + p_vpar->sequence.i_chroma_nb_blocks );                 \
 }
 
 DECLARE_INTRAMB( MPEG1IntraMB, MPEG1Intra );
@@ -1010,53 +997,59 @@ DECLARE_INTRAMB( MPEG2IntraB15MB, MPEG2IntraB15 );
 
 #undef DECLARE_INTRAMB
 #undef DECODE_LUMABLOCK
+#undef DECODE_CHROMABLOCK
 
-#define DECODE_BLOCK( i_b, p_dest, PF_MBFUNC )                              \
-    if( p_mb->i_coded_block_pattern & (1 << (5 - i_b)) )                    \
+#define DECODE_LUMABLOCK( I_B, PF_MBFUNC )                                  \
+    if( p_mb->i_coded_block_pattern & (1 << (3 + p_vpar->sequence.i_chroma_nb_blocks - (I_B))) )                    \
     {                                                                       \
-        p_idct = &p_mb->p_idcts[i_b];                                       \
+        p_idct = &p_mb->p_idcts[I_B];                                       \
         memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) );                \
-        p_idct->p_dct_data = p_dest;                                        \
-        PF_MBFUNC( p_vpar, p_idct );                                        \
+        PF_MBFUNC( p_vpar, p_idct,                                          \
+                   p_vpar->sequence.nonintra_quant.pi_matrix );             \
+    }
+
+#define DECODE_CHROMABLOCK( I_B, PF_MBFUNC )                                \
+    if( p_mb->i_coded_block_pattern & (1 << (3 + p_vpar->sequence.i_chroma_nb_blocks - (I_B))) )                    \
+    {                                                                       \
+        p_idct = &p_mb->p_idcts[I_B];                                       \
+        memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) );                \
+        PF_MBFUNC( p_vpar, p_idct,                                          \
+                   p_vpar->sequence.chroma_nonintra_quant.pi_matrix );      \
     }
 
 #define DECLARE_NONINTRAMB( PSZ_NAME, PF_MBFUNC )                           \
 static __inline__ void PSZ_NAME( vpar_thread_t * p_vpar,                    \
                                  macroblock_t * p_mb )                      \
 {                                                                           \
-    int             i_dct_offset;                                           \
-    yuv_data_t *    p_lum_dest;                                             \
     idct_inner_t *  p_idct;                                                 \
+    int             i_b = 4;                                                \
                                                                             \
-    p_lum_dest = p_mb->pp_dest[0] + p_vpar->mb.i_offset;                    \
+    p_mb->p_y_data = p_mb->pp_dest[0] + p_vpar->mb.i_offset;                \
+    p_mb->p_u_data = p_mb->pp_dest[1] + (p_vpar->mb.i_offset                \
+                            >> p_vpar->sequence.b_chroma_h_subsampled);     \
+    p_mb->p_v_data = p_mb->pp_dest[2] + (p_vpar->mb.i_offset                \
+                            >> p_vpar->sequence.b_chroma_h_subsampled);     \
                                                                             \
-    if( p_mb->i_mb_modes & DCT_TYPE_INTERLACED )                            \
-    {                                                                       \
-        i_dct_offset = p_vpar->picture.i_field_width;                       \
-        p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width * 2;         \
-    }                                                                       \
-    else                                                                    \
+    DECODE_LUMABLOCK( 0, PF_MBFUNC );                                       \
+    DECODE_LUMABLOCK( 1, PF_MBFUNC );                                       \
+    DECODE_LUMABLOCK( 2, PF_MBFUNC );                                       \
+    DECODE_LUMABLOCK( 3, PF_MBFUNC );                                       \
+                                                                            \
+    do                                                                      \
     {                                                                       \
-        i_dct_offset = p_vpar->picture.i_field_width * 8;                   \
-        p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width;             \
+        DECODE_CHROMABLOCK( i_b, PF_MBFUNC );                               \
+        DECODE_CHROMABLOCK( i_b + 1, PF_MBFUNC );                           \
+        i_b += 2;                                                           \
     }                                                                       \
-    p_mb->i_chrom_dct_stride = p_vpar->picture.i_field_width >> 1;          \
-                                                                            \
-    DECODE_BLOCK( 0, p_lum_dest, PF_MBFUNC );                               \
-    DECODE_BLOCK( 1, p_lum_dest + 8, PF_MBFUNC );                           \
-    DECODE_BLOCK( 2, p_lum_dest + i_dct_offset, PF_MBFUNC );                \
-    DECODE_BLOCK( 3, p_lum_dest + i_dct_offset + 8, PF_MBFUNC );            \
-    DECODE_BLOCK( 4, p_mb->pp_dest[1] + (p_vpar->mb.i_offset >> 1),         \
-                  PF_MBFUNC );                                              \
-    DECODE_BLOCK( 5, p_mb->pp_dest[2] + (p_vpar->mb.i_offset >> 1),         \
-                  PF_MBFUNC );                                              \
+    while( i_b < 4 + p_vpar->sequence.i_chroma_nb_blocks );                 \
 }
 
 DECLARE_NONINTRAMB( MPEG1NonIntraMB, MPEG1NonIntra );
 DECLARE_NONINTRAMB( MPEG2NonIntraMB, MPEG2NonIntra );
 
 #undef DECLARE_NONINTRAMB
-#undef DECODE_BLOCK
+#undef DECODE_LUMABLOCK
+#undef DECODE_CHROMABLOCK
 
 
 /*
@@ -1592,16 +1585,48 @@ static __inline__ int CodedPattern( vpar_thread_t * p_vpar )
     lookup_t *  p_tab;
     int         i_code;
 
-    if( (i_code = ShowBits( &p_vpar->bit_stream, 7 )) >= 0x10 ) /* ? */
+    if( (i_code = ShowBits( &p_vpar->bit_stream, 7 )) >= 0x10 )
     {
         p_tab = CBP_7 - 16 + i_code;
         RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+        if( p_vpar->sequence.i_chroma_format != CHROMA_420 )
+        {
+            int i_value = p_tab->i_value;
+
+            if( p_vpar->sequence.i_chroma_format != CHROMA_444 )
+            {
+                i_value <<= 2;
+                i_value |= GetBits( &p_vpar->bit_stream, 2 );
+            }
+            else
+            {
+                i_value <<= 6;
+                i_value |= GetBits( &p_vpar->bit_stream, 6 );
+            }
+            return( i_value );
+        }
         return( p_tab->i_value );
     }
     else
     {
         p_tab = CBP_9 + ShowBits( &p_vpar->bit_stream, 9 );
         RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+        if( p_vpar->sequence.i_chroma_format != CHROMA_420 )
+        {
+            int i_value = p_tab->i_value;
+
+            if( p_vpar->sequence.i_chroma_format != CHROMA_444 )
+            {
+                i_value <<= 2;
+                i_value |= GetBits( &p_vpar->bit_stream, 2 );
+            }
+            else
+            {
+                i_value <<= 6;
+                i_value |= GetBits( &p_vpar->bit_stream, 6 );
+            }
+            return( i_value );
+        }
         return( p_tab->i_value );
     }
 }
@@ -1746,18 +1771,18 @@ mb_intra:
             p_vpar->picture.b_concealment_mv )                              \
         {                                                                   \
             p_f_motion->pppi_ref[0][0] += 16 * i_offset;                    \
-            p_f_motion->pppi_ref[0][1] += 4 * i_offset;                     \
-            p_f_motion->pppi_ref[0][2] += 4 * i_offset;                     \
+            p_f_motion->pppi_ref[0][1] += i_chroma_tmp;                  \
+            p_f_motion->pppi_ref[0][2] += i_chroma_tmp;                  \
         }                                                                   \
         if( i_coding_type == B_CODING_TYPE )                                \
         {                                                                   \
             p_b_motion->pppi_ref[0][0] += 16 * i_offset;                    \
-            p_b_motion->pppi_ref[0][1] += 4 * i_offset;                     \
-            p_b_motion->pppi_ref[0][2] += 4 * i_offset;                     \
+            p_b_motion->pppi_ref[0][1] += i_chroma_tmp;                  \
+            p_b_motion->pppi_ref[0][2] += i_chroma_tmp;                  \
         }                                                                   \
         p_dest[0] += 16 * i_offset;                                         \
-        p_dest[1] += 4 * i_offset;                                          \
-        p_dest[2] += 4 * i_offset;                                          \
+        p_dest[1] += 4 * i_offset;                                       \
+        p_dest[2] += 4 * i_offset;                                       \
         i_offset = 0;                                                       \
     }                                                                       \
     p_vpar->mb.i_offset = i_offset;
@@ -1774,7 +1799,7 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
                                    u32 i_vert_code, boolean_t b_mpeg2,
                                    int i_coding_type, int i_structure )
 {
-    int             i_offset, i_width;
+    int             i_offset, i_width, i_chroma_tmp;
     picture_t *     pp_forward_ref[2];
     yuv_data_t *    p_dest[3];
 
@@ -1805,6 +1830,10 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
     if( i_structure != FRAME_STRUCTURE )
     {
         i_offset <<= 1;
+        i_chroma_tmp =
+            i_offset * (2 - p_vpar->sequence.b_chroma_v_subsampled)
+             * (2 - p_vpar->sequence.b_chroma_h_subsampled)
+              + (i_width >> p_vpar->sequence.b_chroma_h_subsampled);
         pp_forward_ref[1] = p_vpar->sequence.p_forward;
 
         if( i_coding_type != B_CODING_TYPE && p_vpar->picture.b_second_field )
@@ -1815,28 +1844,31 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
         if( i_coding_type != I_CODING_TYPE || p_vpar->picture.b_concealment_mv )
         {
             p_f_motion->pppi_ref[1][0] =
-                    pp_forward_ref[1]->p_y + i_offset * 4 + i_width;
+                pp_forward_ref[1]->p_y + i_offset * 4 + i_width;
             p_f_motion->pppi_ref[1][1] =
-                    pp_forward_ref[1]->p_u + i_offset + (i_width >> 1);
+                pp_forward_ref[1]->p_u + i_chroma_tmp;
             p_f_motion->pppi_ref[1][2] =
-                    pp_forward_ref[1]->p_v + i_offset + (i_width >> 1);
+                pp_forward_ref[1]->p_v + i_chroma_tmp;
         }
         if( i_coding_type == B_CODING_TYPE )
         {
             p_b_motion->pppi_ref[1][0] =
                 p_vpar->sequence.p_backward->p_y + i_offset * 4 + i_width;
             p_b_motion->pppi_ref[1][1] =
-                p_vpar->sequence.p_backward->p_u + i_offset + (i_width >> 1);
+                p_vpar->sequence.p_backward->p_u + i_chroma_tmp;
             p_b_motion->pppi_ref[1][2] =
-                p_vpar->sequence.p_backward->p_v + i_offset + (i_width >> 1);
+                p_vpar->sequence.p_backward->p_v + i_chroma_tmp;
         }
     }
 
+    i_chroma_tmp = i_offset
+                        * (2 - p_vpar->sequence.b_chroma_v_subsampled)
+                        * (2 - p_vpar->sequence.b_chroma_h_subsampled);
     if( i_coding_type != I_CODING_TYPE || p_vpar->picture.b_concealment_mv )
     {
         p_f_motion->pppi_ref[0][0] = pp_forward_ref[0]->p_y + i_offset * 4;
-        p_f_motion->pppi_ref[0][1] = pp_forward_ref[0]->p_u + i_offset;
-        p_f_motion->pppi_ref[0][2] = pp_forward_ref[0]->p_v + i_offset;
+        p_f_motion->pppi_ref[0][1] = pp_forward_ref[0]->p_u + i_chroma_tmp;
+        p_f_motion->pppi_ref[0][2] = pp_forward_ref[0]->p_v + i_chroma_tmp;
         p_f_motion->pi_f_code[0] = p_vpar->picture.ppi_f_code[0][0];
         p_f_motion->pi_f_code[1] = p_vpar->picture.ppi_f_code[0][1];
         p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0;
@@ -1848,9 +1880,9 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
         p_b_motion->pppi_ref[0][0] = p_vpar->sequence.p_backward->p_y
                                         + i_offset * 4;
         p_b_motion->pppi_ref[0][1] = p_vpar->sequence.p_backward->p_u
-                                        + i_offset;
+            + i_chroma_tmp;
         p_b_motion->pppi_ref[0][2] = p_vpar->sequence.p_backward->p_v
-                                        + i_offset;
+            + i_chroma_tmp;
         p_b_motion->pi_f_code[0] = p_vpar->picture.ppi_f_code[1][0];
         p_b_motion->pi_f_code[1] = p_vpar->picture.ppi_f_code[1][1];
         p_b_motion->ppi_pmv[0][0] = p_b_motion->ppi_pmv[0][1] = 0;
@@ -1859,14 +1891,14 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
 
     /* Initialize destination pointers. */
     p_dest[0] = p_vpar->picture.p_picture->p_y + i_offset * 4;
-    p_dest[1] = p_vpar->picture.p_picture->p_u + i_offset;
-    p_dest[2] = p_vpar->picture.p_picture->p_v + i_offset;
+    p_dest[1] = p_vpar->picture.p_picture->p_u + i_chroma_tmp;
+    p_dest[2] = p_vpar->picture.p_picture->p_v + i_chroma_tmp;
 
     if( i_structure == BOTTOM_FIELD )
     {
         p_dest[0] += i_width;
-        p_dest[1] += i_width >> 1;
-        p_dest[2] += i_width >> 1;
+        p_dest[1] += i_width >> p_vpar->sequence.b_chroma_h_subsampled;
+        p_dest[2] += i_width >> p_vpar->sequence.b_chroma_h_subsampled;
     }
     i_width = p_vpar->picture.i_field_width;
 
@@ -1877,19 +1909,22 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
 
     p_vpar->mb.i_offset = MacroblockAddressIncrement( p_vpar ) << 4;
 
+    i_chroma_tmp = i_width * 4
+                        * (2 - p_vpar->sequence.b_chroma_v_subsampled)
+                        * (2 - p_vpar->sequence.b_chroma_h_subsampled);
     while( (int)(p_vpar->mb.i_offset - p_vpar->sequence.i_width) >= 0 )
     {
         /* Unusual construct at the start of some slices. Jump one line. */
         p_vpar->mb.i_offset -= p_vpar->sequence.i_width;
         p_dest[0] += i_width * 16;
-        p_dest[1] += i_width * 4;
-        p_dest[2] += i_width * 4;
+        p_dest[1] += i_chroma_tmp;
+        p_dest[2] += i_chroma_tmp;
         p_f_motion->pppi_ref[0][0] += i_width * 16;
-        p_f_motion->pppi_ref[0][1] += i_width * 4;
-        p_f_motion->pppi_ref[0][2] += i_width * 4;
+        p_f_motion->pppi_ref[0][1] += i_chroma_tmp;
+        p_f_motion->pppi_ref[0][2] += i_chroma_tmp;
         p_f_motion->pppi_ref[1][0] += i_width * 16;
-        p_f_motion->pppi_ref[1][1] += i_width * 4;
-        p_f_motion->pppi_ref[1][2] += i_width * 4;
+        p_f_motion->pppi_ref[1][1] += i_chroma_tmp;
+        p_f_motion->pppi_ref[1][2] += i_chroma_tmp;
     }
 
     for( ; ; )
@@ -1937,7 +1972,6 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
             }
 
             /* Decode blocks */
-            p_mb->i_coded_block_pattern = (1 << 6) - 1;
             if( b_mpeg2 )
             {
                 if( p_vpar->picture.b_intra_vlc_format )
index bbbab23d50c646079fc2d2fc5bf9141bb313cd03..0198fde08236f10dc4ec67de9e1d85601d7a9020 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_headers.c : headers parsing
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_headers.c,v 1.11 2001/10/01 16:44:07 massiot Exp $
+ * $Id: vpar_headers.c,v 1.12 2001/10/11 13:19:27 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Stéphane Borel <stef@via.ecp.fr>
@@ -46,6 +46,7 @@
 #include "vdec_ext-plugins.h"
 #include "vpar_pool.h"
 #include "video_parser.h"
+#include "video_decoder.h"
 
 /*
  * Local prototypes
@@ -397,6 +398,24 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
     p_vpar->sequence.i_height = (p_vpar->sequence.i_mb_height * 16);
     p_vpar->sequence.i_size = p_vpar->sequence.i_width
                                         * p_vpar->sequence.i_height;
+    switch( p_vpar->sequence.i_chroma_format )
+    {
+    case CHROMA_420:
+        p_vpar->sequence.i_chroma_nb_blocks = 2;
+        p_vpar->sequence.b_chroma_h_subsampled = 1;
+        p_vpar->sequence.b_chroma_v_subsampled = 1;
+        break;
+    case CHROMA_422:
+        p_vpar->sequence.i_chroma_nb_blocks = 4;
+        p_vpar->sequence.b_chroma_h_subsampled = 1;
+        p_vpar->sequence.b_chroma_v_subsampled = 0;
+        break;
+    case CHROMA_444:
+        p_vpar->sequence.i_chroma_nb_blocks = 6;
+        p_vpar->sequence.b_chroma_h_subsampled = 0;
+        p_vpar->sequence.b_chroma_v_subsampled = 0;
+        break;
+    }
 
 #if 0
     if(    p_vpar->sequence.i_width != i_width_save
@@ -750,6 +769,28 @@ static void PictureHeader( vpar_thread_t * p_vpar )
     p_vpar->picture.b_current_field =
         (i_structure == BOTTOM_FIELD );
 
+    if( !p_vpar->p_config->decoder_config.p_stream_ctrl->b_grayscale )
+    {
+        switch( p_vpar->sequence.i_chroma_format )
+        {
+        case CHROMA_422:
+            p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblock422;
+            break;
+        case CHROMA_444:
+            p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblock444;
+            break;
+        case CHROMA_420:
+        default:
+            p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblock420;
+            break;
+        }
+    }
+    else
+    {
+        p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblockBW;
+    }
+
+
     if( p_vpar->sequence.b_mpeg2 )
     {
         static f_picture_data_t ppf_picture_data[4][4] =
index bdde52407ac0a57e1c5c5122a6fde680ee1e685e..4490cc7db2b4ed240b3a929eee8c2e17350f9550 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_pool.c : management of the pool of decoder threads
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: vpar_pool.c,v 1.3 2001/09/25 11:46:14 massiot Exp $
+ * $Id: vpar_pool.c,v 1.4 2001/10/11 13:19:27 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -77,6 +77,7 @@ void vpar_InitPool( vpar_thread_t * p_vpar )
     p_vpar->pool.p_macroblocks = NULL;
     p_vpar->pool.pp_empty_macroblocks = NULL;
     p_vpar->pool.pp_new_macroblocks = NULL;
+    p_vpar->pool.p_vpar = p_vpar;
     vpar_SpawnPool( p_vpar );
 
     /* Initialize fake video decoder structure (used when
@@ -92,7 +93,7 @@ void vpar_InitPool( vpar_thread_t * p_vpar )
     p_vpar->pool.p_vdec->p_pool = &p_vpar->pool;
     vdec_InitThread( p_vpar->pool.p_vdec );
 
-    for( j = 0; j < 6; j++ )
+    for( j = 0; j < 12; j++ )
     {
         p_vpar->pool.mb.p_idcts[j].pi_block =
         memalign( 16, 64 * sizeof(dctelem_t) );
@@ -110,13 +111,11 @@ void vpar_InitPool( vpar_thread_t * p_vpar )
 void vpar_SpawnPool( vpar_thread_t * p_vpar )
 {
     int                 i_new_smp;
-    boolean_t           b_grayscale;
     stream_ctrl_t *     p_control;
 
     p_control = p_vpar->p_config->decoder_config.p_stream_ctrl;
     vlc_mutex_lock( &p_control->control_lock );
     i_new_smp = p_control->i_smp;
-    b_grayscale = p_control->b_grayscale;
     vlc_mutex_unlock( &p_control->control_lock );
 
     /* FIXME: No error check because I'm tired. Come back later... */
@@ -136,7 +135,7 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar )
 
                 vdec_DestroyThread( p_vpar->pool.pp_vdec[i] );
 
-                for( j = 0; j < 6; j++ )
+                for( j = 0; j < 12; j++ )
                 {
                     free( p_vpar->pool.p_macroblocks[i].p_idcts[j].pi_block );
                 }
@@ -172,7 +171,7 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar )
             {
                 int j;
 
-                for( j = 0; j < 6; j++ )
+                for( j = 0; j < 12; j++ )
                 {
                     p_vpar->pool.p_macroblocks[i].p_idcts[j].pi_block =
                         memalign( 16, 64 * sizeof(dctelem_t) );
@@ -206,15 +205,6 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar )
         p_vpar->pool.pf_free_mb = FreeMacroblockDummy;
         p_vpar->pool.pf_decode_mb = DecodeMacroblockDummy;
     }
-
-    if( !b_grayscale )
-    {
-        p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblockC;
-    }
-    else
-    {
-        p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblockBW;
-    }
 }
 
 /*****************************************************************************
@@ -230,7 +220,7 @@ void vpar_EndPool( vpar_thread_t * p_vpar )
 
         vdec_DestroyThread( p_vpar->pool.pp_vdec[i] );
 
-        for( j = 0; j < 6; j++ )
+        for( j = 0; j < 12; j++ )
         {
             free( p_vpar->pool.p_macroblocks[i].p_idcts[j].pi_block );
         }
index 242a0ad19319a004bdbfe58e8614a9de2315f491..1b3741065d26ae5caf223055f1e65ab0ae34106a 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_pool.h : video parser/video decoders communication
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_pool.h,v 1.3 2001/09/05 16:07:50 massiot Exp $
+ * $Id: vpar_pool.h,v 1.4 2001/10/11 13:19:27 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -76,6 +76,8 @@ typedef struct vdec_pool_s
     void ( * pf_idct_init )   ( void ** );
     void ( * ppppf_motion[2][2][4] ) ( yuv_data_t *, yuv_data_t *,
                                        int, int );
+
+    struct vpar_thread_s * p_vpar;
 } vdec_pool_t;
 
 /*****************************************************************************