* vpar_blocks.c : blocks parsing
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_blocks.c,v 1.5 2001/07/27 09:17:38 massiot Exp $
+ * $Id: vpar_blocks.c,v 1.6 2001/08/22 17:21:45 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 "vpar_pool.h"
#include "video_parser.h"
+#include "vpar_blocks.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 )
+ {
+ 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
{
- 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, 3 );
+ return 0;
}
- (*pi_value)--;
}
-}
-
-/* Function that initialize the table using the last one */
-void vpar_InitMbAddrInc( vpar_thread_t * p_vpar )
-{
- int i_dummy;
- int i_value;
-
- for( i_dummy = 0 ; i_dummy < 8 ; 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 - 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 );
}
+}
- p_vpar->pl_mb_addr_inc[8].i_value = MB_ADDRINC_ESCAPE;
- p_vpar->pl_mb_addr_inc[8].i_length = 11;
+/*****************************************************************************
+ * GetChromaDCDiff : Get the chrominance DC coefficient difference
+ *****************************************************************************/
+static __inline__ int GetChromaDCDiff( vpar_thread_t * p_vpar )
+{
+ lookup_t * p_tab;
+ int i_size, i_dc_diff, i_code;
- for( i_dummy = 9 ; i_dummy < 15 ; 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[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++ )
+ 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 );
}
+}
- 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 );
-}
+#define SATURATE(val) \
+ if( val > 2047 ) \
+ val = 2047; \
+ else if( val < -2048 ) \
+ val = -2048;
/*****************************************************************************
- * 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;
+ p_idct->i_sparse_pos = 63;
+ }
+ else
+ {
+ p_idct->pf_idct = p_vpar->pf_idct;
+ }
+ }
+ else
+ {
+ p_idct->pf_idct = p_vpar->pf_sparse_idct;
+ p_idct->i_sparse_pos = i_coeff - p_tab->i_run;
+ }
+ }
+ else
+ {
+ p_idct->pf_idct = p_vpar->pf_idct;
}
}
-
-/*
- * 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;
- for( i_parse = 0; !p_vpar->p_fifo->b_die; i_parse++ )
+ i_coeff = 0;
+ i_mismatch = ~p_dest[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, 8 )) >= 0x4 )
{
- 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;
+ p_idct->i_sparse_pos = 63;
+ }
+ else
+ {
+ p_idct->pf_idct = p_vpar->pf_idct;
+ }
+ }
+ else
+ {
+ p_idct->pf_idct = p_vpar->pf_sparse_idct;
+ p_idct->i_sparse_pos = i_coeff - p_tab->i_run;
+ }
+ }
+ else
+ {
+ p_idct->pf_idct = p_vpar->pf_idct;
}
-
- 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;
+ p_idct->i_sparse_pos = 63;
+ }
+ else
+ {
+ p_idct->pf_idct = p_vpar->pf_idct;
+ }
+ }
+ else
+ {
+ p_idct->pf_idct = p_vpar->pf_sparse_idct;
+ 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;
}
+}
+
+/*****************************************************************************
+ * 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;
+ }
+
+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;
+
+ /* Oddification */
+ i_value = (i_value - 1) | 1;
- RemoveBits( &p_vpar->bit_stream, i_length );
+ i_sign = GetSignedBits( &p_vpar->bit_stream, 1 );
+ /* if (i_sign) i_value = -i_value; */
+ i_value = (i_value ^ i_sign) - i_sign;
- switch( i_run )
+ 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;
+ }
- if( i_parse >= 64 )
+ i_value = (i_value * i_q_scale * pi_quant[i_pos]) / 16;
+
+ /* Oddification */
+ i_value = (i_value + ~ShowSignedBits( &p_vpar->bit_stream, 1 )) | 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 )
{
- 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;
+ 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;
}
+}
+
+/*****************************************************************************
+ * 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 = 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 = &ppl_dct_tab1[b_vlc_intra][(i_code>>(12-(4*b_vlc_intra)))-4];
+ 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;
+ }
- switch( i_run )
- {
- 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;
+ RemoveBits( &p_vpar->bit_stream, 2 ); /* End of Block */
- break;
- default:
- b_sign = GetBits( &p_vpar->bit_stream, 1 );
+ if( i_nc <= 1 )
+ {
+ p_idct->pf_idct = p_vpar->pf_sparse_idct;
+ if( i_nc == 0 )
+ {
+ 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;
+ }
}
+#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
/*
*/
/****************************************************************************
- * 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];
-
- 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];
+ dmv_lookup_t * p_tab;
- 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). */
- /* FIXME */
- //intf_Msg( "Your stream uses Dual Prime Arithmetic. Please send a mail"
- // " to massiot@via.ecp.fr for debugging purposes. Thank you." );
-
-#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] );
+ /* I have no idea why this is commented out, since walken doesn't put
+ * comments in its code. --Meuuh */
+ /* 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 );
-
- /* 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 );
- }
+ int i_offset = p_vpar->mb.i_offset;
+ int i_width = p_vpar->picture.i_field_width;
- /* 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 );
-
- RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length );
+ 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;
- /* 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;
+
+ 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;
- RemoveBits( &p_vpar->bit_stream, pl_coded_pattern[i_vlc].i_length );
+ 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;
- return pl_coded_pattern[i_vlc].i_value |
- (GetBits( &p_vpar->bit_stream, 6 ) << 6);
+ /* 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;
- }
-
- p_mb = p_vpar->pool.pf_new_mb( &p_vpar->pool );
+ 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;
- InitMacroblock( p_vpar, p_mb, i_coding_type, i_structure );
+ default:
+ /* End of slice, or error */
+ return 0;
+ }
+ }
+}
- /* 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 );
-
- /* Decode the macroblock NOW ! */
- p_vpar->pool.pf_decode_mb( &p_vpar->pool, p_mb );
}
/*****************************************************************************
* 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. */ \
- p_vpar->pool.pf_free_mb( &p_vpar->pool, 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 ); \
+ }
+
+#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 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) */
+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];
+
+ motion_t * p_f_motion = &p_vpar->mb.f_motion;
+ motion_t * p_b_motion = &p_vpar->mb.b_motion;
- i_inc = MacroblockAddressIncrement( p_vpar );
- *pi_mb_address += i_inc;
+ /* 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;
+
+ /* Initialize motion context. */
+ pp_forward_ref[0] = p_vpar->sequence.p_forward;
- /* 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);
+ 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 )
{
- SkippedMacroblock( p_vpar, i_mb, i_mb_base, i_coding_type,
- i_structure );
+ 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 )
+ {
+ 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. */
- p_mb = p_vpar->pool.pf_new_mb( &p_vpar->pool );
-
- 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 != I_CODING_TYPE || p_vpar->picture.b_concealment_mv )
{
- LoadQuantizerScale( p_vpar );
+ 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;
}
- if( (i_coding_type == P_CODING_TYPE || i_coding_type == B_CODING_TYPE)
- && (p_mb->i_mb_type & MB_MOTION_FORWARD) )
+ if( i_coding_type == B_CODING_TYPE )
{
- if( b_mpeg2 )
- DecodeMVMPEG2( p_vpar, p_mb, 0, i_structure );
- else
- DecodeMVMPEG1( p_vpar, p_mb, 0, i_structure );
- PARSEERROR
+ 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 == B_CODING_TYPE)
- && (p_mb->i_mb_type & MB_MOTION_BACKWARD) )
- {
- if( b_mpeg2 )
- DecodeMVMPEG2( p_vpar, p_mb, 1, i_structure );
- else
- DecodeMVMPEG1( p_vpar, p_mb, 1, 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 == P_CODING_TYPE
- && !(p_mb->i_mb_type & (MB_MOTION_FORWARD|MB_INTRA)) )
+ if( i_structure == BOTTOM_FIELD )
{
- /* 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);
+ 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;
+
+ /* 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( b_mpeg2 )
- DecodeMVMPEG2( p_vpar, p_mb, 0, i_structure );
+ 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
- DecodeMVMPEG1( p_vpar, p_mb, 0, i_structure );
- RemoveBits( &p_vpar->bit_stream, 1 );
- }
+ {
+ /* 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;
+ }
- if( p_mb->i_mb_type & MB_PATTERN )
- {
- switch( i_chroma_format )
+ /* Decode blocks */
+ p_mb->i_coded_block_pattern = (1 << 6) - 1;
+ if( b_mpeg2 )
{
- 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 );
+ if( p_vpar->picture.b_intra_vlc_format )
+ {
+ MPEG2IntraB15MB( p_vpar, p_mb );
+ }
+ else
+ {
+ MPEG2IntraB14MB( p_vpar, p_mb );
+ }
+ }
+ else
+ {
+ MPEG1IntraMB( p_vpar, p_mb );
}
- }
- else
- {
- p_mb->i_coded_block_pattern =
- (1 << (4 + (1 << i_chroma_format))) - 1;
- }
- /*
- * Effectively decode blocks.
- */
- if( b_mpeg2 )
- {
- DecodeMPEG2IntraMB( p_vpar, p_mb );
+ if( i_coding_type == D_CODING_TYPE )
+ {
+ RemoveBits( &p_vpar->bit_stream, 1 );
+ }
}
else
{
- DecodeMPEG1IntraMB( p_vpar, p_mb );
- }
- PARSEERROR
- }
+ /* 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;
- if( !p_vpar->picture.b_error )
- {
- UpdateContext( p_vpar, i_structure );
+ case MC_16X8:
+ MOTION( MotionField16x8, i_mb_modes );
+ break;
- /* Decode the macroblock NOW ! */
- p_vpar->pool.pf_decode_mb( &p_vpar->pool, p_mb );
- }
- else
- {
- /* Go to the next slice. */
- p_vpar->pool.pf_free_mb( &p_vpar->pool, 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 );
}
* 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,
DECLARE_PICD( vpar_PictureData2BB, 1, B_CODING_TYPE, BOTTOM_FIELD );
#endif
+#undef DECLARE_PICD
+