]> git.sesse.net Git - vlc/blobdiff - src/video_decoder/vpar_blocks.c
* Altivec IDCT and motion compensation, based on Paul Mackerras's mpeg2dec
[vlc] / src / video_decoder / vpar_blocks.c
index c143d606ad08b873057e96c4276536089d683251..87a072a925a50b25bd84cb5ca55b6c4a7dde46c4 100644 (file)
@@ -2,11 +2,11 @@
  * vpar_blocks.c : blocks parsing
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_blocks.c,v 1.2 2001/07/17 09:48:08 massiot Exp $
+ * $Id: vpar_blocks.c,v 1.9 2001/09/05 16:07:50 massiot Exp $
  *
- * Authors: Christophe Massiot <massiot@via.ecp.fr>
- *          Jean-Marc Dressler <polux@via.ecp.fr>
- *          Stéphane Borel <stef@via.ecp.fr>
+ * Authors: Michel Lespinasse <walken@zoy.org>
+ *          Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *          Christophe Massiot <massiot@via.ecp.fr>
  *
  * 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
 #include "video_output.h"
 
 #include "vdec_ext-plugins.h"
-#include "video_decoder.h"
+#include "vpar_pool.h"
+#include "video_parser.h"
 
 #include "vpar_blocks.h"
-#include "vpar_headers.h"
-#include "vpar_synchro.h"
-#include "video_parser.h"
-#include "video_fifo.h"
 
 /*
  * Welcome to vpar_blocks.c ! Here's where the heavy processor-critical parsing
  * task is done. This file is divided in several parts :
- *  - Initialization of the lookup tables
  *  - Decoding of coded blocks
  *  - Decoding of motion vectors
  *  - Decoding of the other macroblock structures
  */
 
 
