summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/mpegplay/decoderClass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mpeglib/lib/mpegplay/decoderClass.cpp')
-rw-r--r--mpeglib/lib/mpegplay/decoderClass.cpp893
1 files changed, 893 insertions, 0 deletions
diff --git a/mpeglib/lib/mpegplay/decoderClass.cpp b/mpeglib/lib/mpegplay/decoderClass.cpp
new file mode 100644
index 00000000..e259c8e6
--- /dev/null
+++ b/mpeglib/lib/mpegplay/decoderClass.cpp
@@ -0,0 +1,893 @@
+/*
+ class for decoders
+ Copyright (C) 1999 Martin Vogt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#include "decoderClass.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+
+#ifndef NDEBUG
+#define NDEBUG
+#endif
+#include <assert.h>
+
+
+#define DEBUG_DECODERCLASS(x)
+//#define DEBUG_DECODERCLASS(x) x
+
+/* Array mapping zigzag to array pointer offset. */
+
+
+static const int zigzag_direct_nommx[64] = {
+ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12,
+ 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35,
+ 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
+
+
+static const int zigzag_direct_mmx[64] = {
+
+ 0*8+0/* 0*/, 1*8+0/* 1*/, 0*8+1/* 8*/, 0*8+2/*16*/, 1*8+1/* 9*/, 2*8+0/* 2*/, 3*8+0/* 3*/, 2*8+1/*10*/,
+ 1*8+2/*17*/, 0*8+3/*24*/, 0*8+4/*32*/, 1*8+3/*25*/, 2*8+2/*18*/, 3*8+1/*11*/, 4*8+0/* 4*/, 5*8+0/* 5*/,
+ 4*8+1/*12*/, 5*8+2/*19*/, 2*8+3/*26*/, 1*8+4/*33*/, 0*8+5/*40*/, 0*8+6/*48*/, 1*8+5/*41*/, 2*8+4/*34*/,
+ 3*8+3/*27*/, 4*8+2/*20*/, 5*8+1/*13*/, 6*8+0/* 6*/, 7*8+0/* 7*/, 6*8+1/*14*/, 5*8+2/*21*/, 4*8+3/*28*/,
+ 3*8+4/*35*/, 2*8+5/*42*/, 1*8+6/*49*/, 0*8+7/*56*/, 1*8+7/*57*/, 2*8+6/*50*/, 3*8+5/*43*/, 4*8+4/*36*/,
+ 5*8+3/*29*/, 6*8+2/*22*/, 7*8+1/*15*/, 7*8+2/*23*/, 6*8+3/*30*/, 5*8+4/*37*/, 4*8+5/*44*/, 3*8+6/*51*/,
+ 2*8+7/*58*/, 3*8+7/*59*/, 4*8+6/*52*/, 5*8+5/*45*/, 6*8+4/*38*/, 7*8+3/*31*/, 7*8+4/*39*/, 6*8+5/*46*/,
+ 7*8+6/*53*/, 4*8+7/*60*/, 5*8+7/*61*/, 6*8+6/*54*/, 7*8+5/*47*/, 7*8+6/*55*/, 6*8+7/*62*/, 7*8+7/*63*/
+};
+
+
+
+
+
+/* Bit masks used by bit i/o operations. */
+
+
+
+static unsigned int bitMask[] = {0xffffffff,0x7fffffff,0x3fffffff,0x1fffffff,
+ 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
+ 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
+ 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
+ 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
+ 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
+ 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
+ 0x0000000f, 0x00000007, 0x00000003, 0x00000001};
+
+static unsigned int rBitMask[] = {0xffffffff,0xfffffffe,0xfffffffc,0xfffffff8,
+ 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
+ 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
+ 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
+ 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
+ 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
+ 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
+ 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000};
+
+static unsigned int bitTest[] = { 0x80000000,0x40000000,0x20000000,0x10000000,
+ 0x08000000, 0x04000000, 0x02000000, 0x01000000,
+ 0x00800000, 0x00400000, 0x00200000, 0x00100000,
+ 0x00080000, 0x00040000, 0x00020000, 0x00010000,
+ 0x00008000, 0x00004000, 0x00002000, 0x00001000,
+ 0x00000800, 0x00000400, 0x00000200, 0x00000100,
+ 0x00000080, 0x00000040, 0x00000020, 0x00000010,
+ 0x00000008, 0x00000004, 0x00000002, 0x00000001};
+
+
+
+
+
+DecoderClass::DecoderClass(VideoDecoder* vid_stream,
+ MpegVideoStream* mpegVideoStream) {
+
+ this->vid_stream=vid_stream;
+ this->mpegVideoStream=mpegVideoStream;
+
+
+#ifdef INTEL
+ lmmx=mm_support();
+#else
+ lmmx=false;
+ DEBUG_DECODERCLASS(cout << "no INTEL arch- disable MMX in decoderClass"<<endl;)
+
+#endif
+
+ if (lmmx==true) {
+ lmmx=4;
+ }
+
+ int i;
+ for(i=0;i<64;i++) {
+ zigzag_direct[i]=zigzag_direct_nommx[i];
+ }
+ if (lmmx) {
+ for(i=0;i<64;i++) {
+ // they are different !!!
+ zigzag_direct[i]=zigzag_direct_mmx[i];
+ }
+ }
+ for(i=64;i<256;i++) {
+ zigzag_direct[i]=0;
+ }
+ resetDCT();
+ reconptr = dct_recon[0];
+
+}
+
+
+DecoderClass::~DecoderClass() {
+}
+
+
+
+int DecoderClass::decodeDCTDCSizeLum() {
+ unsigned int macro_val;
+ unsigned int index;
+ index=mpegVideoStream->showBits(5);
+ if (index < 31) {
+ macro_val = dct_dc_size_luminance[index].value;
+ mpegVideoStream->flushBits(dct_dc_size_luminance[index].num_bits);
+ } else {
+ index=mpegVideoStream->showBits(9);
+ index -= 0x1f0;
+ macro_val = dct_dc_size_luminance1[index].value;
+ mpegVideoStream->flushBits(dct_dc_size_luminance1[index].num_bits);
+ }
+ return macro_val;
+}
+
+
+int DecoderClass::decodeDCTDCSizeChrom() {
+ unsigned int macro_val;
+ unsigned int index;
+ index=mpegVideoStream->showBits(5);
+ if (index < 31) {
+ macro_val = dct_dc_size_chrominance[index].value;
+ mpegVideoStream->flushBits(dct_dc_size_chrominance[index].num_bits);
+ }else {
+ index=mpegVideoStream->showBits(10);
+ index -= 0x3e0;
+ macro_val = dct_dc_size_chrominance1[index].value;
+ mpegVideoStream->flushBits(dct_dc_size_chrominance1[index].num_bits);
+ }
+ return macro_val;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeMBAddrInc --
+ *
+ * Huffman DecoderClass for macro_block_address_increment; the location
+ * in which the result will be placed is being passed as argument.
+ * The decoded value is obtained by doing a table lookup on
+ * mb_addr_inc.
+ *
+ * Results:
+ * The decoded value for macro_block_address_increment or MPGDECODE_ERROR
+ * for unbound values will be placed in the location specified.
+ *
+ * Side effects:
+ * Bit stream is irreversibly parsed.
+ *
+ *--------------------------------------------------------------
+ */
+int DecoderClass::decodeMBAddrInc() {
+ unsigned int index;
+ int val;
+ index=mpegVideoStream->showBits(11);
+ val = mb_addr_inc[index].value;
+ mpegVideoStream->flushBits(mb_addr_inc[index].num_bits);
+ if (mb_addr_inc[index].num_bits==0) {
+ DEBUG_DECODERCLASS(cout<<"num_bits==0"<<endl;)
+ val=1;
+ }
+
+ if (val == -1) {
+ DEBUG_DECODERCLASS(cout <<"EROR: decodeMBAddrInc"<<endl;)
+ val=MB_STUFFING;
+ }
+ return val;
+
+}
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeMotionVectors --
+ *
+ * Huffman DecoderClass for the various motion vectors, including
+ * motion_horizontal_forward_code, motion_vertical_forward_code,
+ * motion_horizontal_backward_code, motion_vertical_backward_code.
+ * Location where the decoded result will be placed is being passed
+ * as argument. The decoded values are obtained by doing a table
+ * lookup on motion_vectors.
+ *
+ * Results:
+ * The decoded value for the motion vector or MPGDECODE_ERROR for unbound
+ * values will be placed in the location specified.
+ *
+ * Side effects:
+ * Bit stream is irreversibly parsed.
+ *
+ *--------------------------------------------------------------
+ */
+int DecoderClass::decodeMotionVectors() {
+ unsigned int index;
+ int value;
+ index=mpegVideoStream->showBits(11);
+ value = motion_vectors[index].code;
+
+ mpegVideoStream->flushBits(motion_vectors[index].num_bits);
+ return value;
+}
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeCBP --
+ *
+ * Huffman DecoderClass for coded_block_pattern; location in which the
+ * decoded result will be placed is being passed as argument. The
+ * decoded values are obtained by doing a table lookup on
+ * coded_block_pattern.
+ *
+ * Results:
+ * The decoded value for coded_block_pattern or MPGDECODE_ERROR for unbound
+ * values will be placed in the location specified.
+ *
+ * Side effects:
+ * Bit stream is irreversibly parsed.
+ *
+ *--------------------------------------------------------------
+ */
+int DecoderClass::decodeCBP() {
+ unsigned int index;
+ unsigned int coded_bp;
+ index=mpegVideoStream->showBits(9);
+ coded_bp = coded_block_pattern[index].cbp;
+ mpegVideoStream->flushBits(coded_block_pattern[index].num_bits);
+ return coded_bp;
+}
+
+
+
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeMBTypeB --
+ *
+ * Huffman Decoder for macro_block_type in bidirectionally-coded
+ * pictures;locations in which the decoded results: macroblock_quant,
+ * macroblock_motion_forward, macro_block_motion_backward,
+ * macroblock_pattern, macro_block_intra, will be placed are
+ * being passed as argument. The decoded values are obtained by
+ * doing a table lookup on mb_type_B.
+ *
+ * Results:
+ * The various decoded values for macro_block_type in
+ * bidirectionally-coded pictures or MPGDECODE_ERROR for unbound values will
+ * be placed in the locations specified.
+ *
+ * Side effects:
+ * Bit stream is irreversibly parsed.
+ *
+ *--------------------------------------------------------------
+ */
+void DecoderClass::decodeMBTypeB(int& quant,int& motion_fwd,
+ int& motion_bwd,int& pat,int& intra){
+ unsigned int index;
+
+ index=mpegVideoStream->showBits(6);
+
+ quant = mb_type_B[index].mb_quant;
+ motion_fwd = mb_type_B[index].mb_motion_forward;
+ motion_bwd = mb_type_B[index].mb_motion_backward;
+ pat = mb_type_B[index].mb_pattern;
+ intra = mb_type_B[index].mb_intra;
+ if (index == 0) {
+ DEBUG_DECODERCLASS(cout << "error in decodeMBTypeB"<<endl;)
+ }
+ mpegVideoStream->flushBits(mb_type_B[index].num_bits);
+}
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeMBTypeI --
+ *
+ * Huffman Decoder for macro_block_type in intra-coded pictures;
+ * locations in which the decoded results: macroblock_quant,
+ * macroblock_motion_forward, macro_block_motion_backward,
+ * macroblock_pattern, macro_block_intra, will be placed are
+ * being passed as argument.
+ *
+ * Results:
+ * The various decoded values for macro_block_type in intra-coded
+ * pictures or MPGDECODE_ERROR for unbound values will be placed in the
+ * locations specified.
+ *
+ * Side effects:
+ * Bit stream is irreversibly parsed.
+ *
+ *--------------------------------------------------------------
+ */
+void DecoderClass::decodeMBTypeI(int& quant,int& motion_fwd,
+ int& motion_bwd,int& pat,int& intra) {
+
+ unsigned int index;
+ static int quantTbl[4] = {MPGDECODE_ERROR, 1, 0, 0};
+
+ index=mpegVideoStream->showBits(2);
+
+ motion_fwd = 0;
+ motion_bwd = 0;
+ pat = 0;
+ intra = 1;
+ quant = quantTbl[index];
+ if (quant == MPGDECODE_ERROR) {
+ DEBUG_DECODERCLASS(cout << "decodeMBTypeI Error"<<endl;)
+ }
+ if (index) {
+ mpegVideoStream->flushBits (1 + quant);
+ }
+
+}
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeMBTypeP --
+ *
+ * Huffman Decoder for macro_block_type in predictive-coded pictures;
+ * locations in which the decoded results: macroblock_quant,
+ * macroblock_motion_forward, macro_block_motion_backward,
+ * macroblock_pattern, macro_block_intra, will be placed are
+ * being passed as argument. The decoded values are obtained by
+ * doing a table lookup on mb_type_P.
+ *
+ * Results:
+ * The various decoded values for macro_block_type in
+ * predictive-coded pictures or MPGDECODE_ERROR for unbound values will be
+ * placed in the locations specified.
+ *
+ * Side effects:
+ * Bit stream is irreversibly parsed.
+ *
+ *--------------------------------------------------------------
+ */
+void DecoderClass::decodeMBTypeP(int& quant,int& motion_fwd,
+ int& motion_bwd,int& pat,int& intra) {
+
+ unsigned int index;
+
+ index=mpegVideoStream->showBits(6);
+
+ quant = mb_type_P[index].mb_quant;
+ motion_fwd = mb_type_P[index].mb_motion_forward;
+ motion_bwd = mb_type_P[index].mb_motion_backward;
+ pat = mb_type_P[index].mb_pattern;
+ intra = mb_type_P[index].mb_intra;
+ if (index == 0) {
+ DEBUG_DECODERCLASS(cout << "error in decodeMBTypeP"<<endl;)
+ }
+ mpegVideoStream->flushBits(mb_type_P[index].num_bits);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * decodeDCTCoeff --
+ *
+ * Huffman Decoder for dct_coeff_first and dct_coeff_next;
+ * locations where the results of decoding: run and level, are to
+ * be placed and also the type of DCT coefficients, either
+ * dct_coeff_first or dct_coeff_next, are being passed as argument.
+ *
+ * The decoder first examines the next 8 bits in the input stream,
+ * and perform according to the following cases:
+ *
+ * '0000 0000' - examine 8 more bits (i.e. 16 bits total) and
+ * perform a table lookup on dct_coeff_tbl_0.
+ * One more bit is then examined to determine the sign
+ * of level.
+ *
+ * '0000 0001' - examine 4 more bits (i.e. 12 bits total) and
+ * perform a table lookup on dct_coeff_tbl_1.
+ * One more bit is then examined to determine the sign
+ * of level.
+ *
+ * '0000 0010' - examine 2 more bits (i.e. 10 bits total) and
+ * perform a table lookup on dct_coeff_tbl_2.
+ * One more bit is then examined to determine the sign
+ * of level.
+ *
+ * '0000 0011' - examine 2 more bits (i.e. 10 bits total) and
+ * perform a table lookup on dct_coeff_tbl_3.
+ * One more bit is then examined to determine the sign
+ * of level.
+ *
+ * otherwise - perform a table lookup on dct_coeff_tbl. If the
+ * value of run is not ESCAPE, extract one more bit
+ * to determine the sign of level; otherwise 6 more
+ * bits will be extracted to obtain the actual value
+ * of run , and then 8 or 16 bits to get the value of level.
+ *
+ *
+ *
+ * Results:
+ * The decoded values of run and level or MPGDECODE_ERROR
+ * for unbound values
+ * are placed in the locations specified.
+ *
+ * Side effects:
+ * Bit stream is irreversibly parsed.
+ *
+ *--------------------------------------------------------------
+ */
+
+void DecoderClass::decodeDCTCoeff(unsigned short int* dct_coeff_tbl,
+ unsigned RUNTYPE& run,int& level) {
+
+
+ unsigned int temp, index;
+ unsigned int value, next32bits, flushed;
+
+ /*
+ * Grab the next 32 bits and use it to improve performance of
+ * getting the bits to parse. Thus, calls are translated as:
+ *
+ * show_bitsX <--> next32bits >> (32-X)
+ * get_bitsX <--> val = next32bits >> (32-flushed-X);
+ * flushed += X;
+ * next32bits &= bitMask[flushed];
+ * flush_bitsX <--> flushed += X;
+ * next32bits &= bitMask[flushed];
+ *
+ */
+ next32bits=mpegVideoStream->showBits32();
+
+ flushed = 0;
+
+ /* show_bits8(index); */
+ index = next32bits >> 24;
+
+ if (index > 3) {
+ value = dct_coeff_tbl[index];
+ run = (value & RUN_MASK) >> RUN_SHIFT;
+ if (run == END_OF_BLOCK) {
+ level = END_OF_BLOCK;
+ }
+ else {
+ /* num_bits = (value & NUM_MASK) + 1; */
+ /* flush_bits(num_bits); */
+ flushed = (value & NUM_MASK) + 1;
+ next32bits &= bitMask[flushed];
+ if (run != ESCAPE) {
+ level = (value & LEVEL_MASK) >> LEVEL_SHIFT;
+ /* get_bits1(value); */
+ /* if (value) *level = -*level; */
+ if (next32bits >> (31-flushed)) level = -level;
+ flushed++;
+ /* next32bits &= bitMask[flushed]; last op before update */
+ }
+ else { /* *run == ESCAPE */
+ /* get_bits14(temp); */
+ temp = next32bits >> (18-flushed);
+ flushed += 14;
+ next32bits &= bitMask[flushed];
+ run = temp >> 8;
+ temp &= 0xff;
+ if (temp == 0) {
+ /* get_bits8(*level); */
+ level = next32bits >> (24-flushed);
+ flushed += 8;
+ /* next32bits &= bitMask[flushed]; last op before update */
+ assert(level >= 128);
+ } else if (temp != 128) {
+ /* Grab sign bit */
+ level = ((int) (temp << 24)) >> 24;
+ } else {
+ /* get_bits8(*level); */
+ level = next32bits >> (24-flushed);
+ flushed += 8;
+ /* next32bits &= bitMask[flushed]; last op before update */
+ level = level - 256;
+ assert(level <= -128 && level >= -255);
+ }
+ }
+ /* Update bitstream... */
+ mpegVideoStream->flushBitsDirect(flushed);
+ }
+ }
+ else {
+ if (index == 2) {
+ /* show_bits10(index); */
+ index = next32bits >> 22;
+ value = dct_coeff_tbl_2[index & 3];
+ }
+ else if (index == 3) {
+ /* show_bits10(index); */
+ index = next32bits >> 22;
+ value = dct_coeff_tbl_3[index & 3];
+ }
+ else if (index) { /* index == 1 */
+ /* show_bits12(index); */
+ index = next32bits >> 20;
+ value = dct_coeff_tbl_1[index & 15];
+ }
+ else { /* index == 0 */
+ /* show_bits16(index); */
+ index = next32bits >> 16;
+ value = dct_coeff_tbl_0[index & 255];
+ }
+ run = (value & RUN_MASK) >> RUN_SHIFT;
+ level = (value & LEVEL_MASK) >> LEVEL_SHIFT;
+
+ /*
+ * Fold these operations together to make it fast...
+ */
+ /* num_bits = (value & NUM_MASK) + 1; */
+ /* flush_bits(num_bits); */
+ /* get_bits1(value); */
+ /* if (value) *level = -*level; */
+
+ flushed = (value & NUM_MASK) + 2;
+ if ((next32bits >> (32-flushed)) & 0x1) level = -level;
+
+ /* Update bitstream ... */
+ mpegVideoStream->flushBitsDirect(flushed);
+
+ }
+
+}
+
+
+void DecoderClass::resetDCT() {
+ /* Reset past dct dc y, cr, and cb values. */
+
+ dct_dc_y_past = 1024 << 3;
+ dct_dc_cr_past = 1024 << 3;
+ dct_dc_cb_past = 1024 << 3;
+
+}
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ParseReconBlock --
+ *
+ * Parse values for block structure from bitstream.
+ * n is an indication of the position of the block within
+ * the macroblock (i.e. 0-5) and indicates the type of
+ * block (i.e. luminance or chrominance). Reconstructs
+ * coefficients from values parsed and puts in
+ * block.dct_recon array in vid stream structure.
+ * sparseFlag is set when the block contains only one
+ * coeffictient and is used by the IDCT.
+ *
+ * Results:
+ *
+ *
+ * Side effects:
+ * Bit stream irreversibly parsed.
+ *
+ *--------------------------------------------------------------
+ */
+
+
+void DecoderClass::ParseReconBlock(int& n,int& mb_intra,
+ unsigned int& qscale,
+ int& lflag,
+ unsigned int* iqmatrixptr,
+ unsigned int* niqmatrixptr) {
+
+
+
+
+ int coeffCount=0;
+ if (mpegVideoStream->hasBytes(512) == false) {
+ DEBUG_DECODERCLASS(cout << "cannot get 512 raw bytes"<<endl;)
+ return;
+ }
+
+ {
+ /*
+ * Copy the VideoDecoder fields curBits, bitOffset, and bitBuffer
+ * into local variables with the same names, so the macros use the
+ * local variables instead. This allows register allocation and
+ * can provide 1-2 fps speedup. On machines with not so many registers,
+ * don't do this.
+ */
+ int size, pos, coeff;
+ int level;
+ unsigned RUNTYPE run;
+ unsigned RUNTYPE i;
+
+
+ memset((char *) dct_recon, 0, 64*sizeof(short int));
+
+ if (mb_intra) {
+
+ if (n < 4) {
+
+ /*
+ * Get the luminance bits. This code has been hand optimized to
+ * get by the normal bit parsing routines. We get some speedup
+ * by grabbing the next 16 bits and parsing things locally.
+ * Thus, calls are translated as:
+ *
+ * show_bitsX <--> next16bits >> (16-X)
+ * get_bitsX <--> val = next16bits >> (16-flushed-X);
+ * flushed += X;
+ * next16bits &= bitMask[flushed];
+ * flush_bitsX <--> flushed += X;
+ * next16bits &= bitMask[flushed];
+ *
+ * I've streamlined the code a lot, so that we don't have to mask
+ * out the low order bits and a few of the extra adds are removed.
+ * bsmith
+ */
+ unsigned int next16bits, index, flushed;
+ next16bits=mpegVideoStream->showBits16();
+
+ index = next16bits >> (16-5);
+ if (index < 31) {
+ size = dct_dc_size_luminance[index].value;
+ flushed = dct_dc_size_luminance[index].num_bits;
+ } else {
+ index = next16bits >> (16-9);
+ index -= 0x1f0;
+ size = dct_dc_size_luminance1[index].value;
+ flushed = dct_dc_size_luminance1[index].num_bits;
+ }
+ next16bits &= bitMask[(16+flushed)&0x1f];
+ if (size != 0) {
+ flushed += size;
+ coeff = next16bits >> (16-flushed);
+ if (!(coeff & bitTest[32-size])) {
+ coeff++;
+ coeff|= rBitMask[size&0x1f];
+ }
+ coeff <<= 3;
+ } else {
+ coeff = 0;
+ }
+ mpegVideoStream->flushBitsDirect(flushed);
+
+ if ( (n == 0) && (lflag) ) {
+ coeff += 1024;
+ } else {
+ coeff += dct_dc_y_past;
+ }
+ dct_dc_y_past = coeff;
+
+ } else { /* n = 4 or 5 */
+ /*
+ * Get the chrominance bits. This code has been hand optimized to
+ * as described above
+ */
+
+ unsigned int next16bits, index, flushed;
+ next16bits=mpegVideoStream->showBits16();
+
+ index = next16bits >> (16-5);
+ if (index < 31) {
+ size = dct_dc_size_chrominance[index].value;
+ flushed = dct_dc_size_chrominance[index].num_bits;
+ } else {
+ index = next16bits >> (16-10);
+ index -= 0x3e0;
+ size = dct_dc_size_chrominance1[index].value;
+ flushed = dct_dc_size_chrominance1[index].num_bits;
+ }
+ next16bits &= bitMask[(16+flushed)&0x1f];
+
+ if (size != 0) {
+ flushed += size;
+ coeff = next16bits >> (16-flushed);
+ if (!(coeff & bitTest[32-size])) {
+ coeff++;
+ coeff|=rBitMask[size&0x1f];
+ }
+ coeff <<= 3;
+ } else {
+ coeff = 0;
+ }
+ mpegVideoStream->flushBitsDirect(flushed);
+
+ /* We test 5 first; a result of the mixup of Cr and Cb */
+
+ if (n == 5) {
+ if (lflag) {
+ coeff += 1024;
+ } else {
+ coeff += dct_dc_cr_past;
+ }
+ dct_dc_cr_past = coeff;
+ } else {
+ if (lflag) {
+ coeff += 1024;
+ } else {
+ coeff += dct_dc_cb_past;
+ }
+ dct_dc_cb_past = coeff;
+ }
+ }
+
+ coeff <<= lmmx;
+ reconptr[0] = coeff;
+
+ pos=0;
+ i = 0;
+ coeffCount = (coeff != 0);
+
+
+ // we never have d_types so there is no check
+
+
+ while(1) {
+ decodeDCTCoeff(dct_coeff_next,run,level);
+
+ if (run >=END_OF_BLOCK) {
+ break;
+ }
+ i++;
+ i+=run;
+ pos = zigzag_direct[i&0x3f];
+
+
+ coeff = (level * qscale * iqmatrixptr[pos]) >> 3 ;
+
+ if (level < 0) {
+ coeff += (1 - (coeff & 1));
+ } else {
+ coeff -= (1 - (coeff & 1));
+ }
+
+ coeff <<= lmmx;
+
+ reconptr[pos] = coeff;
+ coeffCount++;
+
+ }
+ mpegVideoStream->flushBitsDirect(2);
+
+ goto end;
+
+ } else { /* non-intra-coded macroblock */
+
+ decodeDCTCoeff(dct_coeff_first,run,level);
+ i = run;
+
+ pos = zigzag_direct[i&0x3f];
+
+ /* quantizes and oddifies each coefficient */
+ if (level < 0) {
+ coeff = ((level - 1) * qscale * niqmatrixptr[pos]) >>3;
+ if ((coeff & 1) == 0) {coeff++;}
+ } else {
+ coeff = ((level + 1) * qscale * niqmatrixptr[pos]) >>3;
+ coeff = (coeff-1) | 1;
+ }
+
+ coeff <<= lmmx;
+
+ reconptr[pos] = coeff;
+ coeffCount = (coeff!=0);
+
+ // we never have d_type pictures here, we do not support them
+
+ while(1) {
+ decodeDCTCoeff(dct_coeff_next,run,level);
+
+ if (run >= END_OF_BLOCK) {
+ break;
+ }
+ i++;
+ i+=run;
+ pos = zigzag_direct[i&0x3f];
+
+ if (level < 0) {
+ coeff = ((level - 1) * qscale * niqmatrixptr[pos]) >>3;
+ if ((coeff & 1) == 0) {coeff++;}
+ } else {
+ coeff = ((level + 1) * qscale * niqmatrixptr[pos]) >> 3;
+ coeff = (coeff-1) | 1;
+ }
+
+ coeff <<= lmmx;
+
+ reconptr[pos] = coeff;
+ coeffCount++;
+ } /* end while */
+
+ mpegVideoStream->flushBitsDirect(2);
+ goto end;
+ }
+
+ end:
+ if (coeffCount == 1) {
+ if (lmmx) {
+ emms();
+ reconptr[pos]>>=lmmx;
+ j_rev_dct_sparse (reconptr, pos);
+ //IDCT_mmx(reconptr);
+ } else {
+ j_rev_dct_sparse (reconptr, pos);
+ }
+
+ } else {
+
+ if (lmmx) {
+ IDCT_mmx(reconptr);
+ } else {
+ j_rev_dct(reconptr);
+ }
+
+ }
+ }
+
+ // we call this at the edn of the "critical sections"
+ /*
+ if (lmmx) {
+ emms();
+ }
+ */
+
+ return;
+
+}
+
+
+
+
+
+void DecoderClass::print() {
+ int i;
+ for(i=0;i<64;i++) {
+ printf(" %d ",zigzag_direct[i]);
+ }
+ printf("\n");
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+