[Mesa-dev] [PATCH 7/7] g3dvl: Rewrite the mpeg 1&2 bitstream parser
deathsimple at vodafone.de
deathsimple at vodafone.de
Wed Aug 24 14:51:52 PDT 2011
From: Christian König <deathsimple at vodafone.de>
Based on work of Maarten Lankhorst this time.
---
src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c | 2442 ++++++++----------------
src/gallium/auxiliary/vl/vl_mpeg12_bitstream.h | 23 +-
src/gallium/auxiliary/vl/vl_mpeg12_decoder.c | 8 +-
src/gallium/auxiliary/vl/vl_vlc.h | 201 ++-
src/gallium/include/pipe/p_video_state.h | 11 +
5 files changed, 934 insertions(+), 1751 deletions(-)
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
index bc88929..ef00e2d 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
@@ -1,6 +1,7 @@
/**************************************************************************
*
- * Copyright 2011 Christian König.
+ * Copyright 2011 Maarten Lankhorst
+ * Copyright 2011 Christian König
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,1817 +26,966 @@
*
**************************************************************************/
-/**
- * This file is based uppon slice_xvmc.c and vlc.h from the xine project,
- * which in turn is based on mpeg2dec. The following is the original copyright:
- *
- * Copyright (C) 2000-2002 Michel Lespinasse <walken at zoy.org>
- * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma at ess.engr.uvic.ca>
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <stdint.h>
-
-#include <pipe/p_compiler.h>
-#include <pipe/p_video_state.h>
+#include <pipe/p_video_decoder.h>
+#include <util/u_memory.h>
#include "vl_vlc.h"
#include "vl_mpeg12_bitstream.h"
-/* take num bits from the high part of bit_buf and zero extend them */
-#define UBITS(buf,num) (((uint32_t)(buf)) >> (32 - (num)))
-
-/* take num bits from the high part of bit_buf and sign extend them */
-#define SBITS(buf,num) (((int32_t)(buf)) >> (32 - (num)))
-
-/* macroblock modes */
-#define MACROBLOCK_INTRA 1
-#define MACROBLOCK_PATTERN 2
-#define MACROBLOCK_MOTION_BACKWARD 4
-#define MACROBLOCK_MOTION_FORWARD 8
-#define MACROBLOCK_QUANT 16
-
-/* motion_type */
-#define MOTION_TYPE_MASK (3*64)
-#define MOTION_TYPE_BASE 64
-#define MC_FIELD (1*64)
-#define MC_FRAME (2*64)
-#define MC_16X8 (2*64)
-#define MC_DMV (3*64)
-
-/* picture structure */
-#define TOP_FIELD 1
-#define BOTTOM_FIELD 2
-#define FRAME_PICTURE 3
-
-/* picture coding type (mpeg2 header) */
-#define I_TYPE 1
-#define P_TYPE 2
-#define B_TYPE 3
-#define D_TYPE 4
-
-typedef struct {
- uint8_t modes;
- uint8_t len;
-} MBtab;
-
-typedef struct {
- uint8_t delta;
- uint8_t len;
-} MVtab;
-
-typedef struct {
- int8_t dmv;
- uint8_t len;
-} DMVtab;
-
-typedef struct {
- uint8_t cbp;
- uint8_t len;
-} CBPtab;
-
-typedef struct {
- uint8_t size;
- uint8_t len;
-} DCtab;
-
-typedef struct {
- uint8_t run;
- uint8_t level;
- uint8_t len;
-} DCTtab;
-
-typedef struct {
- uint8_t mba;
- uint8_t len;
-} MBAtab;
-
-#define INTRA MACROBLOCK_INTRA
-#define QUANT MACROBLOCK_QUANT
-#define MC MACROBLOCK_MOTION_FORWARD
-#define CODED MACROBLOCK_PATTERN
-#define FWD MACROBLOCK_MOTION_FORWARD
-#define BWD MACROBLOCK_MOTION_BACKWARD
-#define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD
-
-static const MBtab MB_I [] = {
- {INTRA|QUANT, 2}, {INTRA, 1}
-};
-
-static const MBtab MB_P [] = {
- {INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5},
- {MC, 3}, {MC, 3}, {MC, 3}, {MC, 3},
- {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
- {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
- {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
- {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
- {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
- {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}
-};
-
-static const MBtab MB_B [] = {
- {0, 0}, {INTRA|QUANT, 6},
- {BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6},
- {INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5},
- {INTRA, 5}, {INTRA, 5},
- {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4},
- {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4},
- {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
- {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
- {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
- {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
- {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
- {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
- {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
- {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
- {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
- {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
- {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
- {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}
-};
-
-#undef INTRA
-#undef QUANT
-#undef MC
-#undef CODED
-#undef FWD
-#undef BWD
-#undef INTER
-
-static const MVtab MV_4 [] = {
- { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2}
-};
-
-static const MVtab MV_10 [] = {
- { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10},
- { 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10},
- {11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9},
- { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7},
- { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7},
- { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}
-};
-
-static const DMVtab DMV_2 [] = {
- { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2}
-};
-
-static const CBPtab CBP_7 [] = {
- {0x22, 7}, {0x12, 7}, {0x0a, 7}, {0x06, 7},
- {0x21, 7}, {0x11, 7}, {0x09, 7}, {0x05, 7},
- {0x3f, 6}, {0x3f, 6}, {0x03, 6}, {0x03, 6},
- {0x24, 6}, {0x24, 6}, {0x18, 6}, {0x18, 6},
- {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, {0x3e, 5},
- {0x02, 5}, {0x02, 5}, {0x02, 5}, {0x02, 5},
- {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, {0x3d, 5},
- {0x01, 5}, {0x01, 5}, {0x01, 5}, {0x01, 5},
- {0x38, 5}, {0x38, 5}, {0x38, 5}, {0x38, 5},
- {0x34, 5}, {0x34, 5}, {0x34, 5}, {0x34, 5},
- {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, {0x2c, 5},
- {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, {0x1c, 5},
- {0x28, 5}, {0x28, 5}, {0x28, 5}, {0x28, 5},
- {0x14, 5}, {0x14, 5}, {0x14, 5}, {0x14, 5},
- {0x30, 5}, {0x30, 5}, {0x30, 5}, {0x30, 5},
- {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5},
- {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4},
- {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4},
- {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4},
- {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4},
- {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
- {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
- {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
- {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
- {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3},
- {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3},
- {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3},
- {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}
-};
-
-static const CBPtab CBP_9 [] = {
- {0, 0}, {0x00, 9}, {0x27, 9}, {0x1b, 9},
- {0x3b, 9}, {0x37, 9}, {0x2f, 9}, {0x1f, 9},
- {0x3a, 8}, {0x3a, 8}, {0x36, 8}, {0x36, 8},
- {0x2e, 8}, {0x2e, 8}, {0x1e, 8}, {0x1e, 8},
- {0x39, 8}, {0x39, 8}, {0x35, 8}, {0x35, 8},
- {0x2d, 8}, {0x2d, 8}, {0x1d, 8}, {0x1d, 8},
- {0x26, 8}, {0x26, 8}, {0x1a, 8}, {0x1a, 8},
- {0x25, 8}, {0x25, 8}, {0x19, 8}, {0x19, 8},
- {0x2b, 8}, {0x2b, 8}, {0x17, 8}, {0x17, 8},
- {0x33, 8}, {0x33, 8}, {0x0f, 8}, {0x0f, 8},
- {0x2a, 8}, {0x2a, 8}, {0x16, 8}, {0x16, 8},
- {0x32, 8}, {0x32, 8}, {0x0e, 8}, {0x0e, 8},
- {0x29, 8}, {0x29, 8}, {0x15, 8}, {0x15, 8},
- {0x31, 8}, {0x31, 8}, {0x0d, 8}, {0x0d, 8},
- {0x23, 8}, {0x23, 8}, {0x13, 8}, {0x13, 8},
- {0x0b, 8}, {0x0b, 8}, {0x07, 8}, {0x07, 8}
+enum {
+ dct_End_of_Block = 0xFF,
+ dct_Escape = 0xFE,
+ dct_DC = 0xFD,
+ dct_AC = 0xFC
};
-static const DCtab DC_lum_5 [] = {
- {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}
+struct dct_coeff
+{
+ uint8_t length;
+ uint8_t run;
+ int16_t level;
};
-static const DCtab DC_chrom_5 [] = {
- {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}
+struct dct_coeff_compressed
+{
+ uint32_t bitcode;
+ struct dct_coeff coeff;
};
-static const DCtab DC_long [] = {
- {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
- {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
- {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}
+/* coding table as found in the spec annex B.5 table B-1 */
+static const struct vl_vlc_compressed macroblock_address_increment[] = {
+ { 0x8000, { 1, 1 } },
+ { 0x6000, { 3, 2 } },
+ { 0x4000, { 3, 3 } },
+ { 0x3000, { 4, 4 } },
+ { 0x2000, { 4, 5 } },
+ { 0x1800, { 5, 6 } },
+ { 0x1000, { 5, 7 } },
+ { 0x0e00, { 7, 8 } },
+ { 0x0c00, { 7, 9 } },
+ { 0x0b00, { 8, 10 } },
+ { 0x0a00, { 8, 11 } },
+ { 0x0900, { 8, 12 } },
+ { 0x0800, { 8, 13 } },
+ { 0x0700, { 8, 14 } },
+ { 0x0600, { 8, 15 } },
+ { 0x05c0, { 10, 16 } },
+ { 0x0580, { 10, 17 } },
+ { 0x0540, { 10, 18 } },
+ { 0x0500, { 10, 19 } },
+ { 0x04c0, { 10, 20 } },
+ { 0x0480, { 10, 21 } },
+ { 0x0460, { 11, 22 } },
+ { 0x0440, { 11, 23 } },
+ { 0x0420, { 11, 24 } },
+ { 0x0400, { 11, 25 } },
+ { 0x03e0, { 11, 26 } },
+ { 0x03c0, { 11, 27 } },
+ { 0x03a0, { 11, 28 } },
+ { 0x0380, { 11, 29 } },
+ { 0x0360, { 11, 30 } },
+ { 0x0340, { 11, 31 } },
+ { 0x0320, { 11, 32 } },
+ { 0x0300, { 11, 33 } }
};
-static const DCTtab DCT_16 [] = {
- {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
- {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
- {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
- {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
- { 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0},
- { 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0},
- { 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0},
- { 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0}
-};
+#define Q PIPE_MPEG12_MB_TYPE_QUANT
+#define F PIPE_MPEG12_MB_TYPE_MOTION_FORWARD
+#define B PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD
+#define P PIPE_MPEG12_MB_TYPE_PATTERN
+#define I PIPE_MPEG12_MB_TYPE_INTRA
-static const DCTtab DCT_15 [] = {
- { 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15},
- { 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15},
- { 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15},
- { 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15},
- { 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14},
- { 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14},
- { 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14},
- { 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14},
- { 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14},
- { 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14},
- { 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14},
- { 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14}
+/* coding table as found in the spec annex B.5 table B-2 */
+static const struct vl_vlc_compressed macroblock_type_i[] = {
+ { 0x8000, { 1, I } },
+ { 0x4000, { 2, Q|I } }
};
-static const DCTtab DCT_13 [] = {
- { 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13},
- { 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13},
- { 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13},
- { 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13},
- { 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12},
- { 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12},
- { 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12},
- { 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12},
- { 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12},
- { 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12},
- { 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12},
- { 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12}
+/* coding table as found in the spec annex B.5 table B-3 */
+static const struct vl_vlc_compressed macroblock_type_p[] = {
+ { 0x8000, { 1, F|P } },
+ { 0x4000, { 2, P } },
+ { 0x2000, { 3, F } },
+ { 0x1800, { 5, I } },
+ { 0x1000, { 5, Q|F|P } },
+ { 0x0800, { 5, Q|P } },
+ { 0x0400, { 6, Q|I } }
};
-static const DCTtab DCT_B14_10 [] = {
- { 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10},
- { 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10}
+/* coding table as found in the spec annex B.5 table B-4 */
+static const struct vl_vlc_compressed macroblock_type_b[] = {
+ { 0x8000, { 2, F|B } },
+ { 0xC000, { 2, F|B|P } },
+ { 0x4000, { 3, B } },
+ { 0x6000, { 3, B|P } },
+ { 0x2000, { 4, F } },
+ { 0x3000, { 4, F|P } },
+ { 0x1800, { 5, I } },
+ { 0x1000, { 5, Q|F|B|P } },
+ { 0x0C00, { 6, Q|F|P } },
+ { 0x0800, { 6, Q|B|P } },
+ { 0x0400, { 6, Q|I } }
};
-static const DCTtab DCT_B14_8 [] = {
- { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6},
- { 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7},
- { 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7},
- { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6},
- { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6},
- { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6},
- { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
- { 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8},
- { 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8}
+#undef Q
+#undef F
+#undef B
+#undef P
+#undef I
+
+/* coding table as found in the spec annex B.5 table B-9 */
+static const struct vl_vlc_compressed coded_block_pattern[] = {
+ { 0xE000, { 3, 60 } },
+ { 0xD000, { 4, 4 } },
+ { 0xC000, { 4, 8 } },
+ { 0xB000, { 4, 16 } },
+ { 0xA000, { 4, 32 } },
+ { 0x9800, { 5, 12 } },
+ { 0x9000, { 5, 48 } },
+ { 0x8800, { 5, 20 } },
+ { 0x8000, { 5, 40 } },
+ { 0x7800, { 5, 28 } },
+ { 0x7000, { 5, 44 } },
+ { 0x6800, { 5, 52 } },
+ { 0x6000, { 5, 56 } },
+ { 0x5800, { 5, 1 } },
+ { 0x5000, { 5, 61 } },
+ { 0x4800, { 5, 2 } },
+ { 0x4000, { 5, 62 } },
+ { 0x3C00, { 6, 24 } },
+ { 0x3800, { 6, 36 } },
+ { 0x3400, { 6, 3 } },
+ { 0x3000, { 6, 63 } },
+ { 0x2E00, { 7, 5 } },
+ { 0x2C00, { 7, 9 } },
+ { 0x2A00, { 7, 17 } },
+ { 0x2800, { 7, 33 } },
+ { 0x2600, { 7, 6 } },
+ { 0x2400, { 7, 10 } },
+ { 0x2200, { 7, 18 } },
+ { 0x2000, { 7, 34 } },
+ { 0x1F00, { 8, 7 } },
+ { 0x1E00, { 8, 11 } },
+ { 0x1D00, { 8, 19 } },
+ { 0x1C00, { 8, 35 } },
+ { 0x1B00, { 8, 13 } },
+ { 0x1A00, { 8, 49 } },
+ { 0x1900, { 8, 21 } },
+ { 0x1800, { 8, 41 } },
+ { 0x1700, { 8, 14 } },
+ { 0x1600, { 8, 50 } },
+ { 0x1500, { 8, 22 } },
+ { 0x1400, { 8, 42 } },
+ { 0x1300, { 8, 15 } },
+ { 0x1200, { 8, 51 } },
+ { 0x1100, { 8, 23 } },
+ { 0x1000, { 8, 43 } },
+ { 0x0F00, { 8, 25 } },
+ { 0x0E00, { 8, 37 } },
+ { 0x0D00, { 8, 26 } },
+ { 0x0C00, { 8, 38 } },
+ { 0x0B00, { 8, 29 } },
+ { 0x0A00, { 8, 45 } },
+ { 0x0900, { 8, 53 } },
+ { 0x0800, { 8, 57 } },
+ { 0x0700, { 8, 30 } },
+ { 0x0600, { 8, 46 } },
+ { 0x0500, { 8, 54 } },
+ { 0x0400, { 8, 58 } },
+ { 0x0380, { 9, 31 } },
+ { 0x0300, { 9, 47 } },
+ { 0x0280, { 9, 55 } },
+ { 0x0200, { 9, 59 } },
+ { 0x0180, { 9, 27 } },
+ { 0x0100, { 9, 39 } },
+ { 0x0080, { 9, 0 } }
};
-static const DCTtab DCT_B14AC_5 [] = {
- { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
- { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
- {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}
+/* coding table as found in the spec annex B.5 table B-10 */
+static const struct vl_vlc_compressed motion_code[] = {
+ { 0x0320, { 11, -16 } },
+ { 0x0360, { 11, -15 } },
+ { 0x03a0, { 11, -14 } },
+ { 0x03e0, { 11, -13 } },
+ { 0x0420, { 11, -12 } },
+ { 0x0460, { 11, -11 } },
+ { 0x04c0, { 10, -10 } },
+ { 0x0540, { 10, -9 } },
+ { 0x05c0, { 10, -8 } },
+ { 0x0700, { 8, -7 } },
+ { 0x0900, { 8, -6 } },
+ { 0x0b00, { 8, -5 } },
+ { 0x0e00, { 7, -4 } },
+ { 0x1800, { 5, -3 } },
+ { 0x3000, { 4, -2 } },
+ { 0x6000, { 3, -1 } },
+ { 0x8000, { 1, 0 } },
+ { 0x4000, { 3, 1 } },
+ { 0x2000, { 4, 2 } },
+ { 0x1000, { 5, 3 } },
+ { 0x0c00, { 7, 4 } },
+ { 0x0a00, { 8, 5 } },
+ { 0x0800, { 8, 6 } },
+ { 0x0600, { 8, 7 } },
+ { 0x0580, { 10, 8 } },
+ { 0x0500, { 10, 9 } },
+ { 0x0480, { 10, 10 } },
+ { 0x0440, { 11, 11 } },
+ { 0x0400, { 11, 12 } },
+ { 0x03c0, { 11, 13 } },
+ { 0x0380, { 11, 14 } },
+ { 0x0340, { 11, 15 } },
+ { 0x0300, { 11, 16 } }
};
-static const DCTtab DCT_B14DC_5 [] = {
- { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
- { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
- { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
- { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
- { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}
+/* coding table as found in the spec annex B.5 table B-11 */
+static const struct vl_vlc_compressed dmvector[] = {
+ { 0x0000, { 1, 0 } },
+ { 0x8000, { 2, 1 } },
+ { 0xc000, { 2, -1 } }
};
-static const DCTtab DCT_B15_10 [] = {
- { 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9},
- { 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9}
+/* coding table as found in the spec annex B.5 table B-12 */
+static const struct vl_vlc_compressed dct_dc_size_luminance[] = {
+ { 0x8000, { 3, 0 } },
+ { 0x0000, { 2, 1 } },
+ { 0x4000, { 2, 2 } },
+ { 0xA000, { 3, 3 } },
+ { 0xC000, { 3, 4 } },
+ { 0xE000, { 4, 5 } },
+ { 0xF000, { 5, 6 } },
+ { 0xF800, { 6, 7 } },
+ { 0xFC00, { 7, 8 } },
+ { 0xFE00, { 8, 9 } },
+ { 0xFF00, { 9, 10 } },
+ { 0xFF80, { 9, 11 } }
};
-static const DCTtab DCT_B15_8 [] = {
- { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6},
- { 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7},
- { 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7},
- { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6},
- { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6},
- { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6},
- { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
- { 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8},
- { 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8},
- { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
- { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
- { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
- { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 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},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
- {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
- {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
- {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
- {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
- { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
- { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
- { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
- { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
- { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
- { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
- { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
- { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
- { 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7},
- { 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7},
- { 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8},
- { 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8}
+/* coding table as found in the spec annex B.5 table B-13 */
+static const struct vl_vlc_compressed dct_dc_size_chrominance[] = {
+ { 0x0000, { 2, 0 } },
+ { 0x4000, { 2, 1 } },
+ { 0x8000, { 2, 2 } },
+ { 0xC000, { 3, 3 } },
+ { 0xE000, { 4, 4 } },
+ { 0xF000, { 5, 5 } },
+ { 0xF800, { 6, 6 } },
+ { 0xFC00, { 7, 7 } },
+ { 0xFE00, { 8, 8 } },
+ { 0xFF00, { 9, 9 } },
+ { 0xFF80, { 10, 10 } },
+ { 0xFFC0, { 10, 11 } }
};
-static const MBAtab MBA_5 [] = {
- {6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4},
- {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
- {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
- {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}
+/* coding table as found in the spec annex B.5 table B-14 */
+static const struct dct_coeff_compressed dct_coeff_tbl_zero[] = {
+ { 0x8000, { 2, dct_End_of_Block, 0 } },
+ { 0x8000, { 1, dct_DC, 1 } },
+ { 0xC000, { 2, dct_AC, 1 } },
+ { 0x6000, { 3, 1, 1 } },
+ { 0x4000, { 4, 0, 2 } },
+ { 0x5000, { 4, 2, 1 } },
+ { 0x2800, { 5, 0, 3 } },
+ { 0x3800, { 5, 3, 1 } },
+ { 0x3000, { 5, 4, 1 } },
+ { 0x1800, { 6, 1, 2 } },
+ { 0x1C00, { 6, 5, 1 } },
+ { 0x1400, { 6, 6, 1 } },
+ { 0x1000, { 6, 7, 1 } },
+ { 0x0C00, { 7, 0, 4 } },
+ { 0x0800, { 7, 2, 2 } },
+ { 0x0E00, { 7, 8, 1 } },
+ { 0x0A00, { 7, 9, 1 } },
+ { 0x0400, { 6, dct_Escape, 0 } },
+ { 0x2600, { 8, 0, 5 } },
+ { 0x2100, { 8, 0, 6 } },
+ { 0x2500, { 8, 1, 3 } },
+ { 0x2400, { 8, 3, 2 } },
+ { 0x2700, { 8, 10, 1 } },
+ { 0x2300, { 8, 11, 1 } },
+ { 0x2200, { 8, 12, 1 } },
+ { 0x2000, { 8, 13, 1 } },
+ { 0x0280, { 10, 0, 7 } },
+ { 0x0300, { 10, 1, 4 } },
+ { 0x02C0, { 10, 2, 3 } },
+ { 0x03C0, { 10, 4, 2 } },
+ { 0x0240, { 10, 5, 2 } },
+ { 0x0380, { 10, 14, 1 } },
+ { 0x0340, { 10, 15, 1 } },
+ { 0x0200, { 10, 16, 1 } },
+ { 0x01D0, { 12, 0, 8 } },
+ { 0x0180, { 12, 0, 9 } },
+ { 0x0130, { 12, 0, 10 } },
+ { 0x0100, { 12, 0, 11 } },
+ { 0x01B0, { 12, 1, 5 } },
+ { 0x0140, { 12, 2, 4 } },
+ { 0x01C0, { 12, 3, 3 } },
+ { 0x0120, { 12, 4, 3 } },
+ { 0x01E0, { 12, 6, 2 } },
+ { 0x0150, { 12, 7, 2 } },
+ { 0x0110, { 12, 8, 2 } },
+ { 0x01F0, { 12, 17, 1 } },
+ { 0x01A0, { 12, 18, 1 } },
+ { 0x0190, { 12, 19, 1 } },
+ { 0x0170, { 12, 20, 1 } },
+ { 0x0160, { 12, 21, 1 } },
+ { 0x00D0, { 13, 0, 12 } },
+ { 0x00C8, { 13, 0, 13 } },
+ { 0x00C0, { 13, 0, 14 } },
+ { 0x00B8, { 13, 0, 15 } },
+ { 0x00B0, { 13, 1, 6 } },
+ { 0x00A8, { 13, 1, 7 } },
+ { 0x00A0, { 13, 2, 5 } },
+ { 0x0098, { 13, 3, 4 } },
+ { 0x0090, { 13, 5, 3 } },
+ { 0x0088, { 13, 9, 2 } },
+ { 0x0080, { 13, 10, 2 } },
+ { 0x00F8, { 13, 22, 1 } },
+ { 0x00F0, { 13, 23, 1 } },
+ { 0x00E8, { 13, 24, 1 } },
+ { 0x00E0, { 13, 25, 1 } },
+ { 0x00D8, { 13, 26, 1 } },
+ { 0x007C, { 14, 0, 16 } },
+ { 0x0078, { 14, 0, 17 } },
+ { 0x0074, { 14, 0, 18 } },
+ { 0x0070, { 14, 0, 19 } },
+ { 0x006C, { 14, 0, 20 } },
+ { 0x0068, { 14, 0, 21 } },
+ { 0x0064, { 14, 0, 22 } },
+ { 0x0060, { 14, 0, 23 } },
+ { 0x005C, { 14, 0, 24 } },
+ { 0x0058, { 14, 0, 25 } },
+ { 0x0054, { 14, 0, 26 } },
+ { 0x0050, { 14, 0, 27 } },
+ { 0x004C, { 14, 0, 28 } },
+ { 0x0048, { 14, 0, 29 } },
+ { 0x0044, { 14, 0, 30 } },
+ { 0x0040, { 14, 0, 31 } },
+ { 0x0030, { 15, 0, 32 } },
+ { 0x002E, { 15, 0, 33 } },
+ { 0x002C, { 15, 0, 34 } },
+ { 0x002A, { 15, 0, 35 } },
+ { 0x0028, { 15, 0, 36 } },
+ { 0x0026, { 15, 0, 37 } },
+ { 0x0024, { 15, 0, 38 } },
+ { 0x0022, { 15, 0, 39 } },
+ { 0x0020, { 15, 0, 40 } },
+ { 0x003E, { 15, 1, 8 } },
+ { 0x003C, { 15, 1, 9 } },
+ { 0x003A, { 15, 1, 10 } },
+ { 0x0038, { 15, 1, 11 } },
+ { 0x0036, { 15, 1, 12 } },
+ { 0x0034, { 15, 1, 13 } },
+ { 0x0032, { 15, 1, 14 } },
+ { 0x0013, { 16, 1, 15 } },
+ { 0x0012, { 16, 1, 16 } },
+ { 0x0011, { 16, 1, 17 } },
+ { 0x0010, { 16, 1, 18 } },
+ { 0x0014, { 16, 6, 3 } },
+ { 0x001A, { 16, 11, 2 } },
+ { 0x0019, { 16, 12, 2 } },
+ { 0x0018, { 16, 13, 2 } },
+ { 0x0017, { 16, 14, 2 } },
+ { 0x0016, { 16, 15, 2 } },
+ { 0x0015, { 16, 16, 2 } },
+ { 0x001F, { 16, 27, 1 } },
+ { 0x001E, { 16, 28, 1 } },
+ { 0x001D, { 16, 29, 1 } },
+ { 0x001C, { 16, 30, 1 } },
+ { 0x001B, { 16, 31, 1 } }
};
-static const MBAtab MBA_11 [] = {
- {32, 11}, {31, 11}, {30, 11}, {29, 11},
- {28, 11}, {27, 11}, {26, 11}, {25, 11},
- {24, 11}, {23, 11}, {22, 11}, {21, 11},
- {20, 10}, {20, 10}, {19, 10}, {19, 10},
- {18, 10}, {18, 10}, {17, 10}, {17, 10},
- {16, 10}, {16, 10}, {15, 10}, {15, 10},
- {14, 8}, {14, 8}, {14, 8}, {14, 8},
- {14, 8}, {14, 8}, {14, 8}, {14, 8},
- {13, 8}, {13, 8}, {13, 8}, {13, 8},
- {13, 8}, {13, 8}, {13, 8}, {13, 8},
- {12, 8}, {12, 8}, {12, 8}, {12, 8},
- {12, 8}, {12, 8}, {12, 8}, {12, 8},
- {11, 8}, {11, 8}, {11, 8}, {11, 8},
- {11, 8}, {11, 8}, {11, 8}, {11, 8},
- {10, 8}, {10, 8}, {10, 8}, {10, 8},
- {10, 8}, {10, 8}, {10, 8}, {10, 8},
- { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
- { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
- { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
- { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
- { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
- { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
- { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
- { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
- { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
- { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}
+/* coding table as found in the spec annex B.5 table B-15 */
+static const struct dct_coeff_compressed dct_coeff_tbl_one[] = {
+ { 0x6000, { 4, dct_End_of_Block, 0 } },
+ { 0x8000, { 2, 0, 1 } },
+ { 0x4000, { 3, 1, 1 } },
+ { 0xC000, { 3, 0, 2 } },
+ { 0x2800, { 5, 2, 1 } },
+ { 0x7000, { 4, 0, 3 } },
+ { 0x3800, { 5, 3, 1 } },
+ { 0x1800, { 6, 4, 1 } },
+ { 0x3000, { 5, 1, 2 } },
+ { 0x1C00, { 6, 5, 1 } },
+ { 0x0C00, { 7, 6, 1 } },
+ { 0x0800, { 7, 7, 1 } },
+ { 0xE000, { 5, 0, 4 } },
+ { 0x0E00, { 7, 2, 2 } },
+ { 0x0A00, { 7, 8, 1 } },
+ { 0xF000, { 7, 9, 1 } },
+ { 0x0400, { 6, dct_Escape, 0 } },
+ { 0xE800, { 5, 0, 5 } },
+ { 0x1400, { 6, 0, 6 } },
+ { 0xF200, { 7, 1, 3 } },
+ { 0x2600, { 8, 3, 2 } },
+ { 0xF400, { 7, 10, 1 } },
+ { 0x2100, { 8, 11, 1 } },
+ { 0x2500, { 8, 12, 1 } },
+ { 0x2400, { 8, 13, 1 } },
+ { 0x1000, { 6, 0, 7 } },
+ { 0x2700, { 8, 1, 4 } },
+ { 0xFC00, { 8, 2, 3 } },
+ { 0xFD00, { 8, 4, 2 } },
+ { 0x0200, { 9, 5, 2 } },
+ { 0x0280, { 9, 14, 1 } },
+ { 0x0380, { 9, 15, 1 } },
+ { 0x0340, { 10, 16, 1 } },
+ { 0xF600, { 7, 0, 8 } },
+ { 0xF800, { 7, 0, 9 } },
+ { 0x2300, { 8, 0, 10 } },
+ { 0x2200, { 8, 0, 11 } },
+ { 0x2000, { 8, 1, 5 } },
+ { 0x0300, { 10, 2, 4 } },
+ { 0x01C0, { 12, 3, 3 } },
+ { 0x0120, { 12, 4, 3 } },
+ { 0x01E0, { 12, 6, 2 } },
+ { 0x0150, { 12, 7, 2 } },
+ { 0x0110, { 12, 8, 2 } },
+ { 0x01F0, { 12, 17, 1 } },
+ { 0x01A0, { 12, 18, 1 } },
+ { 0x0190, { 12, 19, 1 } },
+ { 0x0170, { 12, 20, 1 } },
+ { 0x0160, { 12, 21, 1 } },
+ { 0xFA00, { 8, 0, 12 } },
+ { 0xFB00, { 8, 0, 13 } },
+ { 0xFE00, { 8, 0, 14 } },
+ { 0xFF00, { 8, 0, 15 } },
+ { 0x00B0, { 13, 1, 6 } },
+ { 0x00A8, { 13, 1, 7 } },
+ { 0x00A0, { 13, 2, 5 } },
+ { 0x0098, { 13, 3, 4 } },
+ { 0x0090, { 13, 5, 3 } },
+ { 0x0088, { 13, 9, 2 } },
+ { 0x0080, { 13, 10, 2 } },
+ { 0x00F8, { 13, 22, 1 } },
+ { 0x00F0, { 13, 23, 1 } },
+ { 0x00E8, { 13, 24, 1 } },
+ { 0x00E0, { 13, 25, 1 } },
+ { 0x00D8, { 13, 26, 1 } },
+ { 0x007C, { 14, 0, 16 } },
+ { 0x0078, { 14, 0, 17 } },
+ { 0x0074, { 14, 0, 18 } },
+ { 0x0070, { 14, 0, 19 } },
+ { 0x006C, { 14, 0, 20 } },
+ { 0x0068, { 14, 0, 21 } },
+ { 0x0064, { 14, 0, 22 } },
+ { 0x0060, { 14, 0, 23 } },
+ { 0x005C, { 14, 0, 24 } },
+ { 0x0058, { 14, 0, 25 } },
+ { 0x0054, { 14, 0, 26 } },
+ { 0x0050, { 14, 0, 27 } },
+ { 0x004C, { 14, 0, 28 } },
+ { 0x0048, { 14, 0, 29 } },
+ { 0x0044, { 14, 0, 30 } },
+ { 0x0040, { 14, 0, 31 } },
+ { 0x0030, { 15, 0, 32 } },
+ { 0x002E, { 15, 0, 33 } },
+ { 0x002C, { 15, 0, 34 } },
+ { 0x002A, { 15, 0, 35 } },
+ { 0x0028, { 15, 0, 36 } },
+ { 0x0026, { 15, 0, 37 } },
+ { 0x0024, { 15, 0, 38 } },
+ { 0x0022, { 15, 0, 39 } },
+ { 0x0020, { 15, 0, 40 } },
+ { 0x003E, { 15, 1, 8 } },
+ { 0x003C, { 15, 1, 9 } },
+ { 0x003A, { 15, 1, 10 } },
+ { 0x0038, { 15, 1, 11 } },
+ { 0x0036, { 15, 1, 12 } },
+ { 0x0034, { 15, 1, 13 } },
+ { 0x0032, { 15, 1, 14 } },
+ { 0x0013, { 16, 1, 15 } },
+ { 0x0012, { 16, 1, 16 } },
+ { 0x0011, { 16, 1, 17 } },
+ { 0x0010, { 16, 1, 18 } },
+ { 0x0014, { 16, 6, 3 } },
+ { 0x001A, { 16, 11, 2 } },
+ { 0x0019, { 16, 12, 2 } },
+ { 0x0018, { 16, 13, 2 } },
+ { 0x0017, { 16, 14, 2 } },
+ { 0x0016, { 16, 15, 2 } },
+ { 0x0015, { 16, 16, 2 } },
+ { 0x001F, { 16, 27, 1 } },
+ { 0x001E, { 16, 28, 1 } },
+ { 0x001D, { 16, 29, 1 } },
+ { 0x001C, { 16, 30, 1 } },
+ { 0x001B, { 16, 31, 1 } }
};
-static const int non_linear_quantizer_scale[] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 10, 12, 14, 16, 18, 20, 22,
- 24, 28, 32, 36, 40, 44, 48, 52,
- 56, 64, 72, 80, 88, 96, 104, 112
+/* q_scale_type */
+static const unsigned quant_scale[2][32] = {
+ { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62 },
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24,
+ 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112 }
};
-static INLINE int
-get_macroblock_modes(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture)
-{
- int macroblock_modes;
- const MBtab * tab;
-
- switch (picture->picture_coding_type) {
- case I_TYPE:
-
- tab = MB_I + vl_vlc_ubits(&bs->vlc, 1);
- vl_vlc_dumpbits(&bs->vlc, tab->len);
- macroblock_modes = tab->modes;
-
- return macroblock_modes;
-
- case P_TYPE:
-
- tab = MB_P + vl_vlc_ubits(&bs->vlc, 5);
- vl_vlc_dumpbits(&bs->vlc, tab->len);
- macroblock_modes = tab->modes;
-
- if (picture->picture_structure != FRAME_PICTURE) {
- if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) {
- macroblock_modes |= vl_vlc_ubits(&bs->vlc, 2) * MOTION_TYPE_BASE;
- vl_vlc_dumpbits(&bs->vlc, 2);
- }
- return macroblock_modes;
- } else if (picture->frame_pred_frame_dct) {
- if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
- macroblock_modes |= MC_FRAME;
- return macroblock_modes;
- } else {
- if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) {
- macroblock_modes |= vl_vlc_ubits(&bs->vlc, 2) * MOTION_TYPE_BASE;
- vl_vlc_dumpbits(&bs->vlc, 2);
- }
- return macroblock_modes;
- }
-
- case B_TYPE:
-
- tab = MB_B + vl_vlc_ubits(&bs->vlc, 6);
- vl_vlc_dumpbits(&bs->vlc, tab->len);
- macroblock_modes = tab->modes;
-
- if (picture->picture_structure != FRAME_PICTURE) {
- if (! (macroblock_modes & MACROBLOCK_INTRA)) {
- macroblock_modes |= vl_vlc_ubits(&bs->vlc, 2) * MOTION_TYPE_BASE;
- vl_vlc_dumpbits(&bs->vlc, 2);
- }
- } else if (picture->frame_pred_frame_dct) {
- macroblock_modes |= MC_FRAME;
- } else if (!(macroblock_modes & MACROBLOCK_INTRA)) {
- macroblock_modes |= vl_vlc_ubits(&bs->vlc, 2) * MOTION_TYPE_BASE;
- vl_vlc_dumpbits(&bs->vlc, 2);
- }
- return macroblock_modes;
-
- case D_TYPE:
+static struct vl_vlc_entry tbl_B1[1 << 11];
+static struct vl_vlc_entry tbl_B2[1 << 2];
+static struct vl_vlc_entry tbl_B3[1 << 6];
+static struct vl_vlc_entry tbl_B4[1 << 6];
+static struct vl_vlc_entry tbl_B9[1 << 9];
+static struct vl_vlc_entry tbl_B10[1 << 11];
+static struct vl_vlc_entry tbl_B11[1 << 2];
+static struct vl_vlc_entry tbl_B12[1 << 10];
+static struct vl_vlc_entry tbl_B13[1 << 10];
+static struct dct_coeff tbl_B14_DC[1 << 17];
+static struct dct_coeff tbl_B14_AC[1 << 17];
+static struct dct_coeff tbl_B15[1 << 17];
- vl_vlc_dumpbits(&bs->vlc, 1);
- return MACROBLOCK_INTRA;
-
- default:
- return 0;
- }
-}
-
-static INLINE enum pipe_mpeg12_dct_type
-get_dct_type(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture, int macroblock_modes)
+static INLINE void
+init_dct_coeff_table(struct dct_coeff *dst, const struct dct_coeff_compressed *src,
+ unsigned size, bool is_DC)
{
- enum pipe_mpeg12_dct_type dct_type = PIPE_MPEG12_DCT_TYPE_FRAME;
-
- if ((picture->picture_structure == FRAME_PICTURE) &&
- (!picture->frame_pred_frame_dct) &&
- (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))) {
+ unsigned i;
- dct_type = vl_vlc_ubits(&bs->vlc, 1) ? PIPE_MPEG12_DCT_TYPE_FIELD : PIPE_MPEG12_DCT_TYPE_FRAME;
- vl_vlc_dumpbits(&bs->vlc, 1);
+ for (i=0;i<(1<<17);++i) {
+ dst[i].length = 0;
+ dst[i].level = 0;
+ dst[i].run = dct_End_of_Block;
}
- return dct_type;
-}
-
-static INLINE int
-get_quantizer_scale(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture)
-{
- int quantizer_scale_code;
- quantizer_scale_code = vl_vlc_ubits(&bs->vlc, 5);
- vl_vlc_dumpbits(&bs->vlc, 5);
+ for(; size > 0; --size, ++src) {
+ struct dct_coeff coeff = src->coeff;
+ bool has_sign = true;
- if (picture->q_scale_type)
- return non_linear_quantizer_scale[quantizer_scale_code];
- else
- return quantizer_scale_code << 1;
-}
-
-static INLINE int
-get_motion_delta(struct vl_mpg12_bs *bs, unsigned f_code)
-{
- int delta;
- int sign;
- const MVtab * tab;
+ switch (coeff.run) {
+ case dct_End_of_Block:
+ if (is_DC)
+ continue;
- if (bs->vlc.buf & 0x80000000) {
- vl_vlc_dumpbits(&bs->vlc, 1);
- return 0;
- } else if (bs->vlc.buf >= 0x0c000000) {
+ has_sign = false;
+ break;
- tab = MV_4 + vl_vlc_ubits(&bs->vlc, 4);
- delta = (tab->delta << f_code) + 1;
- bs->vlc.bits += tab->len + f_code + 1;
- bs->vlc.buf <<= tab->len;
+ case dct_Escape:
+ has_sign = false;
+ break;
- sign = vl_vlc_sbits(&bs->vlc, 1);
- bs->vlc.buf <<= 1;
+ case dct_DC:
+ if (!is_DC)
+ continue;
- if (f_code)
- delta += vl_vlc_ubits(&bs->vlc, f_code);
- bs->vlc.buf <<= f_code;
+ coeff.length += 1;
+ coeff.run = 1;
+ break;
- return (delta ^ sign) - sign;
+ case dct_AC:
+ if (is_DC)
+ continue;
- } else {
+ coeff.length += 1;
+ coeff.run = 1;
+ break;
- tab = MV_10 + vl_vlc_ubits(&bs->vlc, 10);
- delta = (tab->delta << f_code) + 1;
- bs->vlc.bits += tab->len + 1;
- bs->vlc.buf <<= tab->len;
+ default:
+ coeff.length += 1;
+ coeff.run += 1;
+ break;
+ }
- sign = vl_vlc_sbits(&bs->vlc, 1);
- bs->vlc.buf <<= 1;
+ for(i=0; i<(1 << (17 - coeff.length)); ++i)
+ dst[src->bitcode << 1 | i] = coeff;
- if (f_code) {
- vl_vlc_needbits(&bs->vlc);
- delta += vl_vlc_ubits(&bs->vlc, f_code);
- vl_vlc_dumpbits(&bs->vlc, f_code);
+ if (has_sign) {
+ coeff.level = -coeff.level;
+ for(; i<(1 << (18 - coeff.length)); ++i)
+ dst[src->bitcode << 1 | i] = coeff;
}
-
- return (delta ^ sign) - sign;
}
}
-static INLINE int
-bound_motion_vector(int vec, unsigned f_code)
+static INLINE void
+init_tables()
{
-#if 1
- unsigned int limit;
- int sign;
-
- limit = 16 << f_code;
-
- if ((unsigned int)(vec + limit) < 2 * limit)
- return vec;
- else {
- sign = ((int32_t)vec) >> 31;
- return vec - ((2 * limit) ^ sign) + sign;
- }
-#else
- return ((int32_t)vec << (28 - f_code)) >> (28 - f_code);
-#endif
+ vl_vlc_init_table(tbl_B1, Elements(tbl_B1), macroblock_address_increment, Elements(macroblock_address_increment));
+ vl_vlc_init_table(tbl_B2, Elements(tbl_B2), macroblock_type_i, Elements(macroblock_type_i));
+ vl_vlc_init_table(tbl_B3, Elements(tbl_B3), macroblock_type_p, Elements(macroblock_type_p));
+ vl_vlc_init_table(tbl_B4, Elements(tbl_B4), macroblock_type_b, Elements(macroblock_type_b));
+ vl_vlc_init_table(tbl_B9, Elements(tbl_B9), coded_block_pattern, Elements(coded_block_pattern));
+ vl_vlc_init_table(tbl_B10, Elements(tbl_B10), motion_code, Elements(motion_code));
+ vl_vlc_init_table(tbl_B11, Elements(tbl_B11), dmvector, Elements(dmvector));
+ vl_vlc_init_table(tbl_B12, Elements(tbl_B12), dct_dc_size_luminance, Elements(dct_dc_size_luminance));
+ vl_vlc_init_table(tbl_B13, Elements(tbl_B13), dct_dc_size_chrominance, Elements(dct_dc_size_chrominance));
+ init_dct_coeff_table(tbl_B14_DC, dct_coeff_tbl_zero, Elements(dct_coeff_tbl_zero), true);
+ init_dct_coeff_table(tbl_B14_AC, dct_coeff_tbl_zero, Elements(dct_coeff_tbl_zero), false);
+ init_dct_coeff_table(tbl_B15, dct_coeff_tbl_one, Elements(dct_coeff_tbl_one), false);
}
static INLINE int
-get_dmv(struct vl_mpg12_bs *bs)
+DIV2DOWN(int todiv)
{
- const DMVtab * tab;
-
- tab = DMV_2 + vl_vlc_ubits(&bs->vlc, 2);
- vl_vlc_dumpbits(&bs->vlc, tab->len);
- return tab->dmv;
+ return (todiv&~1)/2;
}
static INLINE int
-get_coded_block_pattern(struct vl_mpg12_bs *bs)
+DIV2UP(int todiv)
{
- const CBPtab * tab;
-
- vl_vlc_needbits(&bs->vlc);
-
- if (bs->vlc.buf >= 0x20000000) {
-
- tab = CBP_7 + (vl_vlc_ubits(&bs->vlc, 7) - 16);
- vl_vlc_dumpbits(&bs->vlc, tab->len);
- return tab->cbp;
-
- } else {
-
- tab = CBP_9 + vl_vlc_ubits(&bs->vlc, 9);
- vl_vlc_dumpbits(&bs->vlc, tab->len);
- return tab->cbp;
- }
+ return (todiv+1)/2;
}
-static INLINE int
-get_luma_dc_dct_diff(struct vl_mpg12_bs *bs)
+static INLINE void
+motion_vector(struct vl_mpg12_bs *bs, int r, int s, int dmv, short delta[2], short dmvector[2])
{
- const DCtab * tab;
- int size;
- int dc_diff;
-
- if (bs->vlc.buf < 0xf8000000) {
- tab = DC_lum_5 + vl_vlc_ubits(&bs->vlc, 5);
- size = tab->size;
- if (size) {
- bs->vlc.bits += tab->len + size;
- bs->vlc.buf <<= tab->len;
- dc_diff = vl_vlc_ubits(&bs->vlc, size) - UBITS (SBITS (~bs->vlc.buf, 1), size);
- bs->vlc.buf <<= size;
- return dc_diff;
- } else {
- vl_vlc_dumpbits(&bs->vlc, 3);
- return 0;
- }
- } else {
- tab = DC_long + (vl_vlc_ubits(&bs->vlc, 9) - 0x1e0);
- size = tab->size;
- vl_vlc_dumpbits(&bs->vlc, tab->len);
- vl_vlc_needbits(&bs->vlc);
- dc_diff = vl_vlc_ubits(&bs->vlc, size) - UBITS (SBITS (~bs->vlc.buf, 1), size);
- vl_vlc_dumpbits(&bs->vlc, size);
- return dc_diff;
+ int t;
+ for (t = 0; t < 2; ++t) {
+ int motion_code;
+ int r_size = bs->desc.f_code[s][t];
+
+ vl_vlc_fillbits(&bs->vlc);
+ motion_code = vl_vlc_get_vlclbf(&bs->vlc, tbl_B10, 11);
+
+ assert(r_size >= 0);
+ if (r_size && motion_code) {
+ int residual = vl_vlc_get_uimsbf(&bs->vlc, r_size) + 1;
+ delta[t] = ((abs(motion_code) - 1) << r_size) + residual;
+ if (motion_code < 0)
+ delta[t] = -delta[t];
+ } else
+ delta[t] = motion_code;
+ if (dmv)
+ dmvector[t] = vl_vlc_get_vlclbf(&bs->vlc, tbl_B11, 2);
}
}
static INLINE int
-get_chroma_dc_dct_diff(struct vl_mpg12_bs *bs)
+wrap(short f, int shift)
{
- const DCtab * tab;
- int size;
- int dc_diff;
-
- if (bs->vlc.buf < 0xf8000000) {
- tab = DC_chrom_5 + vl_vlc_ubits(&bs->vlc, 5);
- size = tab->size;
- if (size) {
- bs->vlc.bits += tab->len + size;
- bs->vlc.buf <<= tab->len;
- dc_diff = vl_vlc_ubits(&bs->vlc, size) - UBITS (SBITS (~bs->vlc.buf, 1), size);
- bs->vlc.buf <<= size;
- return dc_diff;
- } else {
- vl_vlc_dumpbits(&bs->vlc, 2);
- return 0;
- }
- } else {
- tab = DC_long + (vl_vlc_ubits(&bs->vlc, 10) - 0x3e0);
- size = tab->size;
- vl_vlc_dumpbits(&bs->vlc, tab->len + 1);
- vl_vlc_needbits(&bs->vlc);
- dc_diff = vl_vlc_ubits(&bs->vlc, size) - UBITS (SBITS (~bs->vlc.buf, 1), size);
- vl_vlc_dumpbits(&bs->vlc, size);
- return dc_diff;
- }
+ if (f < (-16 << shift))
+ return f + (32 << shift);
+ else if (f >= 16 << shift)
+ return f - (32 << shift);
+ else
+ return f;
}
static INLINE void
-get_intra_block_B14(struct vl_mpg12_bs *bs, int quantizer_scale, short *dest)
+motion_vector_frame(struct vl_mpg12_bs *bs, int s, struct pipe_mpeg12_macroblock *mb)
{
- int i, val;
- const DCTtab *tab;
-
- i = 0;
-
- vl_vlc_needbits(&bs->vlc);
-
- while (1) {
- if (bs->vlc.buf >= 0x28000000) {
-
- tab = DCT_B14AC_5 + (vl_vlc_ubits(&bs->vlc, 5) - 5);
-
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
+ int dmv = mb->macroblock_modes.bits.frame_motion_type == PIPE_MPEG12_MO_TYPE_DUAL_PRIME;
+ short dmvector[2], delta[2];
- normal_code:
- bs->vlc.buf <<= tab->len;
- bs->vlc.bits += tab->len + 1;
- val = tab->level * quantizer_scale;
+ if (mb->macroblock_modes.bits.frame_motion_type == PIPE_MPEG12_MO_TYPE_FIELD) {
+ mb->motion_vertical_field_select |= vl_vlc_get_uimsbf(&bs->vlc, 1) << s;
+ motion_vector(bs, 0, s, dmv, delta, dmvector);
+ mb->PMV[0][s][0] = wrap(mb->PMV[0][s][0] + delta[0], bs->desc.f_code[s][0]);
+ mb->PMV[0][s][1] = wrap(DIV2DOWN(mb->PMV[0][s][1]) + delta[1], bs->desc.f_code[s][1]) * 2;
- val = (val ^ vl_vlc_sbits(&bs->vlc, 1)) - vl_vlc_sbits(&bs->vlc, 1);
+ mb->motion_vertical_field_select |= vl_vlc_get_uimsbf(&bs->vlc, 1) << (s + 2);
+ motion_vector(bs, 1, s, dmv, delta, dmvector);
+ mb->PMV[1][s][0] = wrap(mb->PMV[1][s][0] + delta[0], bs->desc.f_code[s][0]);
+ mb->PMV[1][s][1] = wrap(DIV2DOWN(mb->PMV[1][s][1]) + delta[1], bs->desc.f_code[s][1]) * 2;
- dest[i] = val;
-
- bs->vlc.buf <<= 1;
- vl_vlc_needbits(&bs->vlc);
-
- continue;
-
- } else if (bs->vlc.buf >= 0x04000000) {
-
- tab = DCT_B14_8 + (vl_vlc_ubits(&bs->vlc, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
-
- i += UBITS(bs->vlc.buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
-
- vl_vlc_dumpbits(&bs->vlc, 12);
- vl_vlc_needbits(&bs->vlc);
- val = vl_vlc_sbits(&bs->vlc, 12) * quantizer_scale;
-
- dest[i] = val;
-
- vl_vlc_dumpbits(&bs->vlc, 12);
- vl_vlc_needbits(&bs->vlc);
-
- continue;
-
- } else if (bs->vlc.buf >= 0x02000000) {
- tab = DCT_B14_10 + (vl_vlc_ubits(&bs->vlc, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else if (bs->vlc.buf >= 0x00800000) {
- tab = DCT_13 + (vl_vlc_ubits(&bs->vlc, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else if (bs->vlc.buf >= 0x00200000) {
- tab = DCT_15 + (vl_vlc_ubits(&bs->vlc, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else {
- tab = DCT_16 + vl_vlc_ubits(&bs->vlc, 16);
- bs->vlc.buf <<= 16;
- vl_vlc_getword(&bs->vlc, bs->vlc.bits + 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
+ } else {
+ motion_vector(bs, 0, s, dmv, delta, dmvector);
+ mb->PMV[0][s][0] = wrap(mb->PMV[0][s][0] + delta[0], bs->desc.f_code[s][0]);
+ mb->PMV[0][s][1] = wrap(mb->PMV[0][s][1] + delta[1], bs->desc.f_code[s][1]);
}
-
- vl_vlc_dumpbits(&bs->vlc, 2); /* dump end of block code */
}
static INLINE void
-get_intra_block_B15(struct vl_mpg12_bs *bs, int quantizer_scale, short *dest)
+motion_vector_field(struct vl_mpg12_bs *bs, int s, struct pipe_mpeg12_macroblock *mb)
{
- int i, val;
- const DCTtab * tab;
-
- i = 0;
-
- vl_vlc_needbits(&bs->vlc);
-
- while (1) {
- if (bs->vlc.buf >= 0x04000000) {
-
- tab = DCT_B15_8 + (vl_vlc_ubits(&bs->vlc, 8) - 4);
-
- i += tab->run;
- if (i < 64) {
-
- normal_code:
- bs->vlc.buf <<= tab->len;
- bs->vlc.bits += tab->len + 1;
- val = tab->level * quantizer_scale;
-
- val = (val ^ vl_vlc_sbits(&bs->vlc, 1)) - vl_vlc_sbits(&bs->vlc, 1);
+ int dmv = mb->macroblock_modes.bits.field_motion_type == PIPE_MPEG12_MO_TYPE_DUAL_PRIME;
+ short dmvector[2], delta[2];
- dest[i] = val;
+ if (mb->macroblock_modes.bits.field_motion_type == PIPE_MPEG12_MO_TYPE_16x8) {
+ mb->motion_vertical_field_select |= vl_vlc_get_uimsbf(&bs->vlc, 1) << s;
+ motion_vector(bs, 0, s, dmv, delta, dmvector);
- bs->vlc.buf <<= 1;
- vl_vlc_needbits(&bs->vlc);
-
- continue;
-
- } else {
-
- /* end of block. I commented out this code because if we */
- /* dont exit here we will still exit at the later test :) */
-
- /* if (i >= 128) break; */ /* end of block */
-
- /* escape code */
-
- i += UBITS(bs->vlc.buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check against buffer overflow */
-
- vl_vlc_dumpbits(&bs->vlc, 12);
- vl_vlc_needbits(&bs->vlc);
- val = vl_vlc_sbits(&bs->vlc, 12) * quantizer_scale;
-
- dest[i] = val;
-
- vl_vlc_dumpbits(&bs->vlc, 12);
- vl_vlc_needbits(&bs->vlc);
-
- continue;
-
- }
- } else if (bs->vlc.buf >= 0x02000000) {
- tab = DCT_B15_10 + (vl_vlc_ubits(&bs->vlc, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else if (bs->vlc.buf >= 0x00800000) {
- tab = DCT_13 + (vl_vlc_ubits(&bs->vlc, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else if (bs->vlc.buf >= 0x00200000) {
- tab = DCT_15 + (vl_vlc_ubits(&bs->vlc, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else {
- tab = DCT_16 + vl_vlc_ubits(&bs->vlc, 16);
- bs->vlc.buf <<= 16;
- vl_vlc_getword(&bs->vlc, bs->vlc.bits + 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
+ mb->motion_vertical_field_select |= vl_vlc_get_uimsbf(&bs->vlc, 1) << (s + 2);
+ motion_vector(bs, 1, s, dmv, delta, dmvector);
+ } else {
+ if (!dmv)
+ mb->motion_vertical_field_select |= vl_vlc_get_uimsbf(&bs->vlc, 1) << s;
+ motion_vector(bs, 0, s, dmv, delta, dmvector);
}
-
- vl_vlc_dumpbits(&bs->vlc, 4); /* dump end of block code */
}
static INLINE void
-get_non_intra_block(struct vl_mpg12_bs *bs, int quantizer_scale, short *dest)
-{
- int i, val;
- const DCTtab *tab;
-
- i = -1;
-
- vl_vlc_needbits(&bs->vlc);
- if (bs->vlc.buf >= 0x28000000) {
- tab = DCT_B14DC_5 + (vl_vlc_ubits(&bs->vlc, 5) - 5);
- goto entry_1;
- } else
- goto entry_2;
-
- while (1) {
- if (bs->vlc.buf >= 0x28000000) {
-
- tab = DCT_B14AC_5 + (vl_vlc_ubits(&bs->vlc, 5) - 5);
-
- entry_1:
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
-
- normal_code:
- bs->vlc.buf <<= tab->len;
- bs->vlc.bits += tab->len + 1;
- val = ((2*tab->level+1) * quantizer_scale) >> 1;
-
- val = (val ^ vl_vlc_sbits(&bs->vlc, 1)) - vl_vlc_sbits(&bs->vlc, 1);
-
- dest[i] = val;
-
- bs->vlc.buf <<= 1;
- vl_vlc_needbits(&bs->vlc);
-
- continue;
-
- }
-
- entry_2:
- if (bs->vlc.buf >= 0x04000000) {
-
- tab = DCT_B14_8 + (vl_vlc_ubits(&bs->vlc, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
-
- i += UBITS(bs->vlc.buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
-
- vl_vlc_dumpbits(&bs->vlc, 12);
- vl_vlc_needbits(&bs->vlc);
- val = 2 * (vl_vlc_sbits(&bs->vlc, 12) + vl_vlc_sbits(&bs->vlc, 1)) + 1;
- val = (val * quantizer_scale) / 2;
-
- dest[i] = val;
-
- vl_vlc_dumpbits(&bs->vlc, 12);
- vl_vlc_needbits(&bs->vlc);
-
- continue;
-
- } else if (bs->vlc.buf >= 0x02000000) {
- tab = DCT_B14_10 + (vl_vlc_ubits(&bs->vlc, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else if (bs->vlc.buf >= 0x00800000) {
- tab = DCT_13 + (vl_vlc_ubits(&bs->vlc, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else if (bs->vlc.buf >= 0x00200000) {
- tab = DCT_15 + (vl_vlc_ubits(&bs->vlc, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else {
- tab = DCT_16 + vl_vlc_ubits(&bs->vlc, 16);
- bs->vlc.buf <<= 16;
- vl_vlc_getword(&bs->vlc, bs->vlc.bits + 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
- vl_vlc_dumpbits(&bs->vlc, 2); /* dump end of block code */
+reset_predictor(struct vl_mpg12_bs *bs) {
+ bs->pred_dc[0] = bs->pred_dc[1] = bs->pred_dc[2] = 0;
}
static INLINE void
-get_mpeg1_intra_block(struct vl_mpg12_bs *bs, int quantizer_scale, short *dest)
+decode_dct(struct vl_mpg12_bs *bs, struct pipe_mpeg12_macroblock *mb, int scale)
{
- int i, val;
- const DCTtab * tab;
+ static const unsigned blk2cc[] = { 0, 0, 0, 0, 1, 2 };
+ static const struct vl_vlc_entry *blk2dcsize[] = {
+ tbl_B12, tbl_B12, tbl_B12, tbl_B12, tbl_B13, tbl_B13
+ };
- i = 0;
+ bool intra = mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA;
+ const struct dct_coeff *table = intra ? bs->intra_dct_tbl : tbl_B14_AC;
+ const struct dct_coeff *entry;
+ int i, cbp, blk = 0;
+ short *dst = mb->blocks;
- vl_vlc_needbits(&bs->vlc);
+ vl_vlc_fillbits(&bs->vlc);
+ mb->coded_block_pattern = cbp = intra ? 0x3F : vl_vlc_get_vlclbf(&bs->vlc, tbl_B9, 9);
- while (1) {
- if (bs->vlc.buf >= 0x28000000) {
+ goto entry;
- tab = DCT_B14AC_5 + (vl_vlc_ubits(&bs->vlc, 5) - 5);
+ while(1) {
+ vl_vlc_eatbits(&bs->vlc, entry->length);
+ if (entry->run == dct_End_of_Block) {
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
+ dst += 64;
+ cbp <<= 1;
+ cbp &= 0x3F;
+ blk++;
- normal_code:
- bs->vlc.buf <<= tab->len;
- bs->vlc.bits += tab->len + 1;
- val = tab->level * quantizer_scale;
-
- /* oddification */
- val = (val - 1) | 1;
-
- /* if (bitstream_get (1)) val = -val; */
- val = (val ^ vl_vlc_sbits(&bs->vlc, 1)) - vl_vlc_sbits(&bs->vlc, 1);
-
- dest[i] = val;
-
- bs->vlc.buf <<= 1;
- vl_vlc_needbits(&bs->vlc);
-
- continue;
-
- } else if (bs->vlc.buf >= 0x04000000) {
-
- tab = DCT_B14_8 + (vl_vlc_ubits(&bs->vlc, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
-
- i += UBITS(bs->vlc.buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
+entry:
+ if (!cbp)
+ break;
- vl_vlc_dumpbits(&bs->vlc, 12);
- vl_vlc_needbits(&bs->vlc);
- val = vl_vlc_sbits(&bs->vlc, 8);
- if (! (val & 0x7f)) {
- vl_vlc_dumpbits(&bs->vlc, 8);
- val = vl_vlc_ubits(&bs->vlc, 8) + 2 * val;
+ while(!(cbp & 0x20)) {
+ cbp <<= 1;
+ blk++;
}
- val = val * quantizer_scale;
-
- /* oddification */
- val = (val + ~SBITS (val, 1)) | 1;
-
- dest[i] = val;
-
- vl_vlc_dumpbits(&bs->vlc, 8);
- vl_vlc_needbits(&bs->vlc);
-
- continue;
-
- } else if (bs->vlc.buf >= 0x02000000) {
- tab = DCT_B14_10 + (vl_vlc_ubits(&bs->vlc, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else if (bs->vlc.buf >= 0x00800000) {
- tab = DCT_13 + (vl_vlc_ubits(&bs->vlc, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else if (bs->vlc.buf >= 0x00200000) {
- tab = DCT_15 + (vl_vlc_ubits(&bs->vlc, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else {
- tab = DCT_16 + vl_vlc_ubits(&bs->vlc, 16);
- bs->vlc.buf <<= 16;
- vl_vlc_getword(&bs->vlc, bs->vlc.bits + 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
- vl_vlc_dumpbits(&bs->vlc, 2); /* dump end of block code */
-}
-
-static INLINE void
-get_mpeg1_non_intra_block(struct vl_mpg12_bs *bs, int quantizer_scale, short *dest)
-{
- int i, val;
- const DCTtab * tab;
-
- i = -1;
-
- vl_vlc_needbits(&bs->vlc);
- if (bs->vlc.buf >= 0x28000000) {
- tab = DCT_B14DC_5 + (vl_vlc_ubits(&bs->vlc, 5) - 5);
- goto entry_1;
- } else
- goto entry_2;
-
- while (1) {
- if (bs->vlc.buf >= 0x28000000) {
-
- tab = DCT_B14AC_5 + (vl_vlc_ubits(&bs->vlc, 5) - 5);
- entry_1:
- i += tab->run;
- if (i >= 64)
- break; /* end of block */
+ vl_vlc_fillbits(&bs->vlc);
- normal_code:
- bs->vlc.buf <<= tab->len;
- bs->vlc.bits += tab->len + 1;
- val = ((2*tab->level+1) * quantizer_scale) >> 1;
+ if (intra) {
+ unsigned cc = blk2cc[blk];
+ unsigned size = vl_vlc_get_vlclbf(&bs->vlc, blk2dcsize[blk], 10);
- /* oddification */
- val = (val - 1) | 1;
-
- /* if (bitstream_get (1)) val = -val; */
- val = (val ^ vl_vlc_sbits(&bs->vlc, 1)) - vl_vlc_sbits(&bs->vlc, 1);
-
- dest[i] = val;
-
- bs->vlc.buf <<= 1;
- vl_vlc_needbits(&bs->vlc);
-
- continue;
-
- }
-
- entry_2:
- if (bs->vlc.buf >= 0x04000000) {
-
- tab = DCT_B14_8 + (vl_vlc_ubits(&bs->vlc, 8) - 4);
-
- i += tab->run;
- if (i < 64)
- goto normal_code;
-
- /* escape code */
+ if (size) {
+ int dct_diff = vl_vlc_get_uimsbf(&bs->vlc, size);
+ int half_range = 1 << (size - 1);
+ if (dct_diff < half_range)
+ dct_diff = (dct_diff + 1) - (2 * half_range);
+ bs->pred_dc[cc] += dct_diff;
+ }
- i += UBITS(bs->vlc.buf << 6, 6) - 64;
- if (i >= 64)
- break; /* illegal, check needed to avoid buffer overflow */
+ dst[0] = bs->pred_dc[cc];
+ i = 0;
- vl_vlc_dumpbits(&bs->vlc, 12);
- vl_vlc_needbits(&bs->vlc);
- val = vl_vlc_sbits(&bs->vlc, 8);
- if (! (val & 0x7f)) {
- vl_vlc_dumpbits(&bs->vlc, 8);
- val = vl_vlc_ubits(&bs->vlc, 8) + 2 * val;
+ } else {
+ entry = tbl_B14_DC + vl_vlc_peekbits(&bs->vlc, 17);
+ i = -1;
+ continue;
}
- val = 2 * (val + SBITS (val, 1)) + 1;
- val = (val * quantizer_scale) / 2;
-
- /* oddification */
- val = (val + ~SBITS (val, 1)) | 1;
-
- dest[i] = val;
-
- vl_vlc_dumpbits(&bs->vlc, 8);
- vl_vlc_needbits(&bs->vlc);
-
- continue;
-
- } else if (bs->vlc.buf >= 0x02000000) {
- tab = DCT_B14_10 + (vl_vlc_ubits(&bs->vlc, 10) - 8);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else if (bs->vlc.buf >= 0x00800000) {
- tab = DCT_13 + (vl_vlc_ubits(&bs->vlc, 13) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else if (bs->vlc.buf >= 0x00200000) {
- tab = DCT_15 + (vl_vlc_ubits(&bs->vlc, 15) - 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- } else {
- tab = DCT_16 + vl_vlc_ubits(&bs->vlc, 16);
- bs->vlc.buf <<= 16;
- vl_vlc_getword(&bs->vlc, bs->vlc.bits + 16);
- i += tab->run;
- if (i < 64)
- goto normal_code;
- }
- break; /* illegal, check needed to avoid buffer overflow */
- }
- vl_vlc_dumpbits(&bs->vlc, 2); /* dump end of block code */
-}
-
-static INLINE void
-slice_intra_DCT(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture, int cc,
- unsigned x, unsigned y, enum pipe_mpeg12_dct_type coding, int quantizer_scale, int dc_dct_pred[3])
-{
- short dest[64];
-
- bs->ycbcr_stream[cc]->x = x;
- bs->ycbcr_stream[cc]->y = y;
- bs->ycbcr_stream[cc]->intra = 1;
- bs->ycbcr_stream[cc]->coding = coding;
- bs->ycbcr_stream[cc]->block_num = bs->block_num++;
-
- vl_vlc_needbits(&bs->vlc);
-
- /* Get the intra DC coefficient and inverse quantize it */
- if (cc == 0)
- dc_dct_pred[0] += get_luma_dc_dct_diff(bs);
- else
- dc_dct_pred[cc] += get_chroma_dc_dct_diff(bs);
-
- memset(dest, 0, sizeof(int16_t) * 64);
- dest[0] = dc_dct_pred[cc];
- if (picture->base.profile == PIPE_VIDEO_PROFILE_MPEG1) {
- if (picture->picture_coding_type != D_TYPE)
- get_mpeg1_intra_block(bs, quantizer_scale, dest);
- } else if (picture->intra_vlc_format)
- get_intra_block_B15(bs, quantizer_scale, dest);
- else
- get_intra_block_B14(bs, quantizer_scale, dest);
-
- memcpy(bs->ycbcr_buffer, dest, sizeof(int16_t) * 64);
-
- bs->num_ycbcr_blocks[cc]++;
- bs->ycbcr_stream[cc]++;
- bs->ycbcr_buffer += 64;
-}
-
-static INLINE void
-slice_non_intra_DCT(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture, int cc,
- unsigned x, unsigned y, enum pipe_mpeg12_dct_type coding, int quantizer_scale)
-{
- short dest[64];
-
- bs->ycbcr_stream[cc]->x = x;
- bs->ycbcr_stream[cc]->y = y;
- bs->ycbcr_stream[cc]->intra = 0;
- bs->ycbcr_stream[cc]->coding = coding;
- bs->ycbcr_stream[cc]->block_num = bs->block_num++;
-
- memset(dest, 0, sizeof(int16_t) * 64);
- if (picture->base.profile == PIPE_VIDEO_PROFILE_MPEG1)
- get_mpeg1_non_intra_block(bs, quantizer_scale, dest);
- else
- get_non_intra_block(bs, quantizer_scale, dest);
-
- memcpy(bs->ycbcr_buffer, dest, sizeof(int16_t) * 64);
-
- bs->num_ycbcr_blocks[cc]++;
- bs->ycbcr_stream[cc]++;
- bs->ycbcr_buffer += 64;
-}
-
-static INLINE void
-motion_mp1(struct vl_mpg12_bs *bs, unsigned f_code[2], struct vl_motionvector *mv)
-{
- int motion_x, motion_y;
-
- mv->top.field_select = mv->bottom.field_select = PIPE_VIDEO_FRAME;
-
- vl_vlc_needbits(&bs->vlc);
- motion_x = (mv->top.x + (get_motion_delta(bs, f_code[0]) << f_code[1]));
- motion_x = bound_motion_vector (motion_x, f_code[0] + f_code[1]);
- mv->top.x = mv->bottom.x = motion_x;
-
- vl_vlc_needbits(&bs->vlc);
- motion_y = (mv->top.y + (get_motion_delta(bs, f_code[0]) << f_code[1]));
- motion_y = bound_motion_vector (motion_y, f_code[0] + f_code[1]);
- mv->top.y = mv->bottom.y = motion_y;
-}
-
-static INLINE void
-motion_fr_frame(struct vl_mpg12_bs *bs, unsigned f_code[2], struct vl_motionvector *mv)
-{
- int motion_x, motion_y;
-
- mv->top.field_select = mv->bottom.field_select = PIPE_VIDEO_FRAME;
-
- vl_vlc_needbits(&bs->vlc);
- motion_x = mv->top.x + get_motion_delta(bs, f_code[0]);
- motion_x = bound_motion_vector(motion_x, f_code[0]);
- mv->top.x = mv->bottom.x = motion_x;
-
- vl_vlc_needbits(&bs->vlc);
- motion_y = mv->top.y + get_motion_delta(bs, f_code[1]);
- motion_y = bound_motion_vector(motion_y, f_code[1]);
- mv->top.y = mv->bottom.y = motion_y;
-}
-
-static INLINE void
-motion_fr_field(struct vl_mpg12_bs *bs, unsigned f_code[2], struct vl_motionvector *mv)
-{
- int motion_x, motion_y;
-
- vl_vlc_needbits(&bs->vlc);
- mv->top.field_select = vl_vlc_ubits(&bs->vlc, 1) ?
- PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD;
- vl_vlc_dumpbits(&bs->vlc, 1);
-
- motion_x = mv->top.x + get_motion_delta(bs, f_code[0]);
- motion_x = bound_motion_vector (motion_x, f_code[0]);
- mv->top.x = motion_x;
-
- vl_vlc_needbits(&bs->vlc);
- motion_y = (mv->top.y >> 1) + get_motion_delta(bs, f_code[1]);
- /* motion_y = bound_motion_vector (motion_y, f_code[1]); */
- mv->top.y = motion_y << 1;
-
- vl_vlc_needbits(&bs->vlc);
- mv->bottom.field_select = vl_vlc_ubits(&bs->vlc, 1) ?
- PIPE_VIDEO_BOTTOM_FIELD : PIPE_VIDEO_TOP_FIELD;
- vl_vlc_dumpbits(&bs->vlc, 1);
-
- motion_x = mv->bottom.x + get_motion_delta(bs, f_code[0]);
- motion_x = bound_motion_vector (motion_x, f_code[0]);
- mv->bottom.x = motion_x;
-
- vl_vlc_needbits(&bs->vlc);
- motion_y = (mv->bottom.y >> 1) + get_motion_delta(bs, f_code[1]);
- /* motion_y = bound_motion_vector (motion_y, f_code[1]); */
- mv->bottom.y = motion_y << 1;
-}
-
-static INLINE void
-motion_fr_dmv(struct vl_mpg12_bs *bs, unsigned f_code[2], struct vl_motionvector *mv)
-{
- int motion_x, motion_y;
-
- // TODO Implement dmv
- mv->top.field_select = mv->bottom.field_select = PIPE_VIDEO_FRAME;
-
- vl_vlc_needbits(&bs->vlc);
- motion_x = mv->top.x + get_motion_delta(bs, f_code[0]);
- motion_x = bound_motion_vector(motion_x, f_code[0]);
- mv->top.x = mv->bottom.x = motion_x;
-
- vl_vlc_needbits(&bs->vlc);
- motion_y = (mv->top.y >> 1) + get_motion_delta(bs, f_code[1]);
- /* motion_y = bound_motion_vector (motion_y, f_code[1]); */
- mv->top.y = mv->bottom.y = motion_y << 1;
-}
-
-/* like motion_frame, but parsing without actual motion compensation */
-static INLINE void
-motion_fr_conceal(struct vl_mpg12_bs *bs, unsigned f_code[2], struct vl_motionvector *mv)
-{
- int tmp;
-
- mv->top.field_select = mv->bottom.field_select = PIPE_VIDEO_FRAME;
-
- vl_vlc_needbits(&bs->vlc);
- tmp = (mv->top.x + get_motion_delta(bs, f_code[0]));
- tmp = bound_motion_vector (tmp, f_code[0]);
- mv->top.x = mv->bottom.x = tmp;
-
- vl_vlc_needbits(&bs->vlc);
- tmp = (mv->top.y + get_motion_delta(bs, f_code[1]));
- tmp = bound_motion_vector (tmp, f_code[1]);
- mv->top.y = mv->bottom.y = tmp;
-
- vl_vlc_dumpbits(&bs->vlc, 1); /* remove marker_bit */
-}
-
-static INLINE void
-motion_fi_field(struct vl_mpg12_bs *bs, unsigned f_code[2], struct vl_motionvector *mv)
-{
- int motion_x, motion_y;
-
- vl_vlc_needbits(&bs->vlc);
-
- // ref_field
- //vl_vlc_ubits(&bs->vlc, 1);
-
- // TODO field select may need to do something here for bob (weave ok)
- mv->top.field_select = mv->bottom.field_select = PIPE_VIDEO_FRAME;
- vl_vlc_dumpbits(&bs->vlc, 1);
-
- motion_x = mv->top.x + get_motion_delta(bs, f_code[0]);
- motion_x = bound_motion_vector (motion_x, f_code[0]);
- mv->top.x = mv->bottom.x = motion_x;
-
- vl_vlc_needbits(&bs->vlc);
- motion_y = mv->top.y + get_motion_delta(bs, f_code[1]);
- motion_y = bound_motion_vector (motion_y, f_code[1]);
- mv->top.y = mv->bottom.y = motion_y;
-}
-
-static INLINE void
-motion_fi_16x8(struct vl_mpg12_bs *bs, unsigned f_code[2], struct vl_motionvector *mv)
-{
- int motion_x, motion_y;
-
- vl_vlc_needbits(&bs->vlc);
-
- // ref_field
- //vl_vlc_ubits(&bs->vlc, 1);
-
- // TODO field select may need to do something here bob (weave ok)
- mv->top.field_select = PIPE_VIDEO_FRAME;
- vl_vlc_dumpbits(&bs->vlc, 1);
-
- motion_x = mv->top.x + get_motion_delta(bs, f_code[0]);
- motion_x = bound_motion_vector (motion_x, f_code[0]);
- mv->top.x = motion_x;
-
- vl_vlc_needbits(&bs->vlc);
- motion_y = mv->top.y + get_motion_delta(bs, f_code[1]);
- motion_y = bound_motion_vector (motion_y, f_code[1]);
- mv->top.y = motion_y;
-
- vl_vlc_needbits(&bs->vlc);
- // ref_field
- //vl_vlc_ubits(&bs->vlc, 1);
-
- // TODO field select may need to do something here for bob (weave ok)
- mv->bottom.field_select = PIPE_VIDEO_FRAME;
- vl_vlc_dumpbits(&bs->vlc, 1);
-
- motion_x = mv->bottom.x + get_motion_delta(bs, f_code[0]);
- motion_x = bound_motion_vector (motion_x, f_code[0]);
- mv->bottom.x = motion_x;
- vl_vlc_needbits(&bs->vlc);
- motion_y = mv->bottom.y + get_motion_delta(bs, f_code[1]);
- motion_y = bound_motion_vector (motion_y, f_code[1]);
- mv->bottom.y = motion_y;
-}
-
-static INLINE void
-motion_fi_dmv(struct vl_mpg12_bs *bs, unsigned f_code[2], struct vl_motionvector *mv)
-{
- int motion_x, motion_y;
-
- // TODO field select may need to do something here for bob (weave ok)
- mv->top.field_select = mv->bottom.field_select = PIPE_VIDEO_FRAME;
-
- vl_vlc_needbits(&bs->vlc);
- motion_x = mv->top.x + get_motion_delta(bs, f_code[0]);
- motion_x = bound_motion_vector (motion_x, f_code[0]);
- mv->top.x = mv->bottom.x = motion_x;
-
- vl_vlc_needbits(&bs->vlc);
- motion_y = mv->top.y + get_motion_delta(bs, f_code[1]);
- motion_y = bound_motion_vector (motion_y, f_code[1]);
- mv->top.y = mv->bottom.y = motion_y;
-}
-
-
-static INLINE void
-motion_fi_conceal(struct vl_mpg12_bs *bs, unsigned f_code[2], struct vl_motionvector *mv)
-{
- int tmp;
-
- vl_vlc_needbits(&bs->vlc);
- vl_vlc_dumpbits(&bs->vlc, 1); /* remove field_select */
-
- tmp = (mv->top.x + get_motion_delta(bs, f_code[0]));
- tmp = bound_motion_vector(tmp, f_code[0]);
- mv->top.x = mv->bottom.x = tmp;
-
- vl_vlc_needbits(&bs->vlc);
- tmp = (mv->top.y + get_motion_delta(bs, f_code[1]));
- tmp = bound_motion_vector(tmp, f_code[1]);
- mv->top.y = mv->bottom.y = tmp;
-
- vl_vlc_dumpbits(&bs->vlc, 1); /* remove marker_bit */
-}
-
-#define MOTION_CALL(routine, macroblock_modes) \
-do { \
- if ((macroblock_modes) & MACROBLOCK_MOTION_FORWARD) \
- routine(bs, picture->f_code[0], &mv_fwd); \
- if ((macroblock_modes) & MACROBLOCK_MOTION_BACKWARD) \
- routine(bs, picture->f_code[1], &mv_bwd); \
-} while (0)
-
-static INLINE void
-store_motionvectors(struct vl_mpg12_bs *bs, unsigned *mv_pos,
- struct vl_motionvector *mv_fwd,
- struct vl_motionvector *mv_bwd)
-{
- bs->mv_stream[0][*mv_pos].top = mv_fwd->top;
- bs->mv_stream[0][*mv_pos].bottom =
- mv_fwd->top.field_select == PIPE_VIDEO_FRAME ?
- mv_fwd->top : mv_fwd->bottom;
-
- bs->mv_stream[1][*mv_pos].top = mv_bwd->top;
- bs->mv_stream[1][*mv_pos].bottom =
- mv_bwd->top.field_select == PIPE_VIDEO_FRAME ?
- mv_bwd->top : mv_bwd->bottom;
-
- (*mv_pos)++;
-}
-
-static INLINE bool
-slice_init(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture,
- int *quantizer_scale, unsigned *x, unsigned *y, unsigned *mv_pos)
-{
- const MBAtab * mba;
-
- vl_vlc_need32bits(&bs->vlc);
- while(bs->vlc.buf < 0x101 || bs->vlc.buf > 0x1AF) {
- if(!vl_vlc_getbyte(&bs->vlc))
- return false;
- }
- *y = (bs->vlc.buf & 0xFF) - 1;
- vl_vlc_restart(&bs->vlc);
+ } else if (entry->run == dct_Escape) {
+ i += vl_vlc_get_uimsbf(&bs->vlc, 6) + 1;
+ if (i > 64)
+ break;
- *quantizer_scale = get_quantizer_scale(bs, picture);
+ dst[i] = vl_vlc_get_simsbf(&bs->vlc, 12) * scale;
- /* ignore intra_slice and all the extra data */
- while (bs->vlc.buf & 0x80000000) {
- vl_vlc_dumpbits(&bs->vlc, 9);
- vl_vlc_needbits(&bs->vlc);
- }
+ } else {
+ i += entry->run;
+ if (i > 64)
+ break;
- /* decode initial macroblock address increment */
- *x = 0;
- while (1) {
- if (bs->vlc.buf >= 0x08000000) {
- mba = MBA_5 + (vl_vlc_ubits(&bs->vlc, 6) - 2);
- break;
- } else if (bs->vlc.buf >= 0x01800000) {
- mba = MBA_11 + (vl_vlc_ubits(&bs->vlc, 12) - 24);
- break;
- } else switch (vl_vlc_ubits(&bs->vlc, 12)) {
- case 8: /* macroblock_escape */
- *x += 33;
- vl_vlc_dumpbits(&bs->vlc, 11);
- vl_vlc_needbits(&bs->vlc);
- continue;
- case 15: /* macroblock_stuffing (MPEG1 only) */
- bs->vlc.buf &= 0xfffff;
- vl_vlc_dumpbits(&bs->vlc, 11);
- vl_vlc_needbits(&bs->vlc);
- continue;
- default: /* error */
- return false;
+ dst[i] = entry->level * scale;
}
- }
- vl_vlc_dumpbits(&bs->vlc, mba->len + 1);
- *x += mba->mba;
- while (*x >= bs->width) {
- *x -= bs->width;
- (*y)++;
+ vl_vlc_fillbits(&bs->vlc);
+ entry = table + vl_vlc_peekbits(&bs->vlc, 17);
}
- if (*y > bs->height)
- return false;
-
- *mv_pos = *x + *y * bs->width;
-
- return true;
}
static INLINE bool
-decode_slice(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc *picture)
+decode_slice(struct vl_mpg12_bs *bs)
{
- enum vl_field_select default_field_select;
- struct vl_motionvector mv_fwd, mv_bwd;
- enum pipe_mpeg12_dct_type dct_type;
+ struct pipe_mpeg12_macroblock mb = {};
+ short dct_blocks[64*6];
+ unsigned dct_scale;
+ signed x = -1;
- /* predictor for DC coefficients in intra blocks */
- int dc_dct_pred[3] = { 0, 0, 0 };
- int quantizer_scale;
+ mb.base.codec = PIPE_VIDEO_CODEC_MPEG12;
+ mb.y = vl_vlc_get_uimsbf(&bs->vlc, 8) - 1;
+ mb.blocks = dct_blocks;
- unsigned x, y, mv_pos;
+ reset_predictor(bs);
+ dct_scale = quant_scale[bs->desc.q_scale_type][vl_vlc_get_uimsbf(&bs->vlc, 5)];
- switch(picture->picture_structure) {
- case TOP_FIELD:
- default_field_select = PIPE_VIDEO_TOP_FIELD;
- break;
-
- case BOTTOM_FIELD:
- default_field_select = PIPE_VIDEO_BOTTOM_FIELD;
- break;
-
- default:
- default_field_select = PIPE_VIDEO_FRAME;
- break;
- }
+ if (vl_vlc_get_uimsbf(&bs->vlc, 1))
+ while (vl_vlc_get_uimsbf(&bs->vlc, 9) & 1)
+ vl_vlc_fillbits(&bs->vlc);
- if (!slice_init(bs, picture, &quantizer_scale, &x, &y, &mv_pos))
- return false;
+ do {
+ int inc = 0;
- mv_fwd.top.x = mv_fwd.top.y = mv_fwd.bottom.x = mv_fwd.bottom.y = 0;
- mv_fwd.top.field_select = mv_fwd.bottom.field_select = default_field_select;
+ vl_vlc_fillbits(&bs->vlc);
- mv_bwd.top.x = mv_bwd.top.y = mv_bwd.bottom.x = mv_bwd.bottom.y = 0;
- mv_bwd.top.field_select = mv_bwd.bottom.field_select = default_field_select;
+ while (vl_vlc_peekbits(&bs->vlc, 11) == 15) {
+ vl_vlc_eatbits(&bs->vlc, 11);
+ vl_vlc_fillbits(&bs->vlc);
+ }
- while (1) {
- int macroblock_modes;
- int mba_inc;
- const MBAtab * mba;
+ while (vl_vlc_peekbits(&bs->vlc, 11) == 8) {
+ vl_vlc_eatbits(&bs->vlc, 11);
+ vl_vlc_fillbits(&bs->vlc);
+ inc += 33;
+ }
+ inc += vl_vlc_get_vlclbf(&bs->vlc, tbl_B1, 11);
+ if (x != -1) {
+ mb.num_skipped_macroblocks = inc - 1;
+ bs->decoder->decode_macroblock(bs->decoder, &mb.base, 1);
+ }
+ mb.x = x += inc;
- vl_vlc_needbits(&bs->vlc);
+ switch (bs->desc.picture_coding_type) {
+ case PIPE_MPEG12_PICTURE_CODING_TYPE_I:
+ mb.macroblock_type = vl_vlc_get_vlclbf(&bs->vlc, tbl_B2, 2);
+ break;
- macroblock_modes = get_macroblock_modes(bs, picture);
- dct_type = get_dct_type(bs, picture, macroblock_modes);
+ case PIPE_MPEG12_PICTURE_CODING_TYPE_P:
+ mb.macroblock_type = vl_vlc_get_vlclbf(&bs->vlc, tbl_B3, 6);
+ break;
- switch(macroblock_modes & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD)) {
- case (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD):
- mv_fwd.top.weight = mv_fwd.bottom.weight = PIPE_VIDEO_MV_WEIGHT_HALF;
- mv_bwd.top.weight = mv_bwd.bottom.weight = PIPE_VIDEO_MV_WEIGHT_HALF;
+ case PIPE_MPEG12_PICTURE_CODING_TYPE_B:
+ mb.macroblock_type = vl_vlc_get_vlclbf(&bs->vlc, tbl_B4, 6);
break;
default:
- mv_fwd.top.field_select = mv_fwd.bottom.field_select = default_field_select;
- mv_bwd.top.field_select = mv_bwd.bottom.field_select = default_field_select;
+ mb.macroblock_type = 0;
+ /* dumb gcc */
+ assert(0);
+ }
- /* fall through */
- case MACROBLOCK_MOTION_FORWARD:
- mv_fwd.top.weight = mv_fwd.bottom.weight = PIPE_VIDEO_MV_WEIGHT_MAX;
- mv_bwd.top.weight = mv_bwd.bottom.weight = PIPE_VIDEO_MV_WEIGHT_MIN;
- break;
+ mb.macroblock_modes.value = 0;
+ if (mb.macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD | PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD)) {
+ if (bs->desc.picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME) {
+ if (bs->desc.frame_pred_frame_dct == 0)
+ mb.macroblock_modes.bits.frame_motion_type = vl_vlc_get_uimsbf(&bs->vlc, 2);
+ else
+ mb.macroblock_modes.bits.frame_motion_type = 2;
+ } else
+ mb.macroblock_modes.bits.field_motion_type = vl_vlc_get_uimsbf(&bs->vlc, 2);
- case MACROBLOCK_MOTION_BACKWARD:
- mv_fwd.top.weight = mv_fwd.bottom.weight = PIPE_VIDEO_MV_WEIGHT_MIN;
- mv_bwd.top.weight = mv_bwd.bottom.weight = PIPE_VIDEO_MV_WEIGHT_MAX;
- break;
+ } else if ((mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA) && bs->desc.concealment_motion_vectors) {
+ if (bs->desc.picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME)
+ mb.macroblock_modes.bits.frame_motion_type = 2;
+ else
+ mb.macroblock_modes.bits.field_motion_type = 1;
}
- /* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */
- if (macroblock_modes & MACROBLOCK_QUANT)
- quantizer_scale = get_quantizer_scale(bs, picture);
+ if (bs->desc.picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME &&
+ bs->desc.frame_pred_frame_dct == 0 &&
+ mb.macroblock_type & (PIPE_MPEG12_MB_TYPE_INTRA | PIPE_MPEG12_MB_TYPE_PATTERN))
+ mb.macroblock_modes.bits.dct_type = vl_vlc_get_uimsbf(&bs->vlc, 1);
- if (macroblock_modes & MACROBLOCK_INTRA) {
+ if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_QUANT)
+ dct_scale = quant_scale[bs->desc.q_scale_type][vl_vlc_get_uimsbf(&bs->vlc, 5)];
- if (picture->concealment_motion_vectors) {
- if (picture->picture_structure == FRAME_PICTURE)
- motion_fr_conceal(bs, picture->f_code[0], &mv_fwd);
- else
- motion_fi_conceal(bs, picture->f_code[0], &mv_fwd);
+ if (inc > 1 && bs->desc.picture_coding_type == PIPE_MPEG12_PICTURE_CODING_TYPE_P)
+ memset(mb.PMV, 0, sizeof(mb.PMV));
- } else {
- mv_fwd.top.x = mv_fwd.top.y = mv_fwd.bottom.x = mv_fwd.bottom.y = 0;
- mv_bwd.top.x = mv_bwd.top.y = mv_bwd.bottom.x = mv_bwd.bottom.y = 0;
- }
- mv_fwd.top.weight = mv_fwd.bottom.weight = PIPE_VIDEO_MV_WEIGHT_MIN;
- mv_bwd.top.weight = mv_bwd.bottom.weight = PIPE_VIDEO_MV_WEIGHT_MIN;
-
- // unravaled loop of 6 block(i) calls in macroblock()
- slice_intra_DCT(bs, picture, 0, x*2+0, y*2+0, dct_type, quantizer_scale, dc_dct_pred);
- slice_intra_DCT(bs, picture, 0, x*2+1, y*2+0, dct_type, quantizer_scale, dc_dct_pred);
- slice_intra_DCT(bs, picture, 0, x*2+0, y*2+1, dct_type, quantizer_scale, dc_dct_pred);
- slice_intra_DCT(bs, picture, 0, x*2+1, y*2+1, dct_type, quantizer_scale, dc_dct_pred);
- slice_intra_DCT(bs, picture, 1, x, y, PIPE_MPEG12_DCT_TYPE_FRAME, quantizer_scale, dc_dct_pred);
- slice_intra_DCT(bs, picture, 2, x, y, PIPE_MPEG12_DCT_TYPE_FRAME, quantizer_scale, dc_dct_pred);
-
- if (picture->picture_coding_type == D_TYPE) {
- vl_vlc_needbits(&bs->vlc);
- vl_vlc_dumpbits(&bs->vlc, 1);
- }
-
- } else {
- if (picture->picture_structure == FRAME_PICTURE)
- switch (macroblock_modes & MOTION_TYPE_MASK) {
- case MC_FRAME:
- if (picture->base.profile == PIPE_VIDEO_PROFILE_MPEG1) {
- MOTION_CALL(motion_mp1, macroblock_modes);
- } else {
- MOTION_CALL(motion_fr_frame, macroblock_modes);
- }
- break;
-
- case MC_FIELD:
- MOTION_CALL (motion_fr_field, macroblock_modes);
- break;
-
- case MC_DMV:
- MOTION_CALL (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD);
- break;
-
- case 0:
- /* non-intra mb without forward mv in a P picture */
- mv_fwd.top.x = mv_fwd.top.y = mv_fwd.bottom.x = mv_fwd.bottom.y = 0;
- mv_bwd.top.x = mv_bwd.top.y = mv_bwd.bottom.x = mv_bwd.bottom.y = 0;
- break;
- }
+ mb.motion_vertical_field_select = 0;
+ if ((mb.macroblock_type & PIPE_MPEG12_MB_TYPE_MOTION_FORWARD) ||
+ (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA && bs->desc.concealment_motion_vectors)) {
+ if (bs->desc.picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME)
+ motion_vector_frame(bs, 0, &mb);
else
- switch (macroblock_modes & MOTION_TYPE_MASK) {
- case MC_FIELD:
- MOTION_CALL (motion_fi_field, macroblock_modes);
- break;
-
- case MC_16X8:
- MOTION_CALL (motion_fi_16x8, macroblock_modes);
- break;
-
- case MC_DMV:
- MOTION_CALL (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD);
- break;
-
- case 0:
- /* non-intra mb without forward mv in a P picture */
- mv_fwd.top.x = mv_fwd.top.y = mv_fwd.bottom.x = mv_fwd.bottom.y = 0;
- mv_bwd.top.x = mv_bwd.top.y = mv_bwd.bottom.x = mv_bwd.bottom.y = 0;
- break;
- }
-
- if (macroblock_modes & MACROBLOCK_PATTERN) {
- int coded_block_pattern = get_coded_block_pattern(bs);
-
- // TODO optimize not fully used for idct accel only mc.
- if (coded_block_pattern & 0x20)
- slice_non_intra_DCT(bs, picture, 0, x*2+0, y*2+0, dct_type, quantizer_scale); // cc0 luma 0
- if (coded_block_pattern & 0x10)
- slice_non_intra_DCT(bs, picture, 0, x*2+1, y*2+0, dct_type, quantizer_scale); // cc0 luma 1
- if (coded_block_pattern & 0x08)
- slice_non_intra_DCT(bs, picture, 0, x*2+0, y*2+1, dct_type, quantizer_scale); // cc0 luma 2
- if (coded_block_pattern & 0x04)
- slice_non_intra_DCT(bs, picture, 0, x*2+1, y*2+1, dct_type, quantizer_scale); // cc0 luma 3
- if (coded_block_pattern & 0x2)
- slice_non_intra_DCT(bs, picture, 1, x, y, PIPE_MPEG12_DCT_TYPE_FRAME, quantizer_scale); // cc1 croma
- if (coded_block_pattern & 0x1)
- slice_non_intra_DCT(bs, picture, 2, x, y, PIPE_MPEG12_DCT_TYPE_FRAME, quantizer_scale); // cc2 croma
- }
-
- dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
+ motion_vector_field(bs, 0, &mb);
}
- store_motionvectors(bs, &mv_pos, &mv_fwd, &mv_bwd);
- if (++x >= bs->width) {
- ++y;
- if (y >= bs->height)
- return false;
- x -= bs->width;
+ if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD) {
+ if (bs->desc.picture_structure == PIPE_MPEG12_PICTURE_STRUCTURE_FRAME)
+ motion_vector_frame(bs, 1, &mb);
+ else
+ motion_vector_field(bs, 1, &mb);
}
- vl_vlc_needbits(&bs->vlc);
- mba_inc = 0;
- while (1) {
- if (bs->vlc.buf >= 0x10000000) {
- mba = MBA_5 + (vl_vlc_ubits(&bs->vlc, 5) - 2);
- break;
- } else if (bs->vlc.buf >= 0x03000000) {
- mba = MBA_11 + (vl_vlc_ubits(&bs->vlc, 11) - 24);
- break;
- } else switch (vl_vlc_ubits(&bs->vlc, 11)) {
- case 8: /* macroblock_escape */
- mba_inc += 33;
- /* pass through */
- case 15: /* macroblock_stuffing (MPEG1 only) */
- vl_vlc_dumpbits(&bs->vlc, 11);
- vl_vlc_needbits(&bs->vlc);
- continue;
- default: /* end of slice, or error */
- return true;
- }
+ if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA && bs->desc.concealment_motion_vectors) {
+ unsigned extra = vl_vlc_get_uimsbf(&bs->vlc, 1);
+ mb.PMV[1][0][0] = mb.PMV[0][0][0];
+ mb.PMV[1][0][1] = mb.PMV[0][0][1];
+ assert(extra);
+ } else if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA ||
+ !(mb.macroblock_type & (PIPE_MPEG12_MB_TYPE_MOTION_FORWARD |
+ PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD))) {
+ memset(mb.PMV, 0, sizeof(mb.PMV));
}
- vl_vlc_dumpbits(&bs->vlc, mba->len);
- mba_inc += mba->mba;
- if (mba_inc) {
- //TODO conversion to signed format signed format
- dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
-
- mv_fwd.top.field_select = mv_fwd.bottom.field_select = default_field_select;
- mv_bwd.top.field_select = mv_bwd.bottom.field_select = default_field_select;
-
- if (picture->picture_coding_type == P_TYPE) {
- mv_fwd.top.x = mv_fwd.top.y = mv_fwd.bottom.x = mv_fwd.bottom.y = 0;
- mv_fwd.top.weight = mv_fwd.bottom.weight = PIPE_VIDEO_MV_WEIGHT_MAX;
- }
- x += mba_inc;
- do {
- store_motionvectors(bs, &mv_pos, &mv_fwd, &mv_bwd);
- } while (--mba_inc);
+ if ((mb.macroblock_type & PIPE_MPEG12_MB_TYPE_MOTION_FORWARD &&
+ mb.macroblock_modes.bits.frame_motion_type == 2) ||
+ (mb.macroblock_modes.bits.frame_motion_type == 3)) {
+ mb.PMV[1][0][0] = mb.PMV[0][0][0];
+ mb.PMV[1][0][1] = mb.PMV[0][0][1];
}
- while (x >= bs->width) {
- ++y;
- if (y >= bs->height)
- return false;
- x -= bs->width;
+
+ if (mb.macroblock_type & PIPE_MPEG12_MB_TYPE_MOTION_BACKWARD &&
+ mb.macroblock_modes.bits.frame_motion_type == 2) {
+ mb.PMV[1][1][0] = mb.PMV[0][1][0];
+ mb.PMV[1][1][1] = mb.PMV[0][1][1];
}
- }
+
+ if (inc > 1 || !(mb.macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA))
+ reset_predictor(bs);
+
+ if (mb.macroblock_type & (PIPE_MPEG12_MB_TYPE_INTRA | PIPE_MPEG12_MB_TYPE_PATTERN)) {
+ memset(dct_blocks, 0, sizeof(dct_blocks));
+ decode_dct(bs, &mb, dct_scale);
+ } else
+ mb.coded_block_pattern = 0;
+
+ } while (vl_vlc_bytes_left(&bs->vlc) && vl_vlc_peekbits(&bs->vlc, 23));
+
+ mb.num_skipped_macroblocks = 0;
+ bs->decoder->decode_macroblock(bs->decoder, &mb.base, 1);
+ return true;
}
void
-vl_mpg12_bs_init(struct vl_mpg12_bs *bs, unsigned width, unsigned height)
+vl_mpg12_bs_init(struct vl_mpg12_bs *bs, struct pipe_video_decoder *decoder)
{
+ static bool tables_initialized = false;
+
assert(bs);
memset(bs, 0, sizeof(struct vl_mpg12_bs));
- bs->width = width;
- bs->height = height;
+ bs->decoder = decoder;
+
+ if (!tables_initialized) {
+ init_tables();
+ tables_initialized = true;
+ }
}
void
-vl_mpg12_bs_set_buffers(struct vl_mpg12_bs *bs, struct vl_ycbcr_block *ycbcr_stream[VL_MAX_PLANES],
- short *ycbcr_buffer, struct vl_motionvector *mv_stream[VL_MAX_REF_FRAMES])
+vl_mpg12_bs_set_picture_desc(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc *picture)
{
- unsigned i;
-
- assert(bs);
- assert(ycbcr_stream && ycbcr_buffer);
- assert(mv_stream);
-
- bs->block_num = 0;
-
- for (i = 0; i < VL_MAX_PLANES; ++i)
- bs->ycbcr_stream[i] = ycbcr_stream[i];
- bs->ycbcr_buffer = ycbcr_buffer;
-
- for (i = 0; i < VL_MAX_REF_FRAMES; ++i)
- bs->mv_stream[i] = mv_stream[i];
-
- // TODO
- for (i = 0; i < bs->width*bs->height; ++i) {
- bs->mv_stream[0][i].top.x = bs->mv_stream[0][i].top.y = 0;
- bs->mv_stream[0][i].top.field_select = PIPE_VIDEO_FRAME;
- bs->mv_stream[0][i].top.weight = PIPE_VIDEO_MV_WEIGHT_MAX;
- bs->mv_stream[0][i].bottom.x = bs->mv_stream[0][i].bottom.y = 0;
- bs->mv_stream[0][i].bottom.field_select = PIPE_VIDEO_FRAME;
- bs->mv_stream[0][i].bottom.weight = PIPE_VIDEO_MV_WEIGHT_MAX;
-
- bs->mv_stream[1][i].top.x = bs->mv_stream[1][i].top.y = 0;
- bs->mv_stream[1][i].top.field_select = PIPE_VIDEO_FRAME;
- bs->mv_stream[1][i].top.weight = PIPE_VIDEO_MV_WEIGHT_MIN;
- bs->mv_stream[1][i].bottom.x = bs->mv_stream[1][i].bottom.y = 0;
- bs->mv_stream[1][i].bottom.field_select = PIPE_VIDEO_FRAME;
- bs->mv_stream[1][i].bottom.weight = PIPE_VIDEO_MV_WEIGHT_MIN;
- }
+ bs->desc = *picture;
+ bs->intra_dct_tbl = picture->intra_vlc_format ? tbl_B15 : tbl_B14_AC;
}
void
-vl_mpg12_bs_decode(struct vl_mpg12_bs *bs, unsigned num_bytes, const void *buffer,
- struct pipe_mpeg12_picture_desc *picture, unsigned num_ycbcr_blocks[3])
+vl_mpg12_bs_decode(struct vl_mpg12_bs *bs, unsigned num_bytes, const uint8_t *buffer)
{
assert(bs);
- assert(num_ycbcr_blocks);
assert(buffer && num_bytes);
- bs->num_ycbcr_blocks = num_ycbcr_blocks;
+ while(num_bytes > 2) {
+ if (buffer[0] == 0x00 && buffer[1] == 0x00 && buffer[2] == 0x01 &&
+ buffer[3] >= 0x01 && buffer[3] < 0xAF) {
+ unsigned consumed;
+
+ buffer += 3;
+ num_bytes -= 3;
+
+ vl_vlc_init(&bs->vlc, buffer, num_bytes);
+
+ if (!decode_slice(bs))
+ return;
- vl_vlc_init(&bs->vlc, buffer, num_bytes);
+ /* it's possible for the vlc to consume up to eight extra bytes */
+ consumed = num_bytes - vl_vlc_bytes_left(&bs->vlc);
+ consumed = consumed > 8 ? consumed - 8 : 0;
- while(decode_slice(bs, picture));
+ /* crap, this is a bug we have consumed more bytes than left in the buffer */
+ assert(consumed <= num_bytes);
+
+ num_bytes -= consumed;
+ buffer += consumed;
+
+ } else {
+ ++buffer;
+ --num_bytes;
+ }
+ }
}
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.h b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.h
index 797a7e7..c3f14a1 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.h
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.h
@@ -30,32 +30,25 @@
#include "vl_defines.h"
#include "vl_vlc.h"
-#include "vl_vertex_buffers.h"
struct vl_mpg12_bs
{
- unsigned width, height;
+ struct pipe_video_decoder *decoder;
- struct vl_vlc vlc;
-
- unsigned block_num;
- unsigned *num_ycbcr_blocks;
+ struct pipe_mpeg12_picture_desc desc;
+ struct dct_coeff *intra_dct_tbl;
- struct vl_ycbcr_block *ycbcr_stream[VL_MAX_PLANES];
- short *ycbcr_buffer;
-
- struct vl_motionvector *mv_stream[VL_MAX_REF_FRAMES];
+ struct vl_vlc vlc;
+ short pred_dc[3];
};
void
-vl_mpg12_bs_init(struct vl_mpg12_bs *bs, unsigned width, unsigned height);
+vl_mpg12_bs_init(struct vl_mpg12_bs *bs, struct pipe_video_decoder *decoder);
void
-vl_mpg12_bs_set_buffers(struct vl_mpg12_bs *bs, struct vl_ycbcr_block *ycbcr_stream[VL_MAX_PLANES],
- short *ycbcr_buffer, struct vl_motionvector *mv_stream[VL_MAX_REF_FRAMES]);
+vl_mpg12_bs_set_picture_desc(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc *picture);
void
-vl_mpg12_bs_decode(struct vl_mpg12_bs *bs, unsigned num_bytes, const void *buffer,
- struct pipe_mpeg12_picture_desc *picture, unsigned num_ycbcr_blocks[3]);
+vl_mpg12_bs_decode(struct vl_mpg12_bs *bs, unsigned num_bytes, const uint8_t *buffer);
#endif /* vl_mpeg12_bitstream_h */
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
index a270667..e0b477d 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
@@ -450,9 +450,7 @@ vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder)
goto error_zscan;
if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
- vl_mpg12_bs_init(&buffer->bs,
- dec->base.width / MACROBLOCK_WIDTH,
- dec->base.height / MACROBLOCK_HEIGHT);
+ vl_mpg12_bs_init(&buffer->bs, decoder);
return buffer;
@@ -614,7 +612,7 @@ vl_mpeg12_begin_frame(struct pipe_video_decoder *decoder)
buf->mv_stream[i] = vl_vb_get_mv_stream(&buf->vertex_stream, i);
if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
- vl_mpg12_bs_set_buffers(&buf->bs, buf->ycbcr_stream, buf->texels, buf->mv_stream);
+ vl_mpg12_bs_set_picture_desc(&buf->bs, &dec->picture_desc);
} else {
@@ -708,7 +706,7 @@ vl_mpeg12_decode_bitstream(struct pipe_video_decoder *decoder,
vl_zscan_set_layout(&buf->zscan[i], dec->picture_desc.alternate_scan ?
dec->zscan_alternate : dec->zscan_normal);
- vl_mpg12_bs_decode(&buf->bs, num_bytes, data, &dec->picture_desc, buf->num_ycbcr_blocks);
+ vl_mpg12_bs_decode(&buf->bs, num_bytes, data);
}
static void
diff --git a/src/gallium/auxiliary/vl/vl_vlc.h b/src/gallium/auxiliary/vl/vl_vlc.h
index e81b1e9..17a7b65 100644
--- a/src/gallium/auxiliary/vl/vl_vlc.h
+++ b/src/gallium/auxiliary/vl/vl_vlc.h
@@ -25,116 +25,147 @@
*
**************************************************************************/
-/**
- * This file is based uppon slice_xvmc.c and vlc.h from the xine project,
- * which in turn is based on mpeg2dec. The following is the original copyright:
- *
- * Copyright (C) 2000-2002 Michel Lespinasse <walken at zoy.org>
- * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma at ess.engr.uvic.ca>
- *
- * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
- * See http://libmpeg2.sourceforge.net/ for updates.
- *
- * mpeg2dec is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpeg2dec is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
#ifndef vl_vlc_h
#define vl_vlc_h
-#include "pipe/p_compiler.h"
+#include <assert.h>
+
+#include <pipe/p_compiler.h>
+
+#include <util/u_math.h>
struct vl_vlc
{
- uint32_t buf; /* current 32 bit working set of buffer */
- int bits; /* used bits in working set */
- const uint8_t *ptr; /* buffer with stream data */
- const uint8_t *max; /* ptr+len of buffer */
+ uint64_t buffer;
+ unsigned valid_bits;
+ uint32_t *data;
+ uint32_t *end;
+};
+
+struct vl_vlc_entry
+{
+ int8_t length;
+ int8_t value;
+};
+
+struct vl_vlc_compressed
+{
+ uint16_t bitcode;
+ struct vl_vlc_entry entry;
};
static INLINE void
-vl_vlc_restart(struct vl_vlc *vlc)
+vl_vlc_init_table(struct vl_vlc_entry *dst, unsigned dst_size, const struct vl_vlc_compressed *src, unsigned src_size)
{
- vlc->buf = (vlc->ptr[0] << 24) | (vlc->ptr[1] << 16) | (vlc->ptr[2] << 8) | vlc->ptr[3];
- vlc->bits = -16;
- vlc->ptr += 4;
+ unsigned i, bits = util_logbase2(dst_size);
+
+ for (i=0;i<dst_size;++i) {
+ dst[i].length = 0;
+ dst[i].value = 0;
+ }
+
+ for(; src_size > 0; --src_size, ++src) {
+ for(i=0; i<(1 << (bits - src->entry.length)); ++i)
+ dst[src->bitcode >> (16 - bits) | i] = src->entry;
+ }
+}
+
+static INLINE void
+vl_vlc_fillbits(struct vl_vlc *vlc)
+{
+ if (vlc->valid_bits < 32) {
+ uint32_t value = *vlc->data;
+
+ //assert(vlc->data <= vlc->end);
+
+#ifndef PIPE_ARCH_BIG_ENDIAN
+ value = util_bswap32(value);
+#endif
+
+ vlc->buffer |= (uint64_t)value << (32 - vlc->valid_bits);
+ ++vlc->data;
+ vlc->valid_bits += 32;
+ }
}
static INLINE void
vl_vlc_init(struct vl_vlc *vlc, const uint8_t *data, unsigned len)
{
- vlc->ptr = data;
- vlc->max = data + len;
- vl_vlc_restart(vlc);
+ assert(vlc);
+ assert(data && len);
+
+ vlc->buffer = 0;
+ vlc->valid_bits = 0;
+
+ /* align the data pointer */
+ while((uint64_t)data & 3) {
+ vlc->buffer |= (uint64_t)*data << (56 - vlc->valid_bits);
+ ++data;
+ --len;
+ vlc->valid_bits += 8;
+ }
+ vlc->data = (uint32_t*)data;
+ vlc->end = (uint32_t*)(data + len);
+
+ vl_vlc_fillbits(vlc);
+ vl_vlc_fillbits(vlc);
+}
+
+static INLINE unsigned
+vl_vlc_bytes_left(struct vl_vlc *vlc)
+{
+ return ((uint8_t*)vlc->end)-((uint8_t*)vlc->data);
}
-static INLINE bool
-vl_vlc_getbyte(struct vl_vlc *vlc)
+static INLINE unsigned
+vl_vlc_peekbits(struct vl_vlc *vlc, unsigned num_bits)
{
- vlc->buf <<= 8;
- vlc->buf |= vlc->ptr[0];
- vlc->ptr++;
- return vlc->ptr < vlc->max;
+ //assert(vlc->valid_bits >= num_bits);
+
+ return vlc->buffer >> (64 - num_bits);
}
-#define vl_vlc_getword(vlc, shift) \
-do { \
- (vlc)->buf |= (((vlc)->ptr[0] << 8) | (vlc)->ptr[1]) << (shift); \
- (vlc)->ptr += 2; \
-} while (0)
-
-/* make sure that there are at least 16 valid bits in bit_buf */
-#define vl_vlc_needbits(vlc) \
-do { \
- if ((vlc)->bits >= 0) { \
- vl_vlc_getword(vlc, (vlc)->bits); \
- (vlc)->bits -= 16; \
- } \
-} while (0)
-
-/* make sure that the full 32 bit of the buffer are valid */
static INLINE void
-vl_vlc_need32bits(struct vl_vlc *vlc)
+vl_vlc_eatbits(struct vl_vlc *vlc, unsigned num_bits)
{
- vl_vlc_needbits(vlc);
- if (vlc->bits > -8) {
- unsigned n = -vlc->bits;
- vlc->buf <<= n;
- vlc->buf |= *vlc->ptr << 8;
- vlc->bits = -8;
- vlc->ptr++;
- }
- if (vlc->bits > -16) {
- unsigned n = -vlc->bits - 8;
- vlc->buf <<= n;
- vlc->buf |= *vlc->ptr;
- vlc->bits = -16;
- vlc->ptr++;
- }
+ //assert(vlc->valid_bits > num_bits);
+
+ vlc->buffer <<= num_bits;
+ vlc->valid_bits -= num_bits;
}
-/* remove num valid bits from bit_buf */
-#define vl_vlc_dumpbits(vlc, num) \
-do { \
- (vlc)->buf <<= (num); \
- (vlc)->bits += (num); \
-} while (0)
+static INLINE unsigned
+vl_vlc_get_uimsbf(struct vl_vlc *vlc, unsigned num_bits)
+{
+ unsigned value;
+
+ //assert(vlc->valid_bits >= num_bits);
+
+ value = vlc->buffer >> (64 - num_bits);
+ vl_vlc_eatbits(vlc, num_bits);
+
+ return value;
+}
+
+static INLINE signed
+vl_vlc_get_simsbf(struct vl_vlc *vlc, unsigned num_bits)
+{
+ signed value;
+
+ //assert(vlc->valid_bits >= num_bits);
+
+ value = ((int64_t)vlc->buffer) >> (64 - num_bits);
+ vl_vlc_eatbits(vlc, num_bits);
-/* take num bits from the high part of bit_buf and zero extend them */
-#define vl_vlc_ubits(vlc, num) (((uint32_t)((vlc)->buf)) >> (32 - (num)))
+ return value;
+}
-/* take num bits from the high part of bit_buf and sign extend them */
-#define vl_vlc_sbits(vlc, num) (((int32_t)((vlc)->buf)) >> (32 - (num)))
+static INLINE int8_t
+vl_vlc_get_vlclbf(struct vl_vlc *vlc, const struct vl_vlc_entry *tbl, unsigned num_bits)
+{
+ tbl += vl_vlc_peekbits(vlc, num_bits);
+ vl_vlc_eatbits(vlc, tbl->length);
+ return tbl->value;
+}
#endif /* vl_vlc_h */
diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h
index 8166ac7..f655ed4 100644
--- a/src/gallium/include/pipe/p_video_state.h
+++ b/src/gallium/include/pipe/p_video_state.h
@@ -44,6 +44,17 @@ struct pipe_video_rect
};
/*
+ * see table 6-12 in the spec
+ */
+enum pipe_mpeg12_picture_coding_type
+{
+ PIPE_MPEG12_PICTURE_CODING_TYPE_I = 0x01,
+ PIPE_MPEG12_PICTURE_CODING_TYPE_P = 0x02,
+ PIPE_MPEG12_PICTURE_CODING_TYPE_B = 0x03,
+ PIPE_MPEG12_PICTURE_CODING_TYPE_D = 0x04
+};
+
+/*
* see table 6-14 in the spec
*/
enum pipe_mpeg12_picture_structure
--
1.7.4.1
More information about the mesa-dev
mailing list