-/*
- * Initialization tables
- */
+/*****************************************************************************
+ * vpar_InitScanTable : Initialize scan table
+ *****************************************************************************/
+void vpar_InitScanTable( vpar_thread_t * p_vpar )
+{
+    int     i;
 
-    /* Table for coded_block_pattern resolution */
-static lookup_t     pl_coded_pattern[512] =
-    { {MB_ERROR, 0}, {0, 9}, {39, 9}, {27, 9}, {59, 9}, {55, 9}, {47, 9}, {31, 9},
-    {58, 8}, {58, 8}, {54, 8}, {54, 8}, {46, 8}, {46, 8}, {30, 8}, {30, 8},
-    {57, 8}, {57, 8}, {53, 8}, {53, 8}, {45, 8}, {45, 8}, {29, 8}, {29, 8},
-    {38, 8}, {38, 8}, {26, 8}, {26, 8}, {37, 8}, {37, 8}, {25, 8}, {25, 8},
-    {43, 8}, {43, 8}, {23, 8}, {23, 8}, {51, 8}, {51, 8}, {15, 8}, {15, 8},
-    {42, 8}, {42, 8}, {22, 8}, {22, 8}, {50, 8}, {50, 8}, {14, 8}, {14, 8},
-    {41, 8}, {41, 8}, {21, 8}, {21, 8}, {49, 8}, {49, 8}, {13, 8}, {13, 8},
-    {35, 8}, {35, 8}, {19, 8}, {19, 8}, {11, 8}, {11, 8}, {7, 8}, {7, 8},
-    {34, 7}, {34, 7}, {34, 7}, {34, 7}, {18, 7}, {18, 7}, {18, 7}, {18, 7},
-    {10, 7}, {10, 7}, {10, 7}, {10, 7}, {6, 7}, {6, 7}, {6, 7}, {6, 7},
-    {33, 7}, {33, 7}, {33, 7}, {33, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
-    {9, 7}, {9, 7}, {9, 7}, {9, 7}, {5, 7}, {5, 7}, {5, 7}, {5, 7},
-    {63, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6}, {63, 6},
-    {3, 6}, {3, 6}, {3, 6}, {3, 6}, {3, 6}, {3, 6}, {3, 6}, {3, 6},
-    {36, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6}, {36, 6},
-    {24, 6}, {24, 6}, {24, 6}, {24, 6}, {24, 6}, {24, 6}, {24, 6}, {24, 6},
-    {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5},
-    {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5}, {62, 5},
-    {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5},
-    {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5}, {2, 5},
-    {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5},
-    {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5}, {61, 5},
-    {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5},
-    {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5}, {1, 5},
-    {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5},
-    {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5}, {56, 5},
-    {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5},
-    {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5}, {52, 5},
-    {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5},
-    {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5}, {44, 5},
-    {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5},
-    {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5}, {28, 5},
-    {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5},
-    {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5}, {40, 5},
-    {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5},
-    {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5}, {20, 5},
-    {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5},
-    {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5}, {48, 5},
-    {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
-    {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
-    {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4},
-    {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4},
-    {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4},
-    {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4}, {32, 4},
-    {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4},
-    {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4},
-    {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4},
-    {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4}, {16, 4},
-    {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4},
-    {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4},
-    {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4},
-    {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4}, {8, 4},
-    {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4},
-    {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4},
-    {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4},
-    {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4}, {4, 4},
-    {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3},
-    {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3},
-    {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3},
-    {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3},
-    {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3},
-    {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3},
-    {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3},
-    {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3}, {60, 3} };
-
-    /* Tables for dc DCT coefficients
-     * Tables are cut in two parts to reduce memory occupation
-     */
-
-    /* Table B-12, dct_dc_size_luminance, codes 00XXX ... 11110 */
-
-static lookup_t     pl_dct_dc_lum_init_table_1[32] =
-    { {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
-      {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
-      {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3},
-      {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {MB_ERROR, 0}
-    };
-
-static lookup_t     ppl_dct_dc_init_table_1[2][32] =
-{    { {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
-      {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
-      {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3},
-      {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {MB_ERROR, 0}},
-{ {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
-      {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
-      {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
-      {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {MB_ERROR, 0}
-    }
-    };
-
-    /* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */
-
-static lookup_t     pl_dct_dc_lum_init_table_2[32] =
-    { {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6},
-      {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9},
-      {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0},
-      {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0},
-      {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0},
-      {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}
-    };
-
-static lookup_t     ppl_dct_dc_init_table_2[2][32] =
-{    { {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6},
-      {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9},
-      {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0},
-      {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0},
-      {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0},
-      {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}, {MB_ERROR, 0}},
-    { {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
-      {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
-      {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7},
-      {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10}
-    }
-    };
-
-    /* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */
-static lookup_t     pl_dct_dc_chrom_init_table_1[32] =
- { {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
-      {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
-      {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
-      {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {MB_ERROR, 0}
-    };
-    
+    memcpy( p_vpar->ppi_scan, pi_scan, sizeof(pi_scan) );
+    p_vpar->pf_norm_scan( p_vpar->ppi_scan );
 
-   /* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */
-static lookup_t     pl_dct_dc_chrom_init_table_2[32] =
-    { {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
-      {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
-      {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7},
-      {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10}
-    };
-
-    /* Tables for ac DCT coefficients. There are cut in many parts to
-     * save space */
-    /* Table B-14, DCT coefficients table zero,
-     * codes 0100 ... 1xxx (used for first (DC) coefficient)
-     */
-static dct_lookup_t pl_DCT_tab_dc[12] =
-    {
-        {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3},
-        {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1},
-        {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}
-    };
-
-    /* Table B-14, DCT coefficients table zero,
-     * codes 0100 ... 1xxx (used for all other coefficients)
-     */
-static dct_lookup_t pl_DCT_tab_ac[12] =
-    {
-        {0,2,4},  {2,1,4},  {1,1,3},  {1,1,3},
-        {DCT_EOB,0,2}, {DCT_EOB,0,2}, {DCT_EOB,0,2}, {DCT_EOB,0,2}, /* EOB */
-        {0,1,2},  {0,1,2},  {0,1,2},  {0,1,2}
-    };
-
-    /* Table B-14, DCT coefficients table zero,
-     * codes 000001xx ... 00111xxx
-     */
-static dct_lookup_t pl_DCT_tab0[60] =
-    {
-        {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6}, {DCT_ESCAPE,0,6},
-        /* Escape */
-        {2,2,7}, {2,2,7}, {9,1,7}, {9,1,7},
-        {0,4,7}, {0,4,7}, {8,1,7}, {8,1,7},
-        {7,1,6}, {7,1,6}, {7,1,6}, {7,1,6},
-        {6,1,6}, {6,1,6}, {6,1,6}, {6,1,6},
-        {1,2,6}, {1,2,6}, {1,2,6}, {1,2,6},
-        {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6},
-        {13,1,8}, {0,6,8}, {12,1,8}, {11,1,8},
-        {3,2,8}, {1,3,8}, {0,5,8}, {10,1,8},
-        {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5},
-        {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5},
-        {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5},
-        {4,1,5}, {4,1,5}, {4,1,5}, {4,1,5},
-        {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
-        {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}
-    };
-
-    /* Table B-15, DCT coefficients table one,
-     * codes 000001xx ... 11111111
-     */
-static dct_lookup_t pl_DCT_tab0a[252] =
-    {
-        {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */
-        {7,1,7}, {7,1,7}, {8,1,7}, {8,1,7},
-        {6,1,7}, {6,1,7}, {2,2,7}, {2,2,7},
-        {0,7,6}, {0,7,6}, {0,7,6}, {0,7,6},
-        {0,6,6}, {0,6,6}, {0,6,6}, {0,6,6},
-        {4,1,6}, {4,1,6}, {4,1,6}, {4,1,6},
-        {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6},
-        {1,5,8}, {11,1,8}, {0,11,8}, {0,10,8},
-        {13,1,8}, {12,1,8}, {3,2,8}, {1,4,8},
-        {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5},
-        {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5},
-        {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5},
-        {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5},
-        {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
-        {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
-        {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
-        {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
-        {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
-        {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
-        {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
-        {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
-        {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
-        {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
-        {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */
-        {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
-        {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
-        {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
-        {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
-        {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
-        {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
-        {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
-        {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
-        {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
-        {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
-        {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
-        {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
-        {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
-        {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
-        {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
-        {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5},
-        {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5},
-        {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5},
-        {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5},
-        {9,1,7}, {9,1,7}, {1,3,7}, {1,3,7},
-        {10,1,7}, {10,1,7}, {0,8,7}, {0,8,7},
-        {0,9,7}, {0,9,7}, {0,12,8}, {0,13,8},
-        {2,3,8}, {4,2,8}, {0,14,8}, {0,15,8}
-    };
-
-    /* Table B-14, DCT coefficients table zero,
-     * codes 0000001000 ... 0000001111
-     */
-static dct_lookup_t pl_DCT_tab1[8] =
-    {
-        {16,1,10}, {5,2,10}, {0,7,10}, {2,3,10},
-        {1,4,10}, {15,1,10}, {14,1,10}, {4,2,10}
-    };
-
-    /* Table B-15, DCT coefficients table one,
-     * codes 000000100x ... 000000111x
-     */
-static dct_lookup_t pl_DCT_tab1a[8] =
-    {
-        {5,2,9}, {5,2,9}, {14,1,9}, {14,1,9},
-        {2,4,10}, {16,1,10}, {15,1,9}, {15,1,9}
-    };
-
-    /* Table B-14/15, DCT coefficients table zero / one,
-     * codes 000000010000 ... 000000011111
-     */
-static dct_lookup_t pl_DCT_tab2[16] =
-    {
-        {0,11,12}, {8,2,12}, {4,3,12}, {0,10,12},
-        {2,4,12}, {7,2,12}, {21,1,12}, {20,1,12},
-        {0,9,12}, {19,1,12}, {18,1,12}, {1,5,12},
-        {3,3,12}, {0,8,12}, {6,2,12}, {17,1,12}
-    };
-
-    /* Table B-14/15, DCT coefficients table zero / one,
-     * codes 0000000010000 ... 0000000011111
-     */
-static dct_lookup_t pl_DCT_tab3[16] =
-    {
-        {10,2,13}, {9,2,13}, {5,3,13}, {3,4,13},
-        {2,5,13}, {1,7,13}, {1,6,13}, {0,15,13},
-        {0,14,13}, {0,13,13}, {0,12,13}, {26,1,13},
-        {25,1,13}, {24,1,13}, {23,1,13}, {22,1,13}
-    };
-
-    /* Table B-14/15, DCT coefficients table zero / one,
-     * codes 00000000010000 ... 00000000011111
-     */
-static dct_lookup_t pl_DCT_tab4[16] =
-    {
-        {0,31,14}, {0,30,14}, {0,29,14}, {0,28,14},
-        {0,27,14}, {0,26,14}, {0,25,14}, {0,24,14},
-        {0,23,14}, {0,22,14}, {0,21,14}, {0,20,14},
-        {0,19,14}, {0,18,14}, {0,17,14}, {0,16,14}
-    };
-
-    /* Table B-14/15, DCT coefficients table zero / one,
-     *   codes 000000000010000 ... 000000000011111
-     */
-static dct_lookup_t pl_DCT_tab5[16] =
-    {
-    {0,40,15}, {0,39,15}, {0,38,15}, {0,37,15},
-    {0,36,15}, {0,35,15}, {0,34,15}, {0,33,15},
-    {0,32,15}, {1,14,15}, {1,13,15}, {1,12,15},
-    {1,11,15}, {1,10,15}, {1,9,15}, {1,8,15}
-    };
-
-    /* Table B-14/15, DCT coefficients table zero / one,
-     * codes 0000000000010000 ... 0000000000011111
-     */
-static dct_lookup_t pl_DCT_tab6[16] =
+    /* If scan table has changed, we must change the quantization matrices. */
+    for( i = 0; i < 64; i++ )
     {
-        {1,18,16}, {1,17,16}, {1,16,16}, {1,15,16},
-        {6,3,16}, {16,2,16}, {15,2,16}, {14,2,16},
-        {13,2,16}, {12,2,16}, {11,2,16}, {31,1,16},
-        {30,1,16}, {29,1,16}, {28,1,16}, {27,1,16}
-    };
-
-    /* Pointers on tables of dct coefficients */
-static dct_lookup_t * ppl_dct_tab1[2] = { pl_DCT_tab_ac, pl_DCT_tab0a };
-
-static dct_lookup_t * ppl_dct_tab2[2] = { pl_DCT_tab_ac, pl_DCT_tab_dc };
-
-/* Replacement for memset( p_table, 0, 8*sizeof( int ) ); */
-static __inline__ void bzero8int( void *p_table )
-{
-    ((int*)p_table)[0] = ((int*)p_table)[1] =
-    ((int*)p_table)[2] = ((int*)p_table)[3] = 
-    ((int*)p_table)[4] = ((int*)p_table)[5] =
-    ((int*)p_table)[6] = ((int*)p_table)[7] = 0;
+        p_vpar->pi_default_intra_quant[ p_vpar->ppi_scan[0][i] ] =
+            pi_default_intra_quant[ pi_scan[0][i] ];
+        p_vpar->pi_default_nonintra_quant[ p_vpar->ppi_scan[0][i] ] =
+            pi_default_nonintra_quant[ pi_scan[0][i] ];
+    }
 }
 
+
 /*
- * Initialization of lookup tables
+ * Block parsing
  */
 
 /*****************************************************************************
- * vpar_InitMbAddrInc : Initialize the lookup table for mb_addr_inc
+ * GetLumaDCDiff : Get the luminance DC coefficient difference
  *****************************************************************************/
-
-/* Function for filling up the lookup table for mb_addr_inc */
-static void FillMbAddrIncTable( vpar_thread_t * p_vpar,
-                                    int i_start, int i_end, int i_step,
-                                    int * pi_value, int i_length )
+static __inline__ int GetLumaDCDiff( vpar_thread_t * p_vpar )
 {
-    int i_pos, i_offset;
-    for( i_pos = i_start ; i_pos < i_end ; i_pos += i_step )
+    lookup_t *  p_tab;
+    int         i_size, i_dc_diff, i_code;
+
+    if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) < 0x1F )
     {
-        for( i_offset = 0 ; i_offset < i_step ; i_offset ++ )
+        p_tab = DC_lum_5 + i_code;
+        i_size = p_tab->i_value;
+        if( i_size )
         {
-            p_vpar->pl_mb_addr_inc[i_pos + i_offset].i_value = * pi_value;
-            p_vpar->pl_mb_addr_inc[i_pos + i_offset].i_length = i_length;
+            RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+            i_dc_diff = GetBits( &p_vpar->bit_stream, i_size );
+            if ((i_dc_diff & (1 << (i_size - 1))) == 0)
+            {
+                i_dc_diff -= (1 << i_size) - 1;
+            }
+            return( i_dc_diff );
+        }
+        else
+        {
+            RemoveBits( &p_vpar->bit_stream, 3 );
+            return 0;
         }
-        (*pi_value)--;
+    }
+    else
+    {
+        p_tab = DC_long - 0x1e0 + ShowBits( &p_vpar->bit_stream, 9 );
+        RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+        i_size = p_tab->i_value;
+        i_dc_diff = GetBits( &p_vpar->bit_stream, i_size );
+        if ((i_dc_diff & (1 << (i_size - 1))) == 0)
+        {
+            i_dc_diff -= (1 << i_size) - 1;
+        }
+        return( i_dc_diff );
     }
 }
 
-/* Function that initialize the table using the last one */
-void vpar_InitMbAddrInc( vpar_thread_t * p_vpar )
+/*****************************************************************************
+ * GetChromaDCDiff : Get the chrominance DC coefficient difference
+ *****************************************************************************/
+static __inline__ int GetChromaDCDiff( vpar_thread_t * p_vpar )
 {
-    int i_dummy;
-    int i_value;
+    lookup_t *  p_tab;
+    int         i_size, i_dc_diff, i_code;
 
-    for( i_dummy = 0 ; i_dummy < 8 ; i_dummy++ )
+    if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) < 0x1F )
     {
-        p_vpar->pl_mb_addr_inc[i_dummy].i_value = MB_ERROR;
-        p_vpar->pl_mb_addr_inc[i_dummy].i_length = 0;
+        p_tab = DC_chrom_5 + i_code;
+        i_size = p_tab->i_value;
+        if( i_size )
+        {
+            RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+            i_dc_diff = GetBits( &p_vpar->bit_stream, i_size );
+            if ((i_dc_diff & (1 << (i_size - 1))) == 0)
+            {
+                i_dc_diff -= (1 << i_size) - 1;
+            }
+            return( i_dc_diff );
+        }
+        else
+        {
+            RemoveBits( &p_vpar->bit_stream, 2 );
+            return 0;
+        }
     }
-
-    p_vpar->pl_mb_addr_inc[8].i_value = MB_ADDRINC_ESCAPE;
-    p_vpar->pl_mb_addr_inc[8].i_length = 11;
-
-    for( i_dummy = 9 ; i_dummy < 15 ; i_dummy ++ )
+    else
     {
-        p_vpar->pl_mb_addr_inc[i_dummy].i_value =  MB_ERROR;
-        p_vpar->pl_mb_addr_inc[i_dummy].i_length = 0;
+        p_tab = DC_long - 0x3e0 + ShowBits( &p_vpar->bit_stream, 10 );
+        RemoveBits( &p_vpar->bit_stream, p_tab->i_length + 1 );
+        i_size = p_tab->i_value;
+        i_dc_diff = GetBits( &p_vpar->bit_stream, i_size );
+        if ((i_dc_diff & (1 << (i_size - 1))) == 0)
+        {
+            i_dc_diff -= (1 << i_size) - 1;
+        }
+        return( i_dc_diff );
     }
+}
 
-    p_vpar->pl_mb_addr_inc[15].i_value = MB_ADDRINC_STUFFING;
-    p_vpar->pl_mb_addr_inc[15].i_length = 11;
 
-    for( i_dummy = 16; i_dummy < 24; i_dummy++ )
-    {
-        p_vpar->pl_mb_addr_inc[i_dummy].i_value =  MB_ERROR;
-        p_vpar->pl_mb_addr_inc[i_dummy].i_length = 0;
+#define SATURATE(val)                                                       \
+    if ((u32)(val + 2048) > 4095)                                           \
+    {                                                                       \
+       val = (val > 0) ? 2047 : -2048;                                      \
     }
 
-    i_value = 33;
-
-    FillMbAddrIncTable( p_vpar, 24, 36, 1, &i_value, 11 );
-    FillMbAddrIncTable( p_vpar, 36, 48, 2, &i_value, 10 );
-    FillMbAddrIncTable( p_vpar, 48, 96, 8, &i_value, 8 );
-    FillMbAddrIncTable( p_vpar, 96, 128, 16, &i_value, 7 );
-    FillMbAddrIncTable( p_vpar, 128, 256, 64, &i_value, 5 );
-    FillMbAddrIncTable( p_vpar, 256, 512, 128, &i_value, 4 );
-    FillMbAddrIncTable( p_vpar, 512, 1024, 256, &i_value, 3 );
-    FillMbAddrIncTable( p_vpar, 1024, 2048, 1024, &i_value, 1 );
-}
-
 /*****************************************************************************
- * vpar_Init*MBType : Initialize lookup table for the Macroblock type
+ * MPEG2IntraB14 : Decode an intra block according to ISO/IEC 13818-2 table B14
  *****************************************************************************/
-
-/* Fonction for filling up the tables */
-static void FillMBType( vpar_thread_t * p_vpar,
-                                   int           i_mb_type,
-                                   int           i_start,
-                                   int           i_end,
-                                   int           i_value,
-                                   int           i_length )
+static void MPEG2IntraB14( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
 {
-    int i_dummy;
+    int         i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
+    s32         i_sign;
+    dct_lookup_t * p_tab;
 
-    for( i_dummy = i_start ; i_dummy < i_end ; i_dummy++ )
-    {
-        p_vpar->ppl_mb_type[i_mb_type][i_dummy].i_value = i_value;
-        p_vpar->ppl_mb_type[i_mb_type][i_dummy].i_length = i_length;
-    }
-}
+    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;
 
-/* Fonction that fills the table for P MB_Type */
-void vpar_InitPMBType( vpar_thread_t * p_vpar )
-{
-    FillMBType( p_vpar, 0, 32, 64, MB_MOTION_FORWARD|MB_PATTERN, 1 );
-    FillMBType( p_vpar, 0, 16, 32, MB_PATTERN, 2 );
-    FillMBType( p_vpar, 0, 8, 16, MB_MOTION_FORWARD, 3 );
-    FillMBType( p_vpar, 0, 6, 8, MB_INTRA, 5 );
-    FillMBType( p_vpar, 0, 4, 6, MB_QUANT|MB_MOTION_FORWARD|MB_PATTERN, 5 );
-    FillMBType( p_vpar, 0, 2, 4, MB_QUANT|MB_PATTERN, 5 );
-    p_vpar->ppl_mb_type[0][1].i_value = MB_QUANT|MB_INTRA;
-    p_vpar->ppl_mb_type[0][1].i_length = 6;
-    p_vpar->ppl_mb_type[0][0].i_value = MB_ERROR;
-    p_vpar->ppl_mb_type[0][0].i_length = 0;
-}
+    i_coeff = 0;
+    i_mismatch = ~p_dest[0];
+    i_nc = (p_dest[0] != 0);
 
-/* Fonction that fills the table for B MB_Type */
-void vpar_InitBMBType( vpar_thread_t * p_vpar )
-{
-    FillMBType( p_vpar, 1, 48, 64, MB_MOTION_FORWARD
-                                  |MB_MOTION_BACKWARD|MB_PATTERN, 2 );
-    FillMBType( p_vpar, 1, 32, 48, MB_MOTION_FORWARD|MB_MOTION_BACKWARD, 2 );
-    FillMBType( p_vpar, 1, 24, 32, MB_MOTION_BACKWARD|MB_PATTERN, 3 );
-    FillMBType( p_vpar, 1, 16, 24, MB_MOTION_BACKWARD, 3 );
-    FillMBType( p_vpar, 1, 12, 16, MB_MOTION_FORWARD|MB_PATTERN, 4 );
-    FillMBType( p_vpar, 1, 8, 12, MB_MOTION_FORWARD, 4 );
-    FillMBType( p_vpar, 1, 6, 8, MB_INTRA, 5 );
-    FillMBType( p_vpar, 1, 4, 6, MB_QUANT|MB_MOTION_FORWARD
-                                |MB_MOTION_BACKWARD|MB_PATTERN, 5 );
-    p_vpar->ppl_mb_type[1][3].i_value = MB_QUANT|MB_MOTION_FORWARD|MB_PATTERN;
-    p_vpar->ppl_mb_type[1][3].i_length = 6;
-    p_vpar->ppl_mb_type[1][2].i_value = MB_QUANT|MB_MOTION_BACKWARD|MB_PATTERN;
-    p_vpar->ppl_mb_type[1][2].i_length = 6;
-    p_vpar->ppl_mb_type[1][1].i_value = MB_QUANT|MB_INTRA;
-    p_vpar->ppl_mb_type[1][1].i_length = 6;
-    p_vpar->ppl_mb_type[1][0].i_value =MB_ERROR;
-    p_vpar->ppl_mb_type[1][0].i_length = 0;
-}
+    for( ; ; )
+    {
+        if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) >= 0x5 )
+        {
+            p_tab = DCT_B14AC_5 - 5 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff >= 64 )
+            {
+                /* End of block */
+                break;
+            }
 
+store_coeff:
+            i_nc++;
+            i_pos = p_scan[ i_coeff ];
+            RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+            i_value = (p_tab->i_level * i_q_scale * pi_quant[i_pos])
+                            >> 4;
 
-/*****************************************************************************
- * vpar_InitDCTTables : Initialize tables giving the length of the dct
- *                      coefficient from the vlc code
- *****************************************************************************/
+            i_sign = GetSignedBits( &p_vpar->bit_stream, 1 );
+            /* if (i_sign) i_value = -i_value; */
+            i_value = (i_value ^ i_sign) - i_sign;
 
-/* First fonction for filling the table */
-static void FillDCTTable( dct_lookup_t * p_tab_dest, dct_lookup_t * p_tab_src,
-                                     int i_step, int i_nb_elem, int i_offset )
-{
-    int i_dummy, i_dummy2;
+            SATURATE( i_value );
+            p_dest[i_pos] = i_value;
+            i_mismatch ^= i_value;
 
-    for( i_dummy=0 ; i_dummy < i_nb_elem ; i_dummy++ )
-    {
-        for( i_dummy2=0 ; i_dummy2 < i_step ; i_dummy2++ )
-        {
-            p_tab_dest[(i_dummy+i_offset)*i_step+i_dummy2] = p_tab_src[i_dummy];
+            continue;
         }
-    }
-}
+        else if( (i_code = ShowBits( &p_vpar->bit_stream, 8 )) >= 0x4 )
+        {
+            p_tab = DCT_B14_8 - 4 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                /* Normal coefficient */
+                goto store_coeff;
+            }
 
+            /* Escape code */
+            i_coeff += (GetBits( &p_vpar->bit_stream, 12 ) & 0x3F) - 64;
+            if( i_coeff >= 64 )
+            {
+                /* Illegal, but needed to avoid overflow */
+                intf_WarnMsg( 2, "Intra-B14 coeff is out of bound" );
+                p_vpar->picture.b_error = 1;
+                break;
+            }
 
-/* Fonction that actually fills the table or create the pointers */
-void vpar_InitDCTTables( vpar_thread_t * p_vpar )
-{
-    /* Tables are cut in two parts to reduce memory occupation */
-    p_vpar->pppl_dct_dc_size[0][0] = pl_dct_dc_lum_init_table_1;
-    p_vpar->pppl_dct_dc_size[0][1] = pl_dct_dc_lum_init_table_2;
-    p_vpar->pppl_dct_dc_size[1][0] = pl_dct_dc_chrom_init_table_1;
-    p_vpar->pppl_dct_dc_size[1][1] = pl_dct_dc_chrom_init_table_2;
-
-    /* XXX?? MB_ERROR is replaced by 0 because if we use -1 we
-     * can block in DecodeMPEG2Intra and others */
-    memset( p_vpar->ppl_dct_coef[0], 0, 16 );
-    memset( p_vpar->ppl_dct_coef[1], 0, 16 );
-
-    /* For table B14 & B15, we have a pointer to tables */
-    /* We fill the table thanks to the fonction defined above */
-    FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab0, 256, 60,  4 );
-    FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab1,  64,  8,  8 );
-    FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab2,  16, 16, 16 );
-    FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab3,   8, 16, 16 );
-    FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab4,   4, 16, 16 );
-    FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab5,   2, 16, 16 );
-    FillDCTTable( p_vpar->ppl_dct_coef[0], pl_DCT_tab6,   1, 16, 16 );
-
-    FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab0a, 256, 60, 4 );
-    FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab1a,  64,  8,  8 );
-    FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab2,   16, 16, 16 );
-    FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab3,    8, 16, 16 );
-    FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab4,    4, 16, 16 );
-    FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab5,    2, 16, 16 );
-    FillDCTTable( p_vpar->ppl_dct_coef[1], pl_DCT_tab6,    1, 16, 16 );
-}
+            i_nc++;
+            i_pos = p_scan[i_coeff];
+            i_value = (GetSignedBits( &p_vpar->bit_stream, 12 )
+                        * i_q_scale * pi_quant[i_pos]) / 16;
 
-/*****************************************************************************
- * vpar_InitScanTable : Initialize scan table
- *****************************************************************************/
-void vpar_InitScanTable( vpar_thread_t * p_vpar )
-{
-    int     i;
+            SATURATE( i_value );
+            p_dest[i_pos] = i_value;
+            i_mismatch ^= i_value;
+            continue;
+        }
+        else if( (i_code = ShowBits( &p_vpar->bit_stream, 16)) >= 0x0200 )
+        {
+            p_tab = DCT_B14_10 - 8 + (i_code >> 6);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else if( i_code >= 0x0080 )
+        {
+            p_tab = DCT_13 - 16 + (i_code >> 3);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else if( i_code >= 0x0020 )
+        {
+            p_tab = DCT_15 - 16 + (i_code >> 1);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else
+        {
+            p_tab = DCT_16 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
 
-    memcpy( p_vpar->ppi_scan, pi_scan, sizeof(pi_scan) );
-    p_vpar->pf_norm_scan( p_vpar->ppi_scan );
+        intf_WarnMsg( 2, "Intra-B14 coeff is out of bound" );
+        p_vpar->picture.b_error = 1;
+        break;
+    }
 
-    /* If scan table has changed, we must change the quantization matrices. */
-    for( i = 0; i < 64; i++ )
+    p_dest[63] ^= i_mismatch & 1;
+    RemoveBits( &p_vpar->bit_stream, 2 ); /* End of Block */
+
+    if( i_nc <= 1 )
     {
-        p_vpar->pi_default_intra_quant[ p_vpar->ppi_scan[0][i] ] =
-            pi_default_intra_quant[ pi_scan[0][i] ];
-        p_vpar->pi_default_nonintra_quant[ p_vpar->ppi_scan[0][i] ] =
-            pi_default_nonintra_quant[ pi_scan[0][i] ];
+        if( p_dest[63] )
+        {
+            if( i_nc == 0 )
+            {
+                p_idct->pf_idct = p_vpar->pf_sparse_idct_copy;
+                p_idct->i_sparse_pos = 63;
+            }
+            else
+            {
+                p_idct->pf_idct = p_vpar->pf_idct_copy;
+            }
+        }
+        else 
+        {
+            p_idct->pf_idct = p_vpar->pf_sparse_idct_copy;
+            p_idct->i_sparse_pos = i_coeff - p_tab->i_run;
+        }
+    }
+    else
+    {
+        p_idct->pf_idct = p_vpar->pf_idct_copy;
     }
 }
 
-
-/*
- * Block parsing
- */
-
-#define SATURATE(val)                                                       \
-    if( val > 2047 )                                                        \
-        val = 2047;                                                         \
-    else if( val < -2048 )                                                  \
-        val = -2048;
-
 /*****************************************************************************
- * DecodeMPEG1NonIntra : decode MPEG-1 non-intra blocks
+ * MPEG2IntraB15 : Decode an intra block according to ISO/IEC 13818-2 table B15
  *****************************************************************************/
-static __inline__ void DecodeMPEG1NonIntra( vpar_thread_t * p_vpar,
-                                            macroblock_t * p_mb, int i_b,
-                                            boolean_t b_chroma, int i_cc )
+static void MPEG2IntraB15( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
 {
-    int             i_parse;
-    int             i_nc;
-    int             i_coef;
-    int             i_code;
-    int             i_length;
-    int             i_pos;
-    int             i_run;
-    int             i_level;
-    boolean_t       b_sign;
-    dct_lookup_t *  p_tab;
-
-    /* Decoding of the AC coefficients */
+    int         i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
+    s32         i_sign;
+    dct_lookup_t * p_tab;
 
-    i_nc = 0;
-    i_coef = 0;
-    b_sign = 0;
+    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;
+
+    i_coeff = 0;
+    i_mismatch = ~p_dest[0];
+    i_nc = (p_dest[0] != 0);
 
-    for( i_parse = 0; !p_vpar->p_fifo->b_die; i_parse++ )
+    for( ; ; )
     {
-        i_code = ShowBits( &p_vpar->bit_stream, 16 );
-        if( i_code >= 16384 )
+        if( (i_code = ShowBits( &p_vpar->bit_stream, 8 )) >= 0x4 )
         {
-            p_tab = &ppl_dct_tab2[(i_parse == 0)][(i_code>>12)-4];
-        }
-        else
-        {
-            p_tab = &p_vpar->ppl_dct_coef[0][i_code];
-        }
-        i_run =     p_tab->i_run;
-        i_level =   p_tab->i_level;
-        i_length =  p_tab->i_length;
+            p_tab = DCT_B15_8 - 4 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
 
-        RemoveBits( &p_vpar->bit_stream, i_length );
+store_coeff:
+                i_nc++;
+                i_pos = p_scan[ i_coeff ];
+                RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+                i_value = (p_tab->i_level * i_q_scale * pi_quant[i_pos])
+                                >> 4;
 
-        switch( i_run )
-        {
-            case DCT_ESCAPE:
-                i_run = GetBits( &p_vpar->bit_stream, 6 );
-                i_level = GetBits( &p_vpar->bit_stream, 8 );
-                if (i_level == 0)
-                    i_level = GetBits( &p_vpar->bit_stream, 8 );
-                else if (i_level == 128)
-                    i_level = GetBits( &p_vpar->bit_stream, 8 ) - 256;
-                else if (i_level > 128)
-                    i_level -= 256;
+                i_sign = GetSignedBits( &p_vpar->bit_stream, 1 );
+                /* if (i_sign) i_value = -i_value; */
+                i_value = (i_value ^ i_sign) - i_sign;
 
-                if( (b_sign = i_level < 0) )
-                    i_level = -i_level;
-                
-                break;
-            case DCT_EOB:
-                if( i_nc <= 1 )
+                SATURATE( i_value );
+                p_dest[i_pos] = i_value;
+                i_mismatch ^= i_value;
+
+                continue;
+            }
+            else
+            {
+                if( i_coeff >= 128 )
                 {
-                    p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct;
-                    p_mb->pi_sparse_pos[i_b] = i_coef;
+                    /* End of block */
+                    break;
                 }
-                else
+
+                /* Escape code */
+                i_coeff += (GetBits( &p_vpar->bit_stream, 12 ) & 0x3F) - 64;
+                if( i_coeff >= 64 )
                 {
-                    p_mb->pf_idct[i_b] = p_vpar->pf_idct;
+                    /* Illegal, but needed to avoid overflow */
+                    intf_WarnMsg( 2, "Intra-B15 coeff is out of bound" );
+                    p_vpar->picture.b_error = 1;
+                    break;
                 }
-                return;
 
-                break;
-            default:
-                b_sign = GetBits( &p_vpar->bit_stream, 1 );
-        }
-        i_coef = i_parse;
-        i_parse += i_run;
-        i_nc ++;
+                i_nc++;
+                i_pos = p_scan[i_coeff];
+                i_value = (GetSignedBits( &p_vpar->bit_stream, 12 )
+                            * i_q_scale * pi_quant[i_pos]) / 16;
 
-        if( i_parse >= 64 )
+                SATURATE( i_value );
+                p_dest[i_pos] = i_value;
+                i_mismatch ^= i_value;
+                continue;
+            }
+        }
+        else if( (i_code = ShowBits( &p_vpar->bit_stream, 16)) >= 0x0200 )
         {
-            break;
+            p_tab = DCT_B15_10 - 8 + (i_code >> 6);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else if( i_code >= 0x0080 )
+        {
+            p_tab = DCT_13 - 16 + (i_code >> 3);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else if( i_code >= 0x0020 )
+        {
+            p_tab = DCT_15 - 16 + (i_code >> 1);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else
+        {
+            p_tab = DCT_16 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
         }
 
-        i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse];
-        i_level = ( ((i_level << 1) + 1) * p_vpar->mb.i_quantizer_scale
-                    * p_vpar->sequence.nonintra_quant.pi_matrix[i_pos] ) >> 4;
+        intf_WarnMsg( 2, "Intra-B15 coeff is out of bound" );
+        p_vpar->picture.b_error = 1;
+        break;
+    }
 
-        /* Mismatch control */
-        /* Equivalent to : if( (val & 1) == 0 ) val = val - 1; */
-        i_level = (i_level - 1) | 1;
+    p_dest[63] ^= i_mismatch & 1;
+    RemoveBits( &p_vpar->bit_stream, 4 ); /* End of Block */
 
-        i_level = b_sign ? -i_level : i_level;
-        
-        SATURATE( i_level );
-        
-        p_mb->ppi_blocks[i_b][i_pos] = i_level;
+    if( i_nc <= 1 )
+    {
+        if( p_dest[63] )
+        {
+            if( i_nc == 0 )
+            {
+                p_idct->pf_idct = p_vpar->pf_sparse_idct_copy;
+                p_idct->i_sparse_pos = 63;
+            }
+            else
+            {
+                p_idct->pf_idct = p_vpar->pf_idct_copy;
+            }
+        }
+        else 
+        {
+            p_idct->pf_idct = p_vpar->pf_sparse_idct_copy;
+            p_idct->i_sparse_pos = i_coeff - p_tab->i_run;
+        }
+    }
+    else
+    {
+        p_idct->pf_idct = p_vpar->pf_idct_copy;
     }
-
-    intf_WarnMsg( 2, "DCT coeff (non-intra) is out of bounds" );
-    p_vpar->picture.b_error = 1;
 }
 
 /*****************************************************************************
- * DecodeMPEG1Intra : decode MPEG-1 intra blocks
+ * MPEG2NonIntra : Decode a non-intra MPEG-2 block
  *****************************************************************************/
-static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar,
-                                         macroblock_t * p_mb, int i_b,
-                                         boolean_t b_chroma, int i_cc )
+static void MPEG2NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
 {
-    int             i_parse;
-    int             i_nc;
-    int             i_coef;
-    int             i_code;
-    int             i_length;
-    int             i_pos;
-    int             i_dct_dc_size;
-    int             i_dct_dc_diff;
-    int             i_run;
-    int             i_level;
-    boolean_t       b_sign;
-    dct_lookup_t *  p_tab;
-    lookup_t *      p_lookup;
-    u8 *            pi_quant = p_vpar->sequence.intra_quant.pi_matrix;
-
-    /* decode length */
-    i_code = ShowBits(&p_vpar->bit_stream, 5);
-
-    if (i_code<31)
+    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;
+    i_nc = 0;
+
+    if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) >= 0x5 )
     {
-        p_lookup = &ppl_dct_dc_init_table_1[b_chroma][i_code];
+        p_tab = DCT_B14DC_5 - 5 + i_code;
+        goto coeff_1;
     }
     else
     {
-        i_code = ShowBits(&p_vpar->bit_stream, (9+b_chroma)) - (0x1f0 * (b_chroma + 1));
-        p_lookup = &ppl_dct_dc_init_table_2[b_chroma][i_code];
+        goto coeff_2;
     }
-    i_dct_dc_size = p_lookup->i_value;
-    i_length = p_lookup->i_length;
-    RemoveBits( &p_vpar->bit_stream, i_length );
 
-    if (i_dct_dc_size == 0)
-        i_dct_dc_diff = 0;
-    else
+    for( ; ; )
     {
-        i_dct_dc_diff = GetBits( &p_vpar->bit_stream, i_dct_dc_size);
-        if ((i_dct_dc_diff & (1<<(i_dct_dc_size-1))) == 0)
-            i_dct_dc_diff -= (1<<i_dct_dc_size) - 1;
-    }
+        if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) >= 0x5 )
+        {
+            p_tab = DCT_B14AC_5 - 5 + i_code;
+coeff_1:
+            i_coeff += p_tab->i_run;
+            if( i_coeff >= 64 )
+            {
+                /* End of block */
+                break;
+            }
 
-    /* Read the actual code with the good length */
-    p_vpar->mb.pi_dc_dct_pred[i_cc] += i_dct_dc_diff;
+store_coeff:
+            i_nc++;
+            i_pos = p_scan[ i_coeff ];
+            RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+            i_value = ((2 * p_tab->i_level + 1) * i_q_scale * pi_quant[i_pos])
+                            >> 5;
 
-    p_mb->ppi_blocks[i_b][0] = p_vpar->mb.pi_dc_dct_pred[i_cc] << 3;
+            i_sign = GetSignedBits( &p_vpar->bit_stream, 1 );
+            /* if (i_sign) i_value = -i_value; */
+            i_value = (i_value ^ i_sign) - i_sign;
 
-    i_nc = ( p_vpar->mb.pi_dc_dct_pred[i_cc] != 0 );
+            SATURATE( i_value );
+            p_dest[i_pos] = i_value;
+            i_mismatch ^= i_value;
 
-    if( p_vpar->picture.i_coding_type == D_CODING_TYPE )
-    {
-        /* Remove end_of_macroblock (always 1, prevents startcode emulation)
-         * ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */
-        RemoveBits( &p_vpar->bit_stream, 1 );
-        /* D pictures do not have AC coefficients */
-        return;
-    }
+            continue;
+        }
+coeff_2:
+        if( (i_code = ShowBits( &p_vpar->bit_stream, 8 )) >= 0x4 )
+        {
+            p_tab = DCT_B14_8 - 4 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                /* Normal coefficient */
+                goto store_coeff;
+            }
 
-    
-    /* Decoding of the AC coefficients */
-    i_coef = 0;
-    b_sign = 0;
+            /* Escape code */
+            i_coeff += (GetBits( &p_vpar->bit_stream, 12 ) & 0x3F) - 64;
+            if( i_coeff >= 64 )
+            {
+                /* Illegal, but needed to avoid overflow */
+                intf_WarnMsg( 2, "MPEG2NonIntra coeff is out of bound" );
+                p_vpar->picture.b_error = 1;
+                break;
+            }
 
-    for( i_parse = 1; !p_vpar->p_fifo->b_die; i_parse++ )
-    {
-        i_code = ShowBits( &p_vpar->bit_stream, 16 );
-        /* We use 2 main tables for the coefficients */
-        if( i_code >= 16384 )
+            i_nc++;
+            i_pos = p_scan[i_coeff];
+            i_value = 2 * (ShowSignedBits( &p_vpar->bit_stream, 1 )
+                            + GetSignedBits( &p_vpar->bit_stream, 12 )) + 1;
+
+            i_value = (i_value * i_q_scale * pi_quant[i_pos]) / 32;
+
+            SATURATE( i_value );
+            p_dest[i_pos] = i_value;
+            i_mismatch ^= i_value;
+            continue;
+        }
+        else if( (i_code = ShowBits( &p_vpar->bit_stream, 16)) >= 0x0200 )
         {
-            p_tab = &ppl_dct_tab1[0][(i_code>>12)-4];
+            p_tab = DCT_B14_10 - 8 + (i_code >> 6);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
         }
-        else
+        else if( i_code >= 0x0080 )
         {
-            p_tab = &p_vpar->ppl_dct_coef[0][i_code];
+            p_tab = DCT_13 - 16 + (i_code >> 3);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
         }
-        i_run =     p_tab->i_run;
-        i_length =  p_tab->i_length;
-        i_level =   p_tab->i_level;
-
-        RemoveBits( &p_vpar->bit_stream, i_length );
-
-        switch( i_run )
+        else if( i_code >= 0x0020 )
         {
-            case DCT_ESCAPE:
-                i_run = GetBits( &p_vpar->bit_stream, 6 );
-                i_level = GetBits( &p_vpar->bit_stream, 8 );
-                if (i_level == 0)
-                    i_level = GetBits( &p_vpar->bit_stream, 8 );
-                else if (i_level == 128)
-                    i_level = GetBits( &p_vpar->bit_stream, 8 ) - 256;
-                else if (i_level > 128)
-                    i_level -= 256;
-                if( (b_sign = i_level < 0) )
-                    i_level = -i_level;
-                break;
-            case DCT_EOB:
-                if( i_nc <= 1 )
-                {
-                    p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct;
-                    p_mb->pi_sparse_pos[i_b] = i_coef;
-                }
-                else
-                {
-                    p_mb->pf_idct[i_b] = p_vpar->pf_idct;
-                }
-                return;
-
-                break;
-            default:
-                b_sign = GetBits( &p_vpar->bit_stream, 1 );
+            p_tab = DCT_15 - 16 + (i_code >> 1);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
         }
-        
-        /* Prepare the next block */
-        i_coef = i_parse;
-        i_parse += i_run;
-        i_nc ++;
-
-        if( i_parse >= 64 )
+        else
         {
-            /* We have an error in the stream */
-            break;
+            p_tab = DCT_16 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
         }
 
-        /* Determine the position of the block in the frame */
-        i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse];
-        i_level = ( i_level *
-                    p_vpar->mb.i_quantizer_scale * pi_quant[i_pos] ) >> 3;
-
-        /* Mismatch control */
-        /* Equivalent to : if( (val & 1) == 0 ) val = val - 1; */
-        i_level = (i_level - 1) | 1;
-
-        i_level = b_sign ? -i_level : i_level;
-        
-        SATURATE( i_level );
-        
-        p_mb->ppi_blocks[i_b][i_pos] = i_level;
+        intf_WarnMsg( 2, "MPEG2NonIntra coeff is out of bound" );
+        p_vpar->picture.b_error = 1;
+        break;
     }
 
-    intf_WarnMsg( 2, "DCT coeff (intra) is out of bounds" );
-    p_vpar->picture.b_error = 1;
-}
+    p_dest[63] ^= i_mismatch & 1;
+    RemoveBits( &p_vpar->bit_stream, 2 ); /* End of Block */
 
-/*****************************************************************************
- * DecodeMPEG2NonIntra : decode MPEG-2 non-intra blocks
- *****************************************************************************/
-static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar,
-                                            macroblock_t * p_mb, int i_b,
-                                            boolean_t b_chroma, int i_cc )
-{
-    int             i_parse;
-    int             i_nc;
-    int             i_coef;
-    int             i_code;
-    int             i_length;
-    int             i_pos;
-    int             i_run;
-    int             i_level;
-    int             i_mismatch = 1;
-    boolean_t       b_sign;
-    u8 *            pi_quant;
-    dct_lookup_t *  p_tab;
-    /* FIXME : if you want to enable other types of chroma, replace this
-     * by p_vpar->sequence.i_chroma_format. */
-    int             i_chroma_format = CHROMA_420;
-
-    /* Give a pointer to the quantization matrices for intra blocks */
-    if( (i_chroma_format == CHROMA_420) || (!b_chroma) )
+    if( i_nc <= 1 )
     {
-        pi_quant = p_vpar->sequence.nonintra_quant.pi_matrix;
+        if( p_dest[63] )
+        {
+            if( i_nc == 0 )
+            {
+                p_idct->pf_idct = p_vpar->pf_sparse_idct_add;
+                p_idct->i_sparse_pos = 63;
+            }
+            else
+            {
+                p_idct->pf_idct = p_vpar->pf_idct_add;
+            }
+        }
+        else 
+        {
+            p_idct->pf_idct = p_vpar->pf_sparse_idct_add;
+            if( i_nc == 0 )
+            {
+                p_idct->i_sparse_pos = 0;
+            }
+            else
+            {
+                p_idct->i_sparse_pos = i_coeff - p_tab->i_run;
+            }
+        }
     }
     else
     {
-        pi_quant = p_vpar->sequence.chroma_nonintra_quant.pi_matrix;
+        p_idct->pf_idct = p_vpar->pf_idct_add;
     }
+}
+
+/*****************************************************************************
+ * MPEG1Intra : Decode an MPEG-1 intra block
+ *****************************************************************************/
+static void MPEG1Intra( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
+{
+    int         i_coeff, i_code, i_pos, i_value, i_nc;
+    s32         i_sign;
+    dct_lookup_t * p_tab;
 
-    /* Decoding of the AC coefficients */
+    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;
 
-    i_nc = 0;
-    i_coef = 0;
-    for( i_parse = 0; !p_vpar->p_fifo->b_die; i_parse++ )
+    i_coeff = 0;
+    i_nc = (p_dest[0] != 0);
+
+    for( ; ; )
     {
-        i_code = ShowBits( &p_vpar->bit_stream, 16 );
-        if( i_code >= 16384 )
-        {
-            p_tab = &ppl_dct_tab2[(i_parse == 0)][(i_code>>12)-4];
-        }
-        else
+        if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) >= 0x5 )
         {
-            p_tab = &p_vpar->ppl_dct_coef[0][i_code];
-        }
-        i_run =     p_tab->i_run;
-        i_level =   p_tab->i_level;
-        i_length =  p_tab->i_length;
+            p_tab = DCT_B14AC_5 - 5 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff >= 64 )
+            {
+                /* End of block */
+                break;
+            }
 
-        RemoveBits( &p_vpar->bit_stream, i_length );
+store_coeff:
+            i_nc++;
+            i_pos = p_scan[ i_coeff ];
+            RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+            i_value = (p_tab->i_level * i_q_scale * pi_quant[i_pos])
+                            >> 4;
 
-        switch( i_run )
+            /* Oddification */
+            i_value = (i_value - 1) | 1;
+
+            i_sign = GetSignedBits( &p_vpar->bit_stream, 1 );
+            /* if (i_sign) i_value = -i_value; */
+            i_value = (i_value ^ i_sign) - i_sign;
+
+            SATURATE( i_value );
+            p_dest[i_pos] = i_value;
+
+            continue;
+        }
+        else if( (i_code = ShowBits( &p_vpar->bit_stream, 8 )) >= 0x4 )
         {
-            case DCT_ESCAPE:
-                i_run = GetBits( &p_vpar->bit_stream, 6 );
-                i_level = GetBits( &p_vpar->bit_stream, 12 );
-                i_level = (b_sign = ( i_level > 2047 )) ? 4096 - i_level
-                                                        : i_level;
-                break;
-            case DCT_EOB:
-                if( i_nc <= 1 )
-                {
-                    p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct;
-                    p_mb->pi_sparse_pos[i_b] = i_coef;
-                }
-                else
-                {
-                    p_mb->pf_idct[i_b] = p_vpar->pf_idct;
-                }
-                
-                /* Mismatch control */
-                p_mb->ppi_blocks[i_b][63] ^= i_mismatch & 1;
-                return;
+            p_tab = DCT_B14_8 - 4 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                /* Normal coefficient */
+                goto store_coeff;
+            }
 
+            /* Escape code */
+            i_coeff += (GetBits( &p_vpar->bit_stream, 12 ) & 0x3F) - 64;
+            if( i_coeff >= 64 )
+            {
+                /* Illegal, but needed to avoid overflow */
+                intf_WarnMsg( 2, "MPEG1Intra coeff is out of bound" );
+                p_vpar->picture.b_error = 1;
                 break;
-            default:
-                b_sign = GetBits( &p_vpar->bit_stream, 1 );
-        }
-        i_coef = i_parse;
-        i_parse += i_run;
-        i_nc ++;
+            }
+
+            i_nc++;
+            i_pos = p_scan[i_coeff];
+            
+            i_value = ShowSignedBits( &p_vpar->bit_stream, 8 );
+            if( !(i_value & 0x7F) )
+            {
+                RemoveBits( &p_vpar->bit_stream, 8 );
+                i_value = ShowBits( &p_vpar->bit_stream, 8 ) + 2 * i_value;
+            }
+
+            i_value = (i_value * i_q_scale * pi_quant[i_pos]) / 16;
+
+            /* Oddification */
+            i_value = (i_value + ~ShowSignedBits( &p_vpar->bit_stream, 1 )) | 1;
 
-        if( i_parse >= 64 )
+            SATURATE( i_value );
+            p_dest[i_pos] = i_value;
+            RemoveBits( &p_vpar->bit_stream, 8 );
+            continue;
+        }
+        else if( (i_code = ShowBits( &p_vpar->bit_stream, 16)) >= 0x0200 )
         {
-            break;
+            p_tab = DCT_B14_10 - 8 + (i_code >> 6);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else if( i_code >= 0x0080 )
+        {
+            p_tab = DCT_13 - 16 + (i_code >> 3);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else if( i_code >= 0x0020 )
+        {
+            p_tab = DCT_15 - 16 + (i_code >> 1);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else
+        {
+            p_tab = DCT_16 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
         }
 
-        i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse];
-        i_level = ( ((i_level << 1) + 1) * p_vpar->mb.i_quantizer_scale
-                    * pi_quant[i_pos] ) >> 5;
-
-        /* Could be replaced by (i_level ^ sign) - sign */
-        i_level = b_sign ? -i_level : i_level;
-        
-        SATURATE( i_level );
-        
-        p_mb->ppi_blocks[i_b][i_pos] = i_level;
-        
-        /* Mismatch control */
-        i_mismatch ^= i_level;
+        intf_WarnMsg( 2, "MPEG1Intra coeff is out of bound" );
+        p_vpar->picture.b_error = 1;
+        break;
     }
 
-    intf_WarnMsg( 2, "DCT coeff (non-intra) is out of bounds" );
-    p_vpar->picture.b_error = 1;
-}
+    RemoveBits( &p_vpar->bit_stream, 2 ); /* End of Block */
 
-/*****************************************************************************
- * DecodeMPEG2Intra : decode MPEG-2 intra blocks
- *****************************************************************************/
-static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar,
-                                         macroblock_t * p_mb, int i_b,
-                                         boolean_t b_chroma, int i_cc )
-{
-    int             i_parse;
-    int             i_nc;
-    int             i_coef;
-    int             i_code;
-    int             i_length;
-    int             i_pos;
-    int             i_dct_dc_size;
-    int             i_dct_dc_diff;
-    int             i_run;
-    int             i_level;
-    int             i_mismatch = 1;
-    boolean_t       b_vlc_intra;
-    boolean_t       b_sign;
-    u8 *            pi_quant;
-    dct_lookup_t *  p_tab;
-    lookup_t *      p_lookup;
-    /* FIXME : if you want to enable other types of chroma, replace this
-     * by p_vpar->sequence.i_chroma_format. */
-    int             i_chroma_format = CHROMA_420;
-
-    /* Give a pointer to the quantization matrices for intra blocks */
-    if( (i_chroma_format == CHROMA_420) || (!b_chroma) )
+    if( i_nc <= 1 )
     {
-        pi_quant = p_vpar->sequence.intra_quant.pi_matrix;
+        p_idct->pf_idct = p_vpar->pf_sparse_idct_copy;
+        p_idct->i_sparse_pos = i_coeff - p_tab->i_run;
     }
     else
     {
-        pi_quant = p_vpar->sequence.chroma_intra_quant.pi_matrix;
+        p_idct->pf_idct = p_vpar->pf_idct_copy;
     }
+}
+
+/*****************************************************************************
+ * MPEG1NonIntra : Decode a non-intra MPEG-1 block
+ *****************************************************************************/
+static void MPEG1NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
+{
+    int         i_coeff, i_code, i_pos, i_value, i_nc;
+    s32         i_sign;
+    dct_lookup_t * p_tab;
 
-    /* decode length */
-    i_code = ShowBits( &p_vpar->bit_stream, 5 );
+    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;
 
-    if (i_code < 31)
+    i_coeff = -1;
+    i_nc = 0;
+
+    if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) >= 0x5 )
     {
-        p_lookup = &ppl_dct_dc_init_table_1[b_chroma][i_code];
+        p_tab = DCT_B14DC_5 - 5 + i_code;
+        goto coeff_1;
     }
     else
     {
-        i_code = ShowBits(&p_vpar->bit_stream, (9+b_chroma)) - (0x1f0 * (b_chroma + 1));
-        p_lookup = &ppl_dct_dc_init_table_2[b_chroma][i_code];
+        goto coeff_2;
     }
-    i_dct_dc_size = p_lookup->i_value;
-    i_length = p_lookup->i_length;
-    RemoveBits( &p_vpar->bit_stream, i_length );
 
-    if (i_dct_dc_size == 0)
-        i_dct_dc_diff = 0;
-    else
+    for( ; ; )
     {
-        i_dct_dc_diff = GetBits( &p_vpar->bit_stream, i_dct_dc_size);
-        if ((i_dct_dc_diff & (1<<(i_dct_dc_size-1))) == 0)
-            i_dct_dc_diff -= (1<<i_dct_dc_size) - 1;
-    }
+        if( (i_code = ShowBits( &p_vpar->bit_stream, 5 )) >= 0x5 )
+        {
+            p_tab = DCT_B14AC_5 - 5 + i_code;
+coeff_1:
+            i_coeff += p_tab->i_run;
+            if( i_coeff >= 64 )
+            {
+                /* End of block */
+                break;
+            }
 
-    /* Read the actual code with the good length */
-    p_vpar->mb.pi_dc_dct_pred[i_cc] += i_dct_dc_diff;
+store_coeff:
+            i_nc++;
+            i_pos = p_scan[ i_coeff ];
+            RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+            i_value = ((2 * p_tab->i_level + 1) * i_q_scale * pi_quant[i_pos])
+                            >> 5;
 
-    p_mb->ppi_blocks[i_b][0] = ( p_vpar->mb.pi_dc_dct_pred[i_cc] <<
-                               ( 3 - p_vpar->picture.i_intra_dc_precision ) );
+            /* Oddification */
+            i_value = (i_value - 1) | 1;
 
-    i_nc = ( p_vpar->mb.pi_dc_dct_pred[i_cc] != 0 );
+            i_sign = GetSignedBits( &p_vpar->bit_stream, 1 );
+            /* if (i_sign) i_value = -i_value; */
+            i_value = (i_value ^ i_sign) - i_sign;
 
-    /* Decoding of the AC coefficients */
+            SATURATE( i_value );
+            p_dest[i_pos] = i_value;
 
-    i_coef = 0;
-    b_vlc_intra = p_vpar->picture.b_intra_vlc_format;
-    for( i_parse = 1; !p_vpar->p_fifo->b_die; i_parse++ )
-    {
-        i_code = ShowBits( &p_vpar->bit_stream, 16 );
-        /* We use 2 main tables for the coefficients */
-        if( i_code >= 16384 )
+            continue;
+        }
+coeff_2:
+        if( (i_code = ShowBits( &p_vpar->bit_stream, 8 )) >= 0x4 )
         {
-            p_tab = &ppl_dct_tab1[b_vlc_intra][(i_code>>(12-(4*b_vlc_intra)))-4];
+            p_tab = DCT_B14_8 - 4 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                /* Normal coefficient */
+                goto store_coeff;
+            }
+
+            /* Escape code */
+            i_coeff += (GetBits( &p_vpar->bit_stream, 12 ) & 0x3F) - 64;
+            if( i_coeff >= 64 )
+            {
+                /* Illegal, but needed to avoid overflow */
+                intf_WarnMsg( 2, "MPEG1NonIntra coeff is out of bound" );
+                p_vpar->picture.b_error = 1;
+                break;
+            }
+
+            i_nc++;
+            i_pos = p_scan[i_coeff];
+            i_value = ShowSignedBits( &p_vpar->bit_stream, 8 );
+            if( !(i_value & 0x7F) )
+            {
+                RemoveBits( &p_vpar->bit_stream, 8 );
+                i_value = ShowBits( &p_vpar->bit_stream, 8 ) + 2 * i_value;
+            }
+            i_sign = ShowSignedBits( &p_vpar->bit_stream, 1 );
+            i_value = 2 * (i_sign + i_value) + 1;
+            i_value = (i_value * i_q_scale * pi_quant[i_pos]) / 32;
+
+            /* Oddification */
+            i_value = (i_value + ~i_sign) | 1;
+
+            SATURATE( i_value );
+            p_dest[i_pos] = i_value;
+            RemoveBits( &p_vpar->bit_stream, 8 );
+            continue;
+        }
+        else if( (i_code = ShowBits( &p_vpar->bit_stream, 16)) >= 0x0200 )
+        {
+            p_tab = DCT_B14_10 - 8 + (i_code >> 6);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else if( i_code >= 0x0080 )
+        {
+            p_tab = DCT_13 - 16 + (i_code >> 3);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
+        }
+        else if( i_code >= 0x0020 )
+        {
+            p_tab = DCT_15 - 16 + (i_code >> 1);
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
         }
         else
         {
-            p_tab = &p_vpar->ppl_dct_coef[b_vlc_intra][i_code];
+            p_tab = DCT_16 + i_code;
+            i_coeff += p_tab->i_run;
+            if( i_coeff < 64 )
+            {
+                goto store_coeff;
+            }
         }
-        i_run =     p_tab->i_run;
-        i_level =   p_tab->i_level;
-        i_length =  p_tab->i_length;
 
-        RemoveBits( &p_vpar->bit_stream, i_length );
+        intf_WarnMsg( 2, "MPEG1NonIntra coeff is out of bound" );
+        p_vpar->picture.b_error = 1;
+        break;
+    }
+
+    RemoveBits( &p_vpar->bit_stream, 2 ); /* End of Block */
 
-        switch( i_run )
+    if( i_nc <= 1 )
+    {
+        p_idct->pf_idct = p_vpar->pf_sparse_idct_add;
+        if( i_nc == 0 )
         {
-            case DCT_ESCAPE:
-                i_run = GetBits( &p_vpar->bit_stream, 6 );
-                i_level = GetBits( &p_vpar->bit_stream, 12 );
-                i_level = (b_sign = ( i_level > 2047 )) ? 4096 - i_level
-                                                        : i_level;
-                break;
-            case DCT_EOB:
-                if( i_nc <= 1 )
-                {
-                    p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct;
-                    p_mb->pi_sparse_pos[i_b] = i_coef;
-                }
-                else
-                {
-                    p_mb->pf_idct[i_b] = p_vpar->pf_idct;
-                }
-                
-                /* Mismatch control */
-                p_mb->ppi_blocks[i_b][63] ^= i_mismatch & 1;
-                return;
-
-                break;
-            default:
-                b_sign = GetBits( &p_vpar->bit_stream, 1 );
+            p_idct->i_sparse_pos = 0;
         }
-        
-        /* Prepare the next block */
-        i_coef = i_parse;
-        i_parse += i_run;
-        i_nc ++;
-
-        if( i_parse >= 64 )
+        else
         {
-            /* We have an error in the stream */
-            break;
+            p_idct->i_sparse_pos = i_coeff - p_tab->i_run;
         }
-
-        /* Determine the position of the block in the frame */
-        i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse];
-        i_level = ( i_level *
-                    p_vpar->mb.i_quantizer_scale *
-                    pi_quant[i_pos] ) >> 4;
-
-        i_level = b_sign ? -i_level : i_level;
-        
-        SATURATE( i_level );
-        
-        p_mb->ppi_blocks[i_b][i_pos] = i_level;
-        
-        /* Mismatch control */
-        i_mismatch ^= i_level;
     }
-
-    intf_WarnMsg( 2, "DCT coeff (intra) is out of bounds" );
-    p_vpar->picture.b_error = 1;
+    else
+    {
+        p_idct->pf_idct = p_vpar->pf_idct_add;
+    }
 }
 
+#undef SATURATE
+
 /*****************************************************************************
- * Decode*Blocks : decode blocks
+ * *MB : decode all blocks of the macroblock
  *****************************************************************************/
-static int      pi_x[12] = {0,8,0,8,0,0,0,0,8,8,8,8};
-static int      pi_y[2][12] = { {0,0,8,8,0,0,8,8,0,0,8,8},
-                                {0,0,1,1,0,0,1,1,0,0,1,1} };
-#define PARSEERROR                                                      \
-if( p_vpar->picture.b_error )                                           \
-{                                                                       \
-    return;                                                             \
+#define DECODE_LUMABLOCK( i_b, p_dest, 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 );
+
+#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;                                                 \
+                                                                            \
+    p_lum_dest = p_mb->pp_dest[0] + p_vpar->mb.i_offset;                    \
+                                                                            \
+    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                                                                    \
+    {                                                                       \
+        i_dct_offset = p_vpar->picture.i_field_width * 8;                   \
+        p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width;             \
+    }                                                                       \
+    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 );                                            \
 }
 
-#define DECODEBLOCKS( MBFUNC, BLOCKFUNC )                               \
-static void MBFUNC( vpar_thread_t * p_vpar, macroblock_t * p_mb )       \
-{                                                                       \
-    /* FIXME : if you want to enable other types of chroma, replace this\
-     * by p_vpar->sequence.i_chroma_format. */                          \
-    int         i_chroma_format = CHROMA_420;                           \
-    int         i_mask, i_b;                                            \
-    yuv_data_t *    p_data1;                                            \
-    yuv_data_t *    p_data2;                                            \
-                                                                        \
-    i_mask = 1 << (3 + (1 << i_chroma_format));                         \
-                                                                        \
-    /* luminance */                                                     \
-    p_data1 = p_mb->p_picture->p_y                                      \
-        + p_mb->i_l_x + p_vpar->mb.i_l_y * (p_vpar->sequence.i_width);  \
-                                                                        \
-    for( i_b = 0 ; i_b < 4 ; i_b++, i_mask >>= 1 )                      \
-    {                                                                   \
-        if( p_mb->i_coded_block_pattern & i_mask )                      \
-        {                                                               \
-            memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) );   \
-            BLOCKFUNC( p_vpar, p_mb, i_b, 0, 0 );                       \
-                                                                        \
-            /* Calculate block coordinates. */                          \
-            p_mb->p_data[i_b] = p_data1                                 \
-                                + pi_y[p_vpar->mb.b_dct_type][i_b]      \
-                                * p_vpar->picture.i_l_stride            \
-                                + pi_x[i_b];                            \
-                                                                        \
-            PARSEERROR                                                  \
-        }                                                               \
-    }                                                                   \
-                                                                        \
-    /* chrominance */                                                   \
-    p_data1 = p_mb->p_picture->p_u                                      \
-              + p_mb->i_c_x                                             \
-              + p_vpar->mb.i_c_y                                        \
-                * (p_vpar->sequence.i_chroma_width);                    \
-    p_data2 = p_mb->p_picture->p_v                                      \
-               + p_mb->i_c_x                                            \
-               + p_vpar->mb.i_c_y                                       \
-                * (p_vpar->sequence.i_chroma_width);                    \
-                                                                        \
-    for( i_b = 4; i_b < 4 + (1 << i_chroma_format);                     \
-         i_b++, i_mask >>= 1 )                                          \
-    {                                                                   \
-        yuv_data_t *    pp_data[2] = {p_data1, p_data2};                \
-                                                                        \
-        if( p_mb->i_coded_block_pattern & i_mask )                      \
-        {                                                               \
-            memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) );   \
-            BLOCKFUNC( p_vpar, p_mb, i_b, 1, 1 + ((i_b - 4) & 1) );     \
-                                                                        \
-            /* Calculate block coordinates. */                          \
-            p_mb->p_data[i_b] = pp_data[i_b & 1]                        \
-                                 + pi_y[p_vpar->mb.b_dct_type][i_b]     \
-                                   * p_vpar->picture.i_c_stride         \
-                                 + pi_x[i_b];                           \
-                                                                        \
-            PARSEERROR                                                  \
-        }                                                               \
-    }                                                                   \
+DECLARE_INTRAMB( MPEG1IntraMB, MPEG1Intra );
+DECLARE_INTRAMB( MPEG2IntraB14MB, MPEG2IntraB14 );
+DECLARE_INTRAMB( MPEG2IntraB15MB, MPEG2IntraB15 );
+
+#undef DECLARE_INTRAMB
+#undef DECODE_LUMABLOCK
+
+#define DECODE_BLOCK( i_b, p_dest, PF_MBFUNC )                              \
+    if( p_mb->i_coded_block_pattern & (1 << (5 - 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 );                                        \
+    }
+
+#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;                                                 \
+                                                                            \
+    p_lum_dest = p_mb->pp_dest[0] + p_vpar->mb.i_offset;                    \
+                                                                            \
+    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                                                                    \
+    {                                                                       \
+        i_dct_offset = p_vpar->picture.i_field_width * 8;                   \
+        p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width;             \
+    }                                                                       \
+    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 );                                              \
 }
 
-DECODEBLOCKS( DecodeMPEG1NonIntraMB, DecodeMPEG1NonIntra );
-DECODEBLOCKS( DecodeMPEG1IntraMB, DecodeMPEG1Intra );
-DECODEBLOCKS( DecodeMPEG2NonIntraMB, DecodeMPEG2NonIntra );
-DECODEBLOCKS( DecodeMPEG2IntraMB, DecodeMPEG2Intra );
+DECLARE_NONINTRAMB( MPEG1NonIntraMB, MPEG1NonIntra );
+DECLARE_NONINTRAMB( MPEG2NonIntraMB, MPEG2NonIntra );
 
-#undef PARSEERROR
+#undef DECLARE_NONINTRAMB
+#undef DECODE_BLOCK
 
 
 /*
@@ -1215,844 +1064,1067 @@ DECODEBLOCKS( DecodeMPEG2IntraMB, DecodeMPEG2Intra );
  */
 
 /****************************************************************************
- * MotionCode : Parse the next motion code
+ * MotionDelta : Parse the next motion delta
  ****************************************************************************/
-static __inline__ int MotionCode( vpar_thread_t * p_vpar )
+static __inline__ int MotionDelta( vpar_thread_t * p_vpar, int i_f_code )
 {
-    int i_code;
-    static lookup_t pl_mv_tab0[8] =
-        { {-1,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1} };
-    /* Table B-10, motion_code, codes 0000011 ... 000011x */
-    static lookup_t pl_mv_tab1[8] =
-        { {-1,0}, {-1,0}, {-1,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5} };
-    /* Table B-10, motion_code, codes 0000001100 ... 000001011x */
-    static lookup_t pl_mv_tab2[12] = {
-        {16,9}, {15,9}, {14,9}, {13,9},
-        {12,9}, {11,9}, {10,8}, {10,8},
-        {9,8},  {9,8},  {8,8},  {8,8} };
+    int         i_delta, i_sign, i_code;
+    lookup_t *  p_tab;
 
-    if( GetBits( &p_vpar->bit_stream, 1 ) )
+    if( ShowBits( &p_vpar->bit_stream, 1 ) )
     {
+        RemoveBits( &p_vpar->bit_stream, 1 );
         return 0;
     }
-    if( (i_code = ShowBits( &p_vpar->bit_stream, 9) ) >= 64 )
-    {
-        i_code >>= 6;
-        RemoveBits( &p_vpar->bit_stream, pl_mv_tab0[i_code].i_length );
-        return( GetBits( &p_vpar->bit_stream, 1 ) ?
-            -pl_mv_tab0[i_code].i_value : pl_mv_tab0[i_code].i_value );
-    }
 
-    if( i_code >= 24 )
+    if( (i_code = ShowBits( &p_vpar->bit_stream, 6 )) >= 0x3 )
     {
-        i_code >>= 3;
-        RemoveBits( &p_vpar->bit_stream, pl_mv_tab1[i_code].i_length );
-        return( GetBits( &p_vpar->bit_stream, 1 ) ?
-            -pl_mv_tab1[i_code].i_value : pl_mv_tab1[i_code].i_value );
-    }
+        p_tab = MV_4 + (i_code >> 2);
+        i_delta = (p_tab->i_value << i_f_code) + 1;
+        RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+
+        i_sign = GetSignedBits( &p_vpar->bit_stream, 1 );
+        if( i_f_code )
+        {
+            i_delta += GetBits( &p_vpar->bit_stream, i_f_code );
+        }
+
+        return (i_delta ^ i_sign) - i_sign;
 
-    if( (i_code -= 12) < 0 )
-    {
-        p_vpar->picture.b_error = 1;
-        intf_WarnMsg( 2, "Invalid motion_vector code" );
-        return 0;
     }
+    else
+    {
+        p_tab = MV_10 + ShowBits( &p_vpar->bit_stream, 10 );
+        i_delta = (p_tab->i_value << i_f_code) + 1;
+        RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+
+        i_sign = GetSignedBits( &p_vpar->bit_stream, 1 );
+        if( i_f_code )
+        {
+            i_delta += GetBits( &p_vpar->bit_stream, i_f_code );
+        }
 
-    RemoveBits( &p_vpar->bit_stream, pl_mv_tab2[i_code].i_length );
-    return( GetBits( &p_vpar->bit_stream, 1 ) ?
-        -pl_mv_tab2[i_code].i_value : pl_mv_tab2[i_code].i_value );
+        return (i_delta ^ i_sign) - i_sign;
+    }
 }
 
 /****************************************************************************
- * DecodeMotionVector : Decode a motion_vector
+ * BoundMotionVector : Bound a motion_vector :-)
  ****************************************************************************/
-static __inline__ void DecodeMotionVector( int * pi_prediction, int i_r_size,
-        int i_motion_code, int i_motion_residual, int i_full_pel )
+static __inline__ int BoundMotionVector( int i_vector, int i_f_code )
 {
-    int i_limit, i_vector;
+    int i_limit;
 
-    /* ISO/IEC 13818-1 section 7.6.3.1 */
-    i_limit = 16 << i_r_size;
-    i_vector = *pi_prediction >> i_full_pel;
+    i_limit = 16 << i_f_code;
 
-    if( i_motion_code > 0 )
+    if( i_vector >= i_limit )
+    {
+        return i_vector - 2 * i_limit;
+    }
+    else if( i_vector < -i_limit)
     {
-        i_vector += ((i_motion_code-1) << i_r_size) + i_motion_residual + 1;
-        if( i_vector >= i_limit )
-            i_vector -= i_limit + i_limit;
+        return i_vector + 2 * i_limit;
     }
-    else if( i_motion_code < 0 )
+    else
     {
-        i_vector -= ((-i_motion_code-1) << i_r_size) + i_motion_residual + 1;
-        if( i_vector < -i_limit )
-            i_vector += i_limit + i_limit;
+        return i_vector;
     }
-    *pi_prediction = i_vector << i_full_pel;
 }
 
 /****************************************************************************
- * MotionVector : Parse the next motion_vector field
+ * GetDMV : Decode a differential motion vector (Dual Prime Arithmetic)
  ****************************************************************************/
-static __inline__ void MotionVector( vpar_thread_t * p_vpar,
-                                     macroblock_t * p_mb, int i_r,
-                                     int i_s, int i_full_pel, int i_structure,
-                                     int i_h_r_size, int i_v_r_size )
+static __inline__ int GetDMV( vpar_thread_t * p_vpar )
 {
-    int i_motion_code, i_motion_residual;
-    int pi_dm_vector[2];
+    dmv_lookup_t * p_tab;
 
-    i_motion_code = MotionCode( p_vpar );
-    i_motion_residual = (i_h_r_size != 0 && i_motion_code != 0) ?
-                        GetBits( &p_vpar->bit_stream, i_h_r_size) : 0;
-    DecodeMotionVector( &p_vpar->mb.pppi_pmv[i_r][i_s][0], i_h_r_size,
-                        i_motion_code, i_motion_residual, i_full_pel );
-    p_mb->pppi_motion_vectors[i_r][i_s][0] = p_vpar->mb.pppi_pmv[i_r][i_s][0];
-
-    if( p_vpar->mb.b_dmv )
-    {
-        if( GetBits(&p_vpar->bit_stream, 1) )
-        {
-            pi_dm_vector[0] = GetBits( &p_vpar->bit_stream, 1 ) ? -1 : 1;
-        }
-        else
-        {
-            pi_dm_vector[0] = 0;
-        }
-    }
+    p_tab = DMV_2 + ShowBits( &p_vpar->bit_stream, 2 );
+    RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+    return( p_tab->i_value );
+}
 
-    i_motion_code = MotionCode( p_vpar );
-    i_motion_residual = (i_v_r_size != 0 && i_motion_code != 0) ?
-                        GetBits( &p_vpar->bit_stream, i_v_r_size) : 0;
+/****************************************************************************
+ * Motion* : Parse motion vectors
+ ****************************************************************************/
+#define MOTION_BLOCK( b_aver, i_x, i_y, i_dest,                             \
+                      pp_src, i_src, i_str, i_hei,                          \
+                      b_s_half )                                            \
+    do {                                                                    \
+        motion_inner_t * p_m_inner = p_mb->p_motions + p_mb->i_nb_motions;  \
+        p_m_inner->b_average = b_aver;                                      \
+        p_m_inner->i_x_pred = i_x;                                          \
+        p_m_inner->i_y_pred = i_y;                                          \
+        p_m_inner->pp_source[0] = pp_src[0];                                \
+        p_m_inner->pp_source[1] = pp_src[1];                                \
+        p_m_inner->pp_source[2] = pp_src[2];                                \
+        p_m_inner->i_dest_offset = i_dest;                                  \
+        p_m_inner->i_src_offset = i_src;                                    \
+        p_m_inner->i_stride = i_str;                                        \
+        p_m_inner->i_height = i_hei;                                        \
+        p_m_inner->b_second_half = b_s_half;                                \
+        p_mb->i_nb_motions++;                                               \
+    } while( 0 );
+
+/* MPEG-1 predictions. */
+
+static void MotionMPEG1( vpar_thread_t * p_vpar,
+                                    macroblock_t * p_mb,
+                                    motion_t * p_motion,
+                                    boolean_t b_average )
+{
+    int i_motion_x, i_motion_y;
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
+    
+    i_motion_x = p_motion->ppi_pmv[0][0]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[0][0] = i_motion_x;
 
+    i_motion_y = p_motion->ppi_pmv[0][1]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[0][1] = i_motion_y;
 
-    if( (p_vpar->mb.i_mv_format == MOTION_FIELD)
-        && (i_structure == FRAME_STRUCTURE) )
+    if( p_motion->pi_f_code[1] )
     {
-         p_vpar->mb.pppi_pmv[i_r][i_s][1] >>= 1;
+        i_motion_x <<= 1;
+        i_motion_y <<= 1;
     }
 
-    DecodeMotionVector( &p_vpar->mb.pppi_pmv[i_r][i_s][1], i_v_r_size,
-                        i_motion_code, i_motion_residual, i_full_pel );
+    MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset,
+                  p_motion->pppi_ref[0], i_offset, i_width, 16, 0 );
+}
 
-    if( (p_vpar->mb.i_mv_format == MOTION_FIELD)
-        && (i_structure == FRAME_STRUCTURE) )
-         p_vpar->mb.pppi_pmv[i_r][i_s][1] <<= 1;
+static void MotionMPEG1Reuse( vpar_thread_t * p_vpar,
+                                         macroblock_t * p_mb,
+                                         motion_t * p_motion,
+                                         boolean_t b_average )
+{
+    int i_motion_x, i_motion_y;
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
 
-    p_mb->pppi_motion_vectors[i_r][i_s][1] = p_vpar->mb.pppi_pmv[i_r][i_s][1];
+    i_motion_x = p_motion->ppi_pmv[0][0];
+    i_motion_y = p_motion->ppi_pmv[0][1];
 
-    if( p_vpar->mb.b_dmv )
+    if( p_motion->pi_f_code[1] )
     {
-        if( GetBits(&p_vpar->bit_stream, 1) )
-        {
-            pi_dm_vector[1] = GetBits( &p_vpar->bit_stream, 1 ) ? -1 : 1;
-        }
-        else
-        {
-            pi_dm_vector[1] = 0;
-        }
-
-        /* Dual Prime Arithmetic (ISO/IEC 13818-2 section 7.6.3.6). */
-
-#define i_mv_x  p_mb->pppi_motion_vectors[0][0][0]
-        if( i_structure == FRAME_STRUCTURE )
-        {
-#define i_mv_y  (p_mb->pppi_motion_vectors[0][0][1] << 1)
-            if( p_vpar->picture.b_top_field_first )
-            {
-                /* vector for prediction of top field from bottom field */
-                p_mb->ppi_dmv[0][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
-                p_mb->ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] - 1;
+        i_motion_x <<= 1;
+        i_motion_y <<= 1;
+    }
 
-                /* vector for prediction of bottom field from top field */
-                p_mb->ppi_dmv[1][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
-                p_mb->ppi_dmv[1][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] + 1;
-            }
-            else
-            {
-                /* vector for prediction of top field from bottom field */
-                p_mb->ppi_dmv[0][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
-                p_mb->ppi_dmv[0][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] - 1;
+     MOTION_BLOCK( b_average, p_motion->ppi_pmv[0][0], p_motion->ppi_pmv[0][1],
+                  i_offset, p_motion->pppi_ref[0], i_offset, i_width, 16, 0 );
+}
 
-                /* vector for prediction of bottom field from top field */
-                p_mb->ppi_dmv[1][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
-                p_mb->ppi_dmv[1][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] + 1;
-            }
-#undef i_mv_y
-        }
-        else
-        {
-#define i_mv_y  p_mb->pppi_motion_vectors[0][0][1]
-            /* vector for prediction from field of opposite 'parity' */
-            p_mb->ppi_dmv[0][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
-            p_mb->ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1];
+/* MPEG-2 frame predictions. */
 
-            /* correct for vertical field shift */
-            if( i_structure == TOP_FIELD )
-                p_mb->ppi_dmv[0][1]--;
-            else
-                p_mb->ppi_dmv[0][1]++;
-#undef i_mv_y
-        }
-#undef i_mv_x
-    }
+static void MotionFrameFrame( vpar_thread_t * p_vpar,
+                                         macroblock_t * p_mb,
+                                         motion_t * p_motion,
+                                         boolean_t b_average )
+{
+    int i_motion_x, i_motion_y;
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
+
+    i_motion_x = p_motion->ppi_pmv[0][0]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_motion_x;
+
+    i_motion_y = p_motion->ppi_pmv[0][1]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[1] );
+    i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] );
+    p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_motion_y;
+
+    MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset,
+                  p_motion->pppi_ref[0], i_offset, i_width, 16, 0 );
 }
 
-/*****************************************************************************
- * DecodeMVMPEG1 : Parse the next MPEG-1 motion vectors
- *****************************************************************************/
-static void DecodeMVMPEG1( vpar_thread_t * p_vpar,
-                           macroblock_t * p_mb, int i_s, int i_structure )
+static void MotionFrameField( vpar_thread_t * p_vpar,
+                                         macroblock_t * p_mb,
+                                         motion_t * p_motion,
+                                         boolean_t b_average )
 {
-    int i_r_size = i_s ? p_vpar->picture.i_backward_f_code - 1 :
-                         p_vpar->picture.i_forward_f_code - 1;
-    MotionVector( p_vpar, p_mb, 0, i_s,
-                  p_vpar->picture.pb_full_pel_vector[i_s], FRAME_STRUCTURE,
-                  i_r_size, i_r_size );
+    int i_motion_x, i_motion_y, i_field_select;
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
+
+    i_field_select = GetSignedBits( &p_vpar->bit_stream, 1 );
+
+    i_motion_x = p_motion->ppi_pmv[0][0]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[0][0] = i_motion_x;
+
+    i_motion_y = (p_motion->ppi_pmv[0][1] >> 1)
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[1] );
+    /* According to ISO/IEC 13818-2 section 7.6.3.2, the vertical motion
+     * vector is restricted to a range that implies it doesn't need to
+     * be bound. */
+    /* i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); */
+    p_motion->ppi_pmv[0][1] = i_motion_y << 1;
+
+    MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset,
+                  p_motion->pppi_ref[0], i_offset + (i_field_select & i_width),
+                  i_width * 2, 8, 0 );
+
+    i_field_select = GetSignedBits( &p_vpar->bit_stream, 1 );
+
+    i_motion_x = p_motion->ppi_pmv[1][0]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[1][0] = i_motion_x;
+
+    i_motion_y = (p_motion->ppi_pmv[1][1] >> 1)
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[1] );
+    /* i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); */
+    p_motion->ppi_pmv[1][1] = i_motion_y << 1;
+
+    MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset + i_width,
+                  p_motion->pppi_ref[0], i_offset + (i_field_select & i_width),
+                  i_width * 2, 8, 0 );
 }
 
-/*****************************************************************************
- * DecodeMVMPEG2 : Parse the next MPEG-2 motion_vectors field
- *****************************************************************************/
-static void DecodeMVMPEG2( vpar_thread_t * p_vpar,
-                           macroblock_t * p_mb, int i_s, int i_structure )
+static void MotionFrameDMV( vpar_thread_t * p_vpar,
+                                       macroblock_t * p_mb,
+                                       motion_t * p_motion,
+                                       boolean_t b_average )
 {
-    if( p_vpar->mb.i_mv_count == 1 )
-    {
-        if( p_vpar->mb.i_mv_format == MOTION_FIELD && !p_vpar->mb.b_dmv )
-        {
-            p_mb->ppi_field_select[0][i_s] = p_mb->ppi_field_select[1][i_s]
-                                            = GetBits( &p_vpar->bit_stream, 1 );
-        }
-        MotionVector( p_vpar, p_mb, 0, i_s, 0, i_structure,
-                      p_vpar->picture.ppi_f_code[i_s][0] - 1,
-                      p_vpar->picture.ppi_f_code[i_s][1] - 1 );
-        p_vpar->mb.pppi_pmv[1][i_s][0] = p_vpar->mb.pppi_pmv[0][i_s][0];
-        p_vpar->mb.pppi_pmv[1][i_s][1] = p_vpar->mb.pppi_pmv[0][i_s][1];
-        p_mb->pppi_motion_vectors[1][i_s][0] = p_vpar->mb.pppi_pmv[0][i_s][0];
-        p_mb->pppi_motion_vectors[1][i_s][1] = p_vpar->mb.pppi_pmv[0][i_s][1];
-    }
-    else
-    {
-        p_mb->ppi_field_select[0][i_s] = GetBits( &p_vpar->bit_stream, 1 );
-        MotionVector( p_vpar, p_mb, 0, i_s, 0, i_structure,
-                      p_vpar->picture.ppi_f_code[i_s][0] - 1,
-                      p_vpar->picture.ppi_f_code[i_s][1] - 1 );
-        p_mb->ppi_field_select[1][i_s] = GetBits( &p_vpar->bit_stream, 1 );
-        MotionVector( p_vpar, p_mb, 1, i_s, 0, i_structure,
-                      p_vpar->picture.ppi_f_code[i_s][0] - 1,
-                      p_vpar->picture.ppi_f_code[i_s][1] - 1 );
-    }
+    int i_motion_x, i_motion_y;
+    int i_dmv_x, i_dmv_y;
+    int i_tmp_x, i_tmp_y;
+
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
+    int m;
+
+    i_motion_x = p_motion->ppi_pmv[0][0]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_motion_x;
+
+    i_dmv_x = GetDMV( p_vpar );
+
+    i_motion_y = (p_motion->ppi_pmv[0][1] >> 1)
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[1] );
+    /* i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] ); */
+    p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_motion_y << 1;
+
+    i_dmv_y = GetDMV( p_vpar );
+
+    /* First field. */
+    MOTION_BLOCK( 0, i_motion_x, i_motion_y, i_offset,
+                  p_motion->pppi_ref[0], i_offset, i_width * 2, 8, 0 );
+    m = p_vpar->picture.b_top_field_first ? 1 : 3;
+    i_tmp_x = ((i_motion_x * m + (i_motion_x > 0)) >> 1) + i_dmv_x;
+    i_tmp_y = ((i_motion_y * m + (i_motion_y > 0)) >> 1) + i_dmv_y - 1;
+    MOTION_BLOCK( 1, i_tmp_x, i_tmp_y, i_offset, p_motion->pppi_ref[0],
+                  i_offset + i_width, i_width * 2, 8, 0 );
+
+    /* Second field. */
+    MOTION_BLOCK( 0, i_motion_x, i_motion_y, i_offset + i_width,
+                  p_motion->pppi_ref[0], i_offset + i_width, i_width * 2, 8, 0 );
+    m = p_vpar->picture.b_top_field_first ? 3 : 1;
+    i_tmp_x = ((i_motion_x * m + (i_motion_x > 0)) >> 1) + i_dmv_x;
+    i_tmp_y = ((i_motion_y * m + (i_motion_y > 0)) >> 1) + i_dmv_y + 1;
+    MOTION_BLOCK( 1, i_tmp_x, i_tmp_y, i_offset + i_width,
+                  p_motion->pppi_ref[0], i_offset, i_width * 2, 8, 0 );
 }
 
-
-/*
- * Macroblock information structures
- */
-
-/*****************************************************************************
- * MacroblockAddressIncrement : Get the macroblock_address_increment field
- *****************************************************************************/
-static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar )
+static void MotionFrameZero( vpar_thread_t * p_vpar,
+                                        macroblock_t * p_mb,
+                                        motion_t * p_motion,
+                                        boolean_t b_average )
 {
-    int i_addr_inc = 0;
-    /* Index in the lookup table mb_addr_inc */
-    int    i_index = ShowBits( &p_vpar->bit_stream, 11 );
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
 
-    /* Test the presence of the escape character */
-    while( i_index == 8 )
-    {
-        RemoveBits( &p_vpar->bit_stream, 11 );
-        i_addr_inc += 33;
-        i_index = ShowBits( &p_vpar->bit_stream, 11 );
-    }
-
-    /* Affect the value from the lookup table */
-    i_addr_inc += p_vpar->pl_mb_addr_inc[i_index].i_value;
-
-    /* Dump the good number of bits */
-    RemoveBits( &p_vpar->bit_stream, p_vpar->pl_mb_addr_inc[i_index].i_length );
-
-    return i_addr_inc;
+    MOTION_BLOCK( b_average, 0, 0, i_offset, p_motion->pppi_ref[0],
+                  i_offset, i_width, 16, 0 );
 }
 
-/*****************************************************************************
- * IMBType : macroblock_type in I pictures
- *****************************************************************************/
-static __inline__ int IMBType( vpar_thread_t * p_vpar )
+static void MotionFrameReuse( vpar_thread_t * p_vpar,
+                                         macroblock_t * p_mb,
+                                         motion_t * p_motion,
+                                         boolean_t b_average )
 {
-    /* Take two bits for testing */
-    int                 i_type = ShowBits( &p_vpar->bit_stream, 2 );
-
-    /* Lookup table for macroblock_type */
-    static lookup_t     pl_mb_Itype[4] = { {MB_ERROR, 0},
-                                           {MB_QUANT|MB_INTRA, 2},
-                                           {MB_INTRA, 1},
-                                           {MB_INTRA, 1} };
-    /* Dump the good number of bits */
-    RemoveBits( &p_vpar->bit_stream, pl_mb_Itype[i_type].i_length );
-    return pl_mb_Itype[i_type].i_value;
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
+
+    MOTION_BLOCK( b_average, p_motion->ppi_pmv[0][0], p_motion->ppi_pmv[0][1],
+                  i_offset, p_motion->pppi_ref[0], i_offset, i_width, 16, 0 );
 }
 
-/*****************************************************************************
- * PMBType : macroblock_type in P pictures
- *****************************************************************************/
-static __inline__ int PMBType( vpar_thread_t * p_vpar )
+/* MPEG-2 field predictions. */
+
+static void MotionFieldField( vpar_thread_t * p_vpar,
+                                         macroblock_t * p_mb,
+                                         motion_t * p_motion,
+                                         boolean_t b_average )
 {
-    /* Testing on 6 bits */
-    int                i_type = ShowBits( &p_vpar->bit_stream, 6 );
+    int i_motion_x, i_motion_y;
+    boolean_t b_field_select;
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
 
-    /* Dump the good number of bits */
-    RemoveBits( &p_vpar->bit_stream, p_vpar->ppl_mb_type[0][i_type].i_length );
-    /* return the value from the lookup table for P type */
-    return p_vpar->ppl_mb_type[0][i_type].i_value;
-}
+    b_field_select = GetBits( &p_vpar->bit_stream, 1 );
 
-/*****************************************************************************
- * BMBType : macroblock_type in B pictures
- *****************************************************************************/
-static __inline__ int BMBType( vpar_thread_t * p_vpar )
-{
-     /* Testing on 6 bits */
-    int                i_type = ShowBits( &p_vpar->bit_stream, 6 );
+    i_motion_x = p_motion->ppi_pmv[0][0]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_motion_x;
 
-    /* Dump the good number of bits */
-    RemoveBits( &p_vpar->bit_stream, p_vpar->ppl_mb_type[1][i_type].i_length );
+    i_motion_y = p_motion->ppi_pmv[0][1]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[1] );
+    i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] );
+    p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_motion_y;
 
-    /* return the value from the lookup table for B type */
-    return p_vpar->ppl_mb_type[1][i_type].i_value;
+    MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset,
+                  p_motion->pppi_ref[b_field_select], i_offset, i_width, 16, 0 );
 }
 
-/*****************************************************************************
- * DMBType : macroblock_type in D pictures
- *****************************************************************************/
-static __inline__ int DMBType( vpar_thread_t * p_vpar )
+static void MotionField16x8( vpar_thread_t * p_vpar,
+                                        macroblock_t * p_mb,
+                                        motion_t * p_motion,
+                                        boolean_t b_average )
 {
-    return GetBits( &p_vpar->bit_stream, 1 );
+    int i_motion_x, i_motion_y;
+    boolean_t b_field_select;
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
+
+    /* First half. */
+    b_field_select = GetBits( &p_vpar->bit_stream, 1 );
+
+    i_motion_x = p_motion->ppi_pmv[0][0]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[0][0] = i_motion_x;
+
+    i_motion_y = p_motion->ppi_pmv[0][1]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[1] );
+    i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] );
+    p_motion->ppi_pmv[0][1] = i_motion_y;
+
+    MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset,
+                  p_motion->pppi_ref[b_field_select], i_offset, i_width, 8, 0 );
+
+    /* Second half. */
+    b_field_select = GetBits( &p_vpar->bit_stream, 1 );
+
+    i_motion_x = p_motion->ppi_pmv[1][0]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[1][0] = i_motion_x;
+
+    i_motion_y = p_motion->ppi_pmv[1][1]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[1] );
+    i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] );
+    p_motion->ppi_pmv[1][1] = i_motion_y;
+
+    MOTION_BLOCK( b_average, i_motion_x, i_motion_y, i_offset,
+                  p_motion->pppi_ref[b_field_select], i_offset, i_width, 8, 1 );
 }
 
-/*****************************************************************************
- * CodedPattern420 : coded_block_pattern with 4:2:0 chroma
- *****************************************************************************/
-static __inline__ int CodedPattern420( vpar_thread_t * p_vpar )
+static void MotionFieldDMV( vpar_thread_t * p_vpar,
+                                       macroblock_t * p_mb,
+                                       motion_t * p_motion,
+                                       boolean_t b_average )
 {
-    /* Take the max 9 bits length vlc code for testing */
-    int      i_vlc = ShowBits( &p_vpar->bit_stream, 9 );
+    int i_motion_x, i_motion_y;
+    int i_dmv_x, i_dmv_y;
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
+    boolean_t b_current_field = p_vpar->picture.b_current_field;
+
+    i_motion_x = p_motion->ppi_pmv[0][0]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_motion_x = BoundMotionVector( i_motion_x, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_motion_x;
+
+    i_dmv_x = GetDMV( p_vpar );
+
+    i_motion_y = p_motion->ppi_pmv[0][1]
+                        + MotionDelta( p_vpar, p_motion->pi_f_code[1] );
+    i_motion_y = BoundMotionVector( i_motion_y, p_motion->pi_f_code[1] );
+    p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_motion_y;
+
+    i_dmv_y = GetDMV( p_vpar );
+
+    MOTION_BLOCK( 0, i_motion_x, i_motion_y, i_offset,
+                  p_motion->pppi_ref[b_current_field],
+                  i_offset, i_width, 16, 0 );
+
+    i_motion_x = ((i_motion_x + (i_motion_x > 0)) >> 1) + i_dmv_x;
+    i_motion_y = ((i_motion_y + (i_motion_y > 0)) >> 1) + i_dmv_y
+                    + 2 * b_current_field - 1;
+    MOTION_BLOCK( 1, i_motion_x, i_motion_y, i_offset,
+                  p_motion->pppi_ref[!b_current_field],
+                  i_offset, i_width, 16, 0 );
+}
 
-    /* Trash the good number of bits read in the lookup table */
-    RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length );
+static void MotionFieldZero( vpar_thread_t * p_vpar,
+                                        macroblock_t * p_mb,
+                                        motion_t * p_motion,
+                                        boolean_t b_average )
+{
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
+    boolean_t b_current_field = p_vpar->picture.b_current_field;
 
-    /* return the value from the vlc table */
-    return pl_coded_pattern[i_vlc].i_value;
+    MOTION_BLOCK( b_average, 0, 0, i_offset, p_motion->pppi_ref[b_current_field],
+                  i_offset, i_width, 16, 0 );
 }
 
-/*****************************************************************************
- * CodedPattern422 : coded_block_pattern with 4:2:2 chroma
- *****************************************************************************/
-static __inline__ int CodedPattern422( vpar_thread_t * p_vpar )
+static void MotionFieldReuse( vpar_thread_t * p_vpar,
+                                         macroblock_t * p_mb,
+                                         motion_t * p_motion,
+                                         boolean_t b_average )
 {
-    int      i_vlc = ShowBits( &p_vpar->bit_stream, 9 );
+    int i_offset = p_vpar->mb.i_offset;
+    int i_width = p_vpar->picture.i_field_width;
+    boolean_t b_current_field = p_vpar->picture.b_current_field;
 
-    RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length );
-
-    /* Supplementary 2 bits long code for 4:2:2 format */
-    return pl_coded_pattern[i_vlc].i_value |
-           (GetBits( &p_vpar->bit_stream, 2 ) << 6);
+    MOTION_BLOCK( b_average, p_motion->ppi_pmv[0][0], p_motion->ppi_pmv[0][1],
+                  i_offset, p_motion->pppi_ref[b_current_field],
+                  i_offset, i_width, 16, 0 );
 }
 
-/*****************************************************************************
- * CodedPattern444 : coded_block_pattern with 4:4:4 chroma
- *****************************************************************************/
-static __inline__ int CodedPattern444( vpar_thread_t * p_vpar )
+/* MPEG-2 concealment motion vectors. */
+
+static void MotionFrameConceal( vpar_thread_t * p_vpar,
+                                           macroblock_t * p_mv,
+                                           motion_t * p_motion )
 {
-    int      i_vlc = ShowBits( &p_vpar->bit_stream, 9 );
+    int i_tmp;
 
-    RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length );
+    i_tmp = p_motion->ppi_pmv[0][0]
+                + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_tmp = BoundMotionVector( i_tmp, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_tmp;
 
-    return pl_coded_pattern[i_vlc].i_value |
-           (GetBits( &p_vpar->bit_stream, 6 ) << 6);
+    i_tmp = p_motion->ppi_pmv[0][1]
+                + MotionDelta( p_vpar, p_motion->pi_f_code[1] );
+    i_tmp = BoundMotionVector( i_tmp, p_motion->pi_f_code[1] );
+    p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_tmp;
+
+    /* Marker bit. */
+    RemoveBits( &p_vpar->bit_stream, 1 );
 }
 
-/*****************************************************************************
- * InitMacroblock : Initialize macroblock values
- *****************************************************************************/
-static __inline__ void InitMacroblock( vpar_thread_t * p_vpar,
-                                       macroblock_t * p_mb, int i_coding_type,
-                                       int i_structure )
+static void MotionFieldConceal( vpar_thread_t * p_vpar,
+                                           macroblock_t * p_mv,
+                                           motion_t * p_motion )
 {
-    int     i_chroma_format = CHROMA_420; /* FIXME : MP@ML */
+    int i_tmp;
 
-    p_mb->i_chroma_nb_blocks = 1 << i_chroma_format;
-    p_mb->p_picture = p_vpar->picture.p_picture;
+    /* field_select */
+    RemoveBits( &p_vpar->bit_stream, 1 );
 
-    if( i_coding_type == B_CODING_TYPE )
-        p_mb->p_backward = p_vpar->sequence.p_backward;
-    else
-        p_mb->p_backward = NULL;
+    i_tmp = p_motion->ppi_pmv[0][0]
+                + MotionDelta( p_vpar, p_motion->pi_f_code[0] );
+    i_tmp = BoundMotionVector( i_tmp, p_motion->pi_f_code[0] );
+    p_motion->ppi_pmv[1][0] = p_motion->ppi_pmv[0][0] = i_tmp;
 
-    if( (i_coding_type == P_CODING_TYPE) || (i_coding_type == B_CODING_TYPE) )
-        p_mb->p_forward = p_vpar->sequence.p_forward;
-    else
-        p_mb->p_forward = NULL;
+    i_tmp = p_motion->ppi_pmv[0][1]
+                + MotionDelta( p_vpar, p_motion->pi_f_code[1] );
+    i_tmp = BoundMotionVector( i_tmp, p_motion->pi_f_code[1] );
+    p_motion->ppi_pmv[1][1] = p_motion->ppi_pmv[0][1] = i_tmp;
 
-    p_mb->i_l_x = p_vpar->mb.i_l_x;
-    p_mb->i_c_x = p_vpar->mb.i_c_x;
-    p_mb->i_motion_l_y = p_vpar->mb.i_l_y;
-    p_mb->i_motion_c_y = p_vpar->mb.i_c_y;
-    if( (p_mb->b_motion_field = (i_structure == BOTTOM_FIELD)) )
-    {
-        p_mb->i_motion_l_y--;
-        p_mb->i_motion_c_y--;
-    }
-    p_mb->i_addb_l_stride = (p_mb->i_l_stride = p_vpar->picture.i_l_stride) - 8;
-    p_mb->i_addb_c_stride = (p_mb->i_c_stride = p_vpar->picture.i_c_stride) - 8;
-    p_mb->b_P_second = ( (i_structure != p_vpar->picture.i_current_structure)
-                           && i_coding_type == P_CODING_TYPE );
+    /* Marker bit. */
+    RemoveBits( &p_vpar->bit_stream, 1 );
 }
 
-/*****************************************************************************
- * UpdateContext : Update the p_vpar contextual values
- *****************************************************************************/
-static __inline__ void UpdateContext( vpar_thread_t * p_vpar, int i_structure )
-{
-    /* Update macroblock real position. */
-    p_vpar->mb.i_l_x += 16;
-    p_vpar->mb.i_l_y += (p_vpar->mb.i_l_x / p_vpar->sequence.i_width)
-                        * (2 - (i_structure == FRAME_STRUCTURE)) * 16;
-    p_vpar->mb.i_l_x %= p_vpar->sequence.i_width;
-
-    p_vpar->mb.i_c_x += p_vpar->sequence.i_chroma_mb_width;
-    p_vpar->mb.i_c_y += (p_vpar->mb.i_c_x / p_vpar->sequence.i_chroma_width)
-                        * (2 - (i_structure == FRAME_STRUCTURE))
-                        * p_vpar->sequence.i_chroma_mb_height;
-    p_vpar->mb.i_c_x %= p_vpar->sequence.i_chroma_width;
-}
+
+/*
+ * Macroblock information structures
+ */
 
 /*****************************************************************************
- * SkippedMacroblock : Generate a skipped macroblock with NULL motion vector
+ * MacroblockAddressIncrement : Get the macroblock_address_increment field
  *****************************************************************************/
-static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb,
-                                          int i_mb_base, int i_coding_type,
-                                          int i_structure  )
+static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar )
 {
-    macroblock_t *  p_mb;
-    int             i_chroma_format = CHROMA_420; /* FIXME : MP@ML */
+    lookup_t *  p_tab;
+    int         i_code;
+    int         i_mba = 0;
 
-    if( i_coding_type == I_CODING_TYPE )
+    for( ; ; )
     {
-        intf_WarnMsg( 2, "skipped macroblock in I-picture" );
-        p_vpar->picture.b_error = 1;
-        return;
-    }
+        if( (i_code = ShowBits( &p_vpar->bit_stream, 5 ) ) >= 0x2 )
+        {
+            p_tab = MBA_5 - 2 + i_code;
+            RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+            return( i_mba + p_tab->i_value );
+        }
+        else if( (i_code = ShowBits( &p_vpar->bit_stream, 11 )) >= 0x18 )
+        {
+            p_tab = MBA_11 - 24 + i_code;
+            RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+            return( i_mba + p_tab->i_value );
+        }
+        else switch( i_code )
+        {
+        case 8:
+            /* Macroblock escape */
+            i_mba += 33;
+            /* continue... */
+        case 15:
+            /* Macroblock stuffing (MPEG-1 ONLY) */
+            RemoveBits( &p_vpar->bit_stream, 11 );
+            break;
 
-    if( (p_mb = vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
-    {
-        /* b_die == 1 */
-        return;
+        default:
+            /* End of slice, or error */
+            return 0;
+        }
     }
-#ifdef VDEC_SMP
-    p_vpar->picture.pp_mb[i_mb_base + i_mb] = p_mb;
-#endif
-
-    InitMacroblock( p_vpar, p_mb, i_coding_type, i_structure );
+}
 
-    /* Motion type is picture structure. */
-    p_mb->pf_motion = p_vpar->ppf_motion_skipped[i_chroma_format]
-                                                [i_structure];
-    p_mb->i_coded_block_pattern = 0;
+/*****************************************************************************
+ * CodedPattern : coded_block_pattern
+ *****************************************************************************/
+static __inline__ int CodedPattern( vpar_thread_t * p_vpar )
+{
+    lookup_t *  p_tab;
+    int         i_code;
 
-    /* Motion direction and motion vectors depend on the coding type. */
-    if( i_coding_type == B_CODING_TYPE )
+    if( (i_code = ShowBits( &p_vpar->bit_stream, 7 )) >= 0x10 ) /* ? */
     {
-        p_mb->i_mb_type = p_vpar->mb.i_motion_dir;
-        memcpy( p_mb->pppi_motion_vectors, p_vpar->mb.pppi_pmv,
-                sizeof( p_vpar->mb.pppi_pmv ) );
+        p_tab = CBP_7 - 16 + i_code;
+        RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+        return( p_tab->i_value );
     }
     else
     {
-        p_mb->i_mb_type = MB_MOTION_FORWARD;
-        bzero8int( p_mb->pppi_motion_vectors );
+        p_tab = CBP_9 + ShowBits( &p_vpar->bit_stream, 9 );
+        RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+        return( p_tab->i_value );
     }
-
-    /* Set the field we use for motion compensation */
-    p_mb->ppi_field_select[0][0] = p_mb->ppi_field_select[0][1]
-                                 = ( i_structure == BOTTOM_FIELD );
-
-    UpdateContext( p_vpar, i_structure );
-
-#ifndef VDEC_SMP
-    /* Decode the macroblock NOW ! */
-    vpar_DecodeMacroblock ( &p_vpar->vfifo, p_mb );
-#endif
 }
 
 /*****************************************************************************
  * MacroblockModes : Get the macroblock_modes structure
  *****************************************************************************/
-static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
-                                        macroblock_t * p_mb,
-                                        int i_coding_type,
-                                        int i_structure )
+static __inline__ int MacroblockModes( vpar_thread_t * p_vpar,
+                                       macroblock_t * p_mb,
+                                       int i_coding_type,
+                                       int i_structure )
 {
-    static int          ppi_mv_count[2][4] = { {0, 1, 2, 1}, {0, 2, 1, 1} };
-    static int          ppi_mv_format[2][4] = { {0, 1, 1, 1}, {0, 1, 2, 1} };
+    int         i_mb_modes;
+    lookup_t *  p_tab;
 
-    /* Get macroblock_type. */
     switch( i_coding_type )
     {
-    case P_CODING_TYPE:
-        p_mb->i_mb_type = PMBType( p_vpar );
-        break;
-    case B_CODING_TYPE:
-        p_mb->i_mb_type = BMBType( p_vpar );
-        break;
     case I_CODING_TYPE:
-        p_mb->i_mb_type = IMBType( p_vpar );
-        break;
-    case D_CODING_TYPE:
-        p_mb->i_mb_type = DMBType( p_vpar );
-    }
+        p_tab = MB_I + ShowBits( &p_vpar->bit_stream, 1 );
+        RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+        i_mb_modes = p_tab->i_value;
 
-    if( i_coding_type == B_CODING_TYPE )
-    {
-        /* We need to remember the motion direction of the last macroblock
-         * before a skipped macroblock (ISO/IEC 13818-2 7.6.6) */
-        p_vpar->mb.i_motion_dir = p_mb->i_mb_type
-                              & (MB_MOTION_FORWARD | MB_MOTION_BACKWARD);
-    }
+        if( (i_structure == FRAME_STRUCTURE) &&
+            (!p_vpar->picture.b_frame_pred_frame_dct) )
+        {
+            i_mb_modes |= GetBits( &p_vpar->bit_stream, 1 )
+                                * DCT_TYPE_INTERLACED;
+        }
+        return( i_mb_modes );
 
-    /* SCALABILITY : warning, we don't know if spatial_temporal_weight_code
-     * has to be dropped, take care if you use scalable streams. */
-    /* RemoveBits( &p_vpar->bit_stream, 2 ); */
+    case P_CODING_TYPE:
+        p_tab = MB_P + ShowBits( &p_vpar->bit_stream, 5 );
+        RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+        i_mb_modes = p_tab->i_value;
 
-    if( (i_coding_type == P_CODING_TYPE || i_coding_type == B_CODING_TYPE)
-        && (p_mb->i_mb_type & (MB_MOTION_FORWARD | MB_MOTION_BACKWARD)) )
-    {
-        if( !(i_structure == FRAME_STRUCTURE
-               && p_vpar->picture.b_frame_pred_frame_dct) )
+        if( i_structure != FRAME_STRUCTURE )
+        {
+            if( i_mb_modes & MB_MOTION_FORWARD )
+            {
+                i_mb_modes |= GetBits( &p_vpar->bit_stream, 2 )
+                                    * MOTION_TYPE_BASE;
+            }
+            return( i_mb_modes );
+        }
+        else if( p_vpar->picture.b_frame_pred_frame_dct )
         {
-            p_vpar->mb.i_motion_type = GetBits( &p_vpar->bit_stream, 2 );
+            if( i_mb_modes & MB_MOTION_FORWARD )
+            {
+                i_mb_modes |= MC_FRAME;
+            }
+            return( i_mb_modes );
         }
         else
         {
-            p_vpar->mb.i_motion_type = MOTION_FRAME;
+            if( i_mb_modes & MB_MOTION_FORWARD )
+            {
+                i_mb_modes |= GetBits( &p_vpar->bit_stream, 2 )
+                                    * MOTION_TYPE_BASE;
+            }
+            if( i_mb_modes & (MB_INTRA | MB_PATTERN) )
+            {
+                i_mb_modes |= GetBits( &p_vpar->bit_stream, 1 )
+                                    * DCT_TYPE_INTERLACED;
+            }
+            return( i_mb_modes );
         }
 
-        /* XXX?? */
-        p_vpar->mb.i_mv_count = ppi_mv_count[i_structure == FRAME_STRUCTURE]
-                                            [p_vpar->mb.i_motion_type];
-        p_vpar->mb.i_mv_format = ppi_mv_format[i_structure == FRAME_STRUCTURE]
-                                              [p_vpar->mb.i_motion_type];
-        p_vpar->mb.b_dmv = p_vpar->mb.i_motion_type == MOTION_DMV;
-    }
+    case B_CODING_TYPE:
+        p_tab = MB_B + ShowBits( &p_vpar->bit_stream, 6 );
+        RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
+        i_mb_modes = p_tab->i_value;
 
-    p_vpar->mb.b_dct_type = 0;
-    if( (i_structure == FRAME_STRUCTURE) &&
-        (!p_vpar->picture.b_frame_pred_frame_dct) &&
-        (p_mb->i_mb_type & (MB_PATTERN|MB_INTRA)) )
-    {
-        if( (p_vpar->mb.b_dct_type = GetBits( &p_vpar->bit_stream, 1 )) )
+        if( i_structure != FRAME_STRUCTURE )
         {
-            /* The DCT is coded on fields. Jump one line between each
-             * sample. */
-            p_mb->i_addb_l_stride <<= 1;
-            p_mb->i_addb_l_stride += 8;
-#if 0
-            /* FIXME: MP@ML */
-            /* With CHROMA_420, the DCT is necessarily frame-coded. */
-            if( i_chroma_format != CHROMA_420 )
+            if( !( i_mb_modes & MB_INTRA ) )
             {
-                p_mb->i_addb_c_stride <<= 1;
-                p_mb->i_addb_c_stride += 8;
+                i_mb_modes |= GetBits( &p_vpar->bit_stream, 2 )
+                                    * MOTION_TYPE_BASE;
             }
-#endif
+            return( i_mb_modes );
+        }
+        else if( p_vpar->picture.b_frame_pred_frame_dct )
+        {
+            i_mb_modes |= MC_FRAME;
+            return( i_mb_modes );
+        }
+        else
+        {
+            if( i_mb_modes & MB_INTRA )
+            {
+                goto mb_intra;
+            }
+            i_mb_modes |= GetBits( &p_vpar->bit_stream, 2 )
+                                * MOTION_TYPE_BASE;
+            if( i_mb_modes & (MB_INTRA | MB_PATTERN) )
+            {
+mb_intra:
+                i_mb_modes |= GetBits( &p_vpar->bit_stream, 1 )
+                                    * DCT_TYPE_INTERLACED;
+            }
+            return( i_mb_modes );
         }
+
+    case D_CODING_TYPE:
+        RemoveBits( &p_vpar->bit_stream, 1 );
+        return( MB_INTRA );
+
+    default:
+        return( 0 );
     }
 }
 
+
+/*
+ * Picture data parsing management
+ */
+
 /*****************************************************************************
- * ParseMacroblock : Parse the next macroblock
+ * ParseSlice : Parse the next slice structure
  *****************************************************************************/
-#define PARSEERROR                                                      \
-if( p_vpar->picture.b_error )                                           \
-{                                                                       \
-    /* Go to the next slice. */                                         \
-    vpar_FreeMacroblock( &p_vpar->vfifo, p_mb );                        \
-    return;                                                             \
-}
+#define MOTION( pf_routine, i_direction )                                   \
+    if( (i_direction) & MB_MOTION_FORWARD )                                 \
+    {                                                                       \
+        pf_routine( p_vpar, p_mb, &p_vpar->mb.f_motion, 0 );                \
+        if( (i_coding_type == B_CODING_TYPE)                                \
+                && ((i_direction) & MB_MOTION_BACKWARD) )                   \
+        {                                                                   \
+            pf_routine( p_vpar, p_mb, &p_vpar->mb.b_motion, 1 );            \
+        }                                                                   \
+    }                                                                       \
+    else if( (i_coding_type == B_CODING_TYPE)                               \
+                 && ((i_direction) & MB_MOTION_BACKWARD) )                  \
+    {                                                                       \
+        pf_routine( p_vpar, p_mb, &p_vpar->mb.b_motion, 0 );                \
+    }
 
-static __inline__ void ParseMacroblock(
-                           vpar_thread_t * p_vpar,
-                           int * pi_mb_address,     /* previous address to be
-                                                     * used for mb_addr_incr */
-                           int i_mb_previous,          /* actual previous mb */
-                           int i_mb_base,     /* non-zero if field structure */
-                           /* The following parameters are explicit in
-                            * optimized routines : */
-                           boolean_t b_mpeg2,             /* you know what ? */
-                           int i_coding_type,                /* I, P, B or D */
-                           int i_structure )   /* T(OP), B(OTTOM) or F(RAME) */
+#define CHECK_BOUNDARIES                                                    \
+    i_offset = p_vpar->mb.i_offset;                                         \
+    if( i_offset == i_width )                                               \
+    {                                                                       \
+        if( i_coding_type != I_CODING_TYPE ||                               \
+            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;                     \
+        }                                                                   \
+        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_dest[0] += 16 * i_offset;                                         \
+        p_dest[1] += 4 * i_offset;                                          \
+        p_dest[2] += 4 * i_offset;                                          \
+        i_offset = 0;                                                       \
+    }                                                                       \
+    p_vpar->mb.i_offset = i_offset;
+
+#define PARSEERROR                                                          \
+    if( p_vpar->picture.b_error )                                           \
+    {                                                                       \
+        /* Go to the next slice. */                                         \
+        p_vpar->pool.pf_free_mb( &p_vpar->pool, p_mb );                     \
+        return;                                                             \
+    }
+
+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_mb;
-    int             i_inc;
-    int             i_chroma_format = CHROMA_420; /* FIXME : MP@ML */
-    macroblock_t *  p_mb;
+    int             i_offset, i_width;
+    picture_t *     pp_forward_ref[2];
+    yuv_data_t *    p_dest[3];
 
-    i_inc = MacroblockAddressIncrement( p_vpar );
-    *pi_mb_address += i_inc;
+    motion_t *      p_f_motion = &p_vpar->mb.f_motion;
+    motion_t *      p_b_motion = &p_vpar->mb.b_motion;
+
+    /* Parse header. */
+    LoadQuantizerScale( p_vpar );
 
-    if( i_inc < 0 )
+    if( GetBits( &p_vpar->bit_stream, 1 ) )
     {
-        intf_WarnMsg( 2, "Bad address increment (%d)", i_inc );
-        p_vpar->picture.b_error = 1;
-        return;
+        /* intra_slice, slice_id */
+        RemoveBits( &p_vpar->bit_stream, 8 );
+        /* extra_information_slice */
+        while( GetBits( &p_vpar->bit_stream, 1 ) )
+        {
+            RemoveBits( &p_vpar->bit_stream, 8 );
+        }
     }
 
-    if( *pi_mb_address - i_mb_previous - 1 )
-    {
-        /* Skipped macroblock (ISO/IEC 13818-2 7.6.6). */
+    /* Calculate the position of the macroblock. */
+    i_width = p_vpar->sequence.i_width;
+    i_offset = (i_vert_code - 1) * i_width * 4;
 
-        /* Reset DC predictors (7.2.1). */
-        p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1]
-            = p_vpar->mb.pi_dc_dct_pred[2]
-            = 1 << (7 + p_vpar->picture.i_intra_dc_precision);
+    /* Initialize motion context. */
+    pp_forward_ref[0] = p_vpar->sequence.p_forward;
+
+    if( i_structure != FRAME_STRUCTURE )
+    {
+        i_offset <<= 1;
+        pp_forward_ref[1] = p_vpar->sequence.p_forward;
 
-        if( i_coding_type == P_CODING_TYPE )
+        if( i_coding_type != B_CODING_TYPE && p_vpar->picture.b_second_field )
         {
-            /* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */
-            bzero8int( p_vpar->mb.pppi_pmv );
+            pp_forward_ref[!p_vpar->picture.b_current_field] =
+                p_vpar->picture.p_picture;
         }
-
-        for( i_mb = i_mb_previous + 1; i_mb < *pi_mb_address; i_mb++ )
+        if( ( i_coding_type != I_CODING_TYPE || 
+              p_vpar->picture.b_concealment_mv ) && pp_forward_ref[1] != NULL )
+        {
+            p_f_motion->pppi_ref[1][0] =
+                    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);
+            p_f_motion->pppi_ref[1][2] =
+                    pp_forward_ref[1]->p_v + i_offset + (i_width >> 1);
+        }
+        if( i_coding_type == B_CODING_TYPE )
         {
-            SkippedMacroblock( p_vpar, i_mb, i_mb_base, i_coding_type,
-                               i_structure );
+            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_b_motion->pppi_ref[1][2] =
+                p_vpar->sequence.p_backward->p_v + i_offset + (i_width >> 1);
         }
     }
 
-    /* Get a macroblock structure. */
-    if( (p_mb = vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
+    if( i_coding_type != I_CODING_TYPE || p_vpar->picture.b_concealment_mv )
     {
-        /* b_die == 1 */
-        return;
+        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->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;
+        p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0;
     }
-#ifdef VDEC_SMP
-    p_vpar->picture.pp_mb[i_mb_base + *pi_mb_address] = p_mb;
-#endif
 
-    InitMacroblock( p_vpar, p_mb, i_coding_type, i_structure );
-
-    /* Parse off macroblock_modes structure. */
-    MacroblockModes( p_vpar, p_mb, i_coding_type, i_structure );
-
-    if( p_mb->i_mb_type & MB_QUANT )
+    if( i_coding_type == B_CODING_TYPE )
     {
-        LoadQuantizerScale( 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;
+        p_b_motion->pppi_ref[0][2] = p_vpar->sequence.p_backward->p_v
+                                        + i_offset;
+        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;
+        p_b_motion->ppi_pmv[1][0] = p_b_motion->ppi_pmv[1][1] = 0;
     }
 
-    if( (i_coding_type == P_CODING_TYPE || i_coding_type == B_CODING_TYPE)
-         && (p_mb->i_mb_type & MB_MOTION_FORWARD) )
-    {
-        if( b_mpeg2 )
-            DecodeMVMPEG2( p_vpar, p_mb, 0, i_structure );
-        else
-            DecodeMVMPEG1( p_vpar, p_mb, 0, i_structure );
-        PARSEERROR
-    }
+    /* 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;
 
-    if( (i_coding_type == B_CODING_TYPE)
-         && (p_mb->i_mb_type & MB_MOTION_BACKWARD) )
+    if( i_structure == BOTTOM_FIELD )
     {
-        if( b_mpeg2 )
-            DecodeMVMPEG2( p_vpar, p_mb, 1, i_structure );
-        else
-            DecodeMVMPEG1( p_vpar, p_mb, 1, i_structure );
-        PARSEERROR
+        p_dest[0] += i_width;
+        p_dest[1] += i_width >> 1;
+        p_dest[2] += i_width >> 1;
     }
+    i_width = p_vpar->picture.i_field_width;
 
-    if( i_coding_type == P_CODING_TYPE
-         && !(p_mb->i_mb_type & (MB_MOTION_FORWARD|MB_INTRA)) )
-    {
-        /* Special No-MC macroblock in P pictures (7.6.3.5). */
-        p_mb->i_mb_type |= MB_MOTION_FORWARD;
-        bzero8int( p_vpar->mb.pppi_pmv );
-        bzero8int( p_mb->pppi_motion_vectors );
-        p_vpar->mb.i_motion_type = 1 + (i_structure == FRAME_STRUCTURE);
-        p_mb->ppi_field_select[0][0] = (i_structure == BOTTOM_FIELD);
-    }
+    /* Reset intra DC coefficients predictors (ISO/IEC 13818-2 7.2.1). */
+    p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1]
+        = p_vpar->mb.pi_dc_dct_pred[2]
+        = 1 << (7 + p_vpar->picture.i_intra_dc_precision);
 
-    if( (i_coding_type != I_CODING_TYPE) && !(p_mb->i_mb_type & MB_INTRA) )
+    p_vpar->mb.i_offset = MacroblockAddressIncrement( p_vpar ) << 4;
+
+    for( ; ; )
     {
-        /* Reset DC predictors (7.2.1). */
-        p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1]
-            = p_vpar->mb.pi_dc_dct_pred[2]
-            = 1 << (7 + p_vpar->picture.i_intra_dc_precision);
+        /* Decode macroblocks. */
+        macroblock_t *  p_mb;
+        int             i_mb_modes;
 
-        /* Motion function pointer. */
-        p_mb->pf_motion = p_vpar->pppf_motion[i_chroma_format]
-                                             [i_structure == FRAME_STRUCTURE]
-                                             [p_vpar->mb.i_motion_type];
+        /* Get a macroblock structure. */
+        p_mb = p_vpar->pool.pf_new_mb( &p_vpar->pool );
+        p_mb->i_nb_motions = 0;
+        p_mb->pp_dest[0] = p_dest[0]; 
+        p_mb->pp_dest[1] = p_dest[1]; 
+        p_mb->pp_dest[2] = p_dest[2]; 
 
-        if( p_mb->i_mb_type & MB_PATTERN )
-        {
-            switch( i_chroma_format )
-            {
-            case CHROMA_420:
-                p_mb->i_coded_block_pattern = CodedPattern420( p_vpar );
-                break;
-            case CHROMA_422:
-                p_mb->i_coded_block_pattern = CodedPattern422( p_vpar );
-                break;
-            case CHROMA_444:
-                p_mb->i_coded_block_pattern = CodedPattern444( p_vpar );
-            }
-        }
-        else
-        {
-            p_mb->i_coded_block_pattern = 0;
-        }
+        /* Parse off macroblock_modes structure. */
+        p_mb->i_mb_modes = i_mb_modes =
+                MacroblockModes( p_vpar, p_mb, i_coding_type, i_structure );
 
-        /*
-         * Effectively decode blocks.
-         */
-        if( b_mpeg2 )
-            DecodeMPEG2NonIntraMB( p_vpar, p_mb );
-        else
-            DecodeMPEG1NonIntraMB( p_vpar, p_mb );
-        PARSEERROR
-    }
-    else
-    {
-        if( !p_vpar->picture.b_concealment_mv )
+        if( i_mb_modes & MB_QUANT )
         {
-            /* Reset MV predictors. */
-            bzero8int( p_vpar->mb.pppi_pmv );
+            LoadQuantizerScale( p_vpar );
         }
-        else
+
+        if( i_mb_modes & MB_INTRA )
         {
+            if( p_vpar->picture.b_concealment_mv )
+            {
+                if( i_structure == FRAME_STRUCTURE )
+                {
+                    MotionFrameConceal( p_vpar, p_mb, p_f_motion );
+                }
+                else
+                {
+                    MotionFieldConceal( p_vpar, p_mb, p_f_motion );
+                }
+            }
+            else
+            {
+                /* Reset motion vectors predictors. */
+                p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0;
+                p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0;
+                p_b_motion->ppi_pmv[0][0] = p_b_motion->ppi_pmv[0][1] = 0;
+                p_b_motion->ppi_pmv[1][0] = p_b_motion->ppi_pmv[1][1] = 0;
+            }
+
+            /* Decode blocks */
+            p_mb->i_coded_block_pattern = (1 << 6) - 1;
             if( b_mpeg2 )
-                DecodeMVMPEG2( p_vpar, p_mb, 0, i_structure );
+            {
+                if( p_vpar->picture.b_intra_vlc_format )
+                {
+                    MPEG2IntraB15MB( p_vpar, p_mb );
+                }
+                else
+                {
+                    MPEG2IntraB14MB( p_vpar, p_mb );
+                }
+            }
             else
-                DecodeMVMPEG1( p_vpar, p_mb, 0, i_structure );
-            RemoveBits( &p_vpar->bit_stream, 1 );
-        }
+            {
+                MPEG1IntraMB( p_vpar, p_mb );
+            }
 
-        if( p_mb->i_mb_type & MB_PATTERN )
-        {
-            switch( i_chroma_format )
+            if( i_coding_type == D_CODING_TYPE )
             {
-            case CHROMA_420:
-                p_mb->i_coded_block_pattern = CodedPattern420( p_vpar );
-                break;
-            case CHROMA_422:
-                p_mb->i_coded_block_pattern = CodedPattern422( p_vpar );
-                break;
-            case CHROMA_444:
-                p_mb->i_coded_block_pattern = CodedPattern444( p_vpar );
+                RemoveBits( &p_vpar->bit_stream, 1 );
             }
         }
         else
         {
-            p_mb->i_coded_block_pattern =
-                                (1 << (4 + (1 << i_chroma_format))) - 1;
-        }
+            /* Non-intra block */
+            if( !b_mpeg2 )
+            {
+                if( (i_mb_modes & MOTION_TYPE_MASK) == MC_FRAME )
+                {
+                    MOTION( MotionMPEG1, i_mb_modes );
+                }
+                else
+                {
+                    /* Non-intra MB without forward mv in a P picture. */
+                    p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0;
+                    p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0;
+                    MOTION( MotionFrameZero, MB_MOTION_FORWARD );
+                }
+            }
+            else if( i_structure == FRAME_STRUCTURE )
+            {
+                switch( i_mb_modes & MOTION_TYPE_MASK )
+                {
+                case MC_FRAME:
+                    MOTION( MotionFrameFrame, i_mb_modes );
+                    break;
+
+                case MC_FIELD:
+                    MOTION( MotionFrameField, i_mb_modes );
+                    break;
+
+                case MC_DMV:
+                    MOTION( MotionFrameDMV, MB_MOTION_FORWARD );
+                    break;
+
+                case 0:
+                    /* Non-intra MB without forward mv in a P picture. */
+                    p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0;
+                    p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0;
+                    MOTION( MotionFrameZero, MB_MOTION_FORWARD );
+                }
+            }
+            else
+            {
+                /* Field structure. */
+                switch( i_mb_modes & MOTION_TYPE_MASK )
+                {
+                case MC_FIELD:
+                    MOTION( MotionFieldField, i_mb_modes );
+                    break;
 
-        /*
-         * Effectively decode blocks.
-         */
-        if( b_mpeg2 )
-            DecodeMPEG2IntraMB( p_vpar, p_mb );
-        else
-            DecodeMPEG1IntraMB( p_vpar, p_mb );
-        PARSEERROR
-    }
+                case MC_16X8:
+                    MOTION( MotionField16x8, i_mb_modes );
+                    break;
 
-    if( !p_vpar->picture.b_error )
-    {
-        UpdateContext( p_vpar, i_structure );
-#ifndef VDEC_SMP
-        /* Decode the macroblock NOW ! */
-        vpar_DecodeMacroblock ( &p_vpar->vfifo, p_mb );
-#endif
-    }
-    else
-    {
-        /* Go to the next slice. */
-        vpar_FreeMacroblock( &p_vpar->vfifo, p_mb );
-    }
-}
+                case MC_DMV:
+                    MOTION( MotionFieldDMV, i_mb_modes );
+                    break;
 
-#undef PARSEERROR
+                case 0:
+                    /* Non-intra MB without forward mv in a P picture. */
+                    p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0;
+                    p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0;
+                    MOTION( MotionFieldZero, MB_MOTION_FORWARD );
 
+                }
+            }
 
-/*
- * Picture data parsing management
- */
+            /* ISO/IEC 13818-2 6.3.17.4 : Coded Block Pattern */
+            if( i_mb_modes & MB_PATTERN )
+            {
+                p_mb->i_coded_block_pattern = CodedPattern( p_vpar );
+                if( b_mpeg2 )
+                {
+                    MPEG2NonIntraMB( p_vpar, p_mb );
+                }
+                else
+                {
+                    MPEG1NonIntraMB( p_vpar, p_mb );
+                }
+            }
+            else
+            {
+                p_mb->i_coded_block_pattern = 0;
+            }
 
-/*****************************************************************************
- * SliceHeader : Parse the next slice structure
- *****************************************************************************/
-static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
-                                    int * pi_mb_address, int i_mb_base,
-                                    u32 i_vert_code, boolean_t b_mpeg2,
-                                    int i_coding_type, int i_structure )
-{
-    int         i_mb_address_save = *pi_mb_address;
+            /* Reset intra DC coefficients predictors. */
+            p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1]
+                = p_vpar->mb.pi_dc_dct_pred[2]
+                = 1 << (7 + p_vpar->picture.i_intra_dc_precision);
+        }
 
-#if 0
-    /* FIXME : MP@ML doesn't support this. */
-    if( b_high )
-    {
-        /* Picture with more than 2800 lines. */
-        i_vert_code += GetBits( &p_vpar->bit_stream, 3 ) << 7;
-    }
-    if( b_dp_scalable )
-    {
-        /* DATA_PARTITIONING scalability. */
-        RemoveBits( &p_vpar->bit_stream, 7 ); /* priority_breakpoint */
-    }
-#endif
+        /* End of macroblock. */
+        PARSEERROR;
+        p_vpar->pool.pf_decode_mb( &p_vpar->pool, p_mb );
 
-    LoadQuantizerScale( p_vpar );
+        /* Prepare context for the next macroblock. */
+        p_vpar->mb.i_offset += 16;
+        CHECK_BOUNDARIES;
 
-    if( GetBits( &p_vpar->bit_stream, 1 ) )
-    {
-        /* intra_slice, slice_id */
-        RemoveBits( &p_vpar->bit_stream, 8 );
-        /* extra_information_slice */
-        while( GetBits( &p_vpar->bit_stream, 1 ) )
+        if( ShowBits( &p_vpar->bit_stream, 1 ) )
         {
-            RemoveBits( &p_vpar->bit_stream, 8 );
+            /* Macroblock Address Increment == 1 */
+            RemoveBits( &p_vpar->bit_stream, 1 );
         }
-    }
-    *pi_mb_address = (i_vert_code - 1) * p_vpar->sequence.i_mb_width;
-
-    if( *pi_mb_address < i_mb_address_save )
-    {
-        intf_WarnMsg( 2, "Slices do not follow" );
-        p_vpar->picture.b_error = 1;
-        return;
-    }
-
-    /* Reset DC coefficients predictors (ISO/IEC 13818-2 7.2.1). */
-    p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1]
-        = p_vpar->mb.pi_dc_dct_pred[2]
-        = 1 << (7 + p_vpar->picture.i_intra_dc_precision);
+        else
+        {
+            /* Check for skipped macroblock(s). */
+            int i_mba_inc;
 
-    /* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */
-    bzero8int( p_vpar->mb.pppi_pmv );
+            i_mba_inc = MacroblockAddressIncrement( p_vpar );
+            if( !i_mba_inc )
+            {
+                /* End of slice. */
+                break;
+            }
 
-    do
-    {
-        ParseMacroblock( p_vpar, pi_mb_address, i_mb_address_save,
-                         i_mb_base, b_mpeg2, i_coding_type, i_structure );
+            /* Reset intra DC predictors. */
+            p_vpar->mb.pi_dc_dct_pred[0] = p_vpar->mb.pi_dc_dct_pred[1]
+                = p_vpar->mb.pi_dc_dct_pred[2]
+                = 1 << (7 + p_vpar->picture.i_intra_dc_precision);
 
-        i_mb_address_save = *pi_mb_address;
-        if( p_vpar->picture.b_error )
-        {
-            return;
+            if( i_coding_type == P_CODING_TYPE )
+            {
+                p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0;
+                p_f_motion->ppi_pmv[1][0] = p_f_motion->ppi_pmv[1][1] = 0;
+
+                do {
+                    p_mb = p_vpar->pool.pf_new_mb( &p_vpar->pool );
+                    p_mb->i_mb_modes = 0;
+                    p_mb->i_nb_motions = 0;
+                    p_mb->i_coded_block_pattern = 0;
+                    p_mb->pp_dest[0] = p_dest[0]; 
+                    p_mb->pp_dest[1] = p_dest[1]; 
+                    p_mb->pp_dest[2] = p_dest[2]; 
+
+                    if( i_structure == FRAME_STRUCTURE )
+                    {
+                        MOTION( MotionFrameZero, MB_MOTION_FORWARD );
+                    }
+                    else
+                    {
+                        MOTION( MotionFieldZero, MB_MOTION_FORWARD );
+                    }
+
+                    p_vpar->pool.pf_decode_mb( &p_vpar->pool, p_mb );
+                    p_vpar->mb.i_offset += 16;
+                    CHECK_BOUNDARIES;
+                } while( --i_mba_inc );
+            }
+            else
+            {
+                do {
+                    p_mb = p_vpar->pool.pf_new_mb( &p_vpar->pool );
+                    p_mb->i_mb_modes = 0;
+                    p_mb->i_nb_motions = 0;
+                    p_mb->i_coded_block_pattern = 0;
+                    p_mb->pp_dest[0] = p_dest[0]; 
+                    p_mb->pp_dest[1] = p_dest[1]; 
+                    p_mb->pp_dest[2] = p_dest[2]; 
+
+                    if( !b_mpeg2 )
+                    {
+                        MOTION( MotionMPEG1Reuse, i_mb_modes );
+                    }
+                    else if( i_structure == FRAME_STRUCTURE )
+                    {
+                        MOTION( MotionFrameReuse, i_mb_modes );
+                    }
+                    else
+                    {
+                        MOTION( MotionFieldReuse, i_mb_modes );
+                    }
+
+                    p_vpar->pool.pf_decode_mb( &p_vpar->pool, p_mb );
+                    p_vpar->mb.i_offset += 16;
+                    CHECK_BOUNDARIES;
+                } while( --i_mba_inc );
+            }
         }
     }
-    while( ShowBits( &p_vpar->bit_stream, 23 ) && !p_vpar->p_fifo->b_die );
+
     NextStartCode( &p_vpar->bit_stream );
 }
 
@@ -2060,69 +2132,32 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
  * PictureData : Parse off all macroblocks (ISO/IEC 13818-2 6.2.3.7)
  *****************************************************************************/
 static __inline__ void vpar_PictureData( vpar_thread_t * p_vpar,
-                                         int i_mb_base, boolean_t b_mpeg2,
+                                         boolean_t b_mpeg2,
                                          int i_coding_type, int i_structure )
 {
-    int         i_mb_address = 0;
     u32         i_dummy;
 
     NextStartCode( &p_vpar->bit_stream );
-    while( ((i_coding_type != I_CODING_TYPE && i_coding_type != D_CODING_TYPE)
-             || !p_vpar->picture.b_error)
-           && i_mb_address < (p_vpar->sequence.i_mb_size
-                                >> (i_structure != FRAME_STRUCTURE))
-           && !p_vpar->picture.b_error
-           && !p_vpar->p_fifo->b_die )
+    while( !p_vpar->picture.b_error && !p_vpar->p_fifo->b_die )
     {
         if( ((i_dummy = ShowBits( &p_vpar->bit_stream, 32 ))
                  < SLICE_START_CODE_MIN) ||
             (i_dummy > SLICE_START_CODE_MAX) )
         {
-            intf_WarnMsg( 2, "Premature end of picture" );
-            p_vpar->picture.b_error = 1;
             break;
         }
         RemoveBits32( &p_vpar->bit_stream );
 
         /* Decode slice data. */
-        SliceHeader( p_vpar, &i_mb_address, i_mb_base, i_dummy & 255,
-                     b_mpeg2, i_coding_type, i_structure );
+        ParseSlice( p_vpar, i_dummy & 255, b_mpeg2, i_coding_type,
+                    i_structure );
     }
-
-#if 0
-    /* Buggy */
-    /* Try to recover from error. If we missed less than half the
-     * number of macroblocks of the picture, mark the missed ones
-     * as skipped. */
-    if( (i_coding_type == P_CODING_TYPE || i_coding_type == B_CODING_TYPE)
-        && !p_vpar->sequence.b_expect_discontinuity
-        && p_vpar->picture.b_error &&
-        ( (i_mb_address-i_mb_base) > (p_vpar->sequence.i_mb_size >> 1)
-           || (i_structure != FRAME_STRUCTURE
-               && (i_mb_address-i_mb_base) >
-                         (p_vpar->sequence.i_mb_size >> 2) ) ) )
-    {
-        int         i_mb;
-
-        p_vpar->picture.b_error = 0;
-        for( i_mb = i_mb_address + 1;
-             i_mb < (p_vpar->sequence.i_mb_size
-                     << (i_structure != FRAME_STRUCTURE));
-             i_mb++ )
-        {
-            SkippedMacroblock( p_vpar, i_mb, i_mb_base,
-                               i_coding_type,
-                               i_structure );
-        }
-    }
-#endif
 }
 
 #define DECLARE_PICD( FUNCNAME, B_MPEG2, I_CODING_TYPE, I_STRUCTURE )       \
-void FUNCNAME( vpar_thread_t * p_vpar, int i_mb_base )                      \
+void FUNCNAME( vpar_thread_t * p_vpar )                                     \
 {                                                                           \
-    vpar_PictureData( p_vpar, i_mb_base, B_MPEG2, I_CODING_TYPE,            \
-                      I_STRUCTURE );                                        \
+    vpar_PictureData( p_vpar, B_MPEG2, I_CODING_TYPE, I_STRUCTURE );        \
 }
 
 DECLARE_PICD( vpar_PictureDataGENERIC, p_vpar->sequence.b_mpeg2,
@@ -2145,3 +2180,5 @@ DECLARE_PICD( vpar_PictureData2PB, 1, P_CODING_TYPE, BOTTOM_FIELD );
 DECLARE_PICD( vpar_PictureData2BB, 1, B_CODING_TYPE, BOTTOM_FIELD );
 #endif
 
+#undef DECLARE_PICD
+