mirror of https://github.com/PCSX2/pcsx2.git
1526 lines
34 KiB
C++
1526 lines
34 KiB
C++
/*
|
|
* Mpeg.c
|
|
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
|
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
|
* Modified by Florin for PCSX2 emu
|
|
*
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
// [Air] Note: many functions in this module are large and only used once, so they
|
|
// have been forced to inline since it won't bloat the program and gets rid of
|
|
// some call overhead.
|
|
|
|
#include "PrecompiledHeader.h"
|
|
|
|
#include "Common.h"
|
|
#include "IPU.h"
|
|
#include "Mpeg.h"
|
|
#include "Vlc.h"
|
|
#include "coroutine.h"
|
|
|
|
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
|
|
};
|
|
|
|
/* Bitstream and buffer needs to be reallocated in order for successful
|
|
reading of the old data. Here the old data stored in the 2nd slot
|
|
of the internal buffer is copied to 1st slot, and the new data read
|
|
into 1st slot is copied to the 2nd slot. Which will later be copied
|
|
back to the 1st slot when 128bits have been read.
|
|
*/
|
|
extern void ReorderBitstream();
|
|
|
|
int get_macroblock_modes(decoder_t * const decoder)
|
|
{
|
|
#define bit_buf (decoder->bitstream_buf)
|
|
#define bits (decoder->bitstream_bits)
|
|
#define bit_ptr (decoder->bitstream_ptr)
|
|
int macroblock_modes;
|
|
const MBtab * tab;
|
|
|
|
switch (decoder->coding_type)
|
|
{
|
|
|
|
case I_TYPE:
|
|
macroblock_modes = UBITS(bit_buf, 2);
|
|
|
|
if (macroblock_modes == 0) return 0; // error
|
|
|
|
tab = MB_I + (macroblock_modes >> 1);
|
|
DUMPBITS(bit_buf, bits, tab->len);
|
|
macroblock_modes = tab->modes;
|
|
|
|
if ((!(decoder->frame_pred_frame_dct)) &&
|
|
(decoder->picture_structure == FRAME_PICTURE))
|
|
{
|
|
macroblock_modes |= UBITS(bit_buf, 1) * DCT_TYPE_INTERLACED;
|
|
DUMPBITS(bit_buf, bits, 1);
|
|
}
|
|
return macroblock_modes;
|
|
|
|
case P_TYPE:
|
|
macroblock_modes = UBITS(bit_buf, 6);
|
|
|
|
if (macroblock_modes == 0) return 0; // error
|
|
|
|
tab = MB_P + (macroblock_modes >> 1);
|
|
DUMPBITS(bit_buf, bits, tab->len);
|
|
macroblock_modes = tab->modes;
|
|
|
|
if (decoder->picture_structure != FRAME_PICTURE)
|
|
{
|
|
if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
|
|
{
|
|
macroblock_modes |= UBITS(bit_buf, 2) * MOTION_TYPE_BASE;
|
|
DUMPBITS(bit_buf, bits, 2);
|
|
}
|
|
|
|
return macroblock_modes;
|
|
}
|
|
else if (decoder->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 |= UBITS(bit_buf, 2) * MOTION_TYPE_BASE;
|
|
DUMPBITS(bit_buf, bits, 2);
|
|
}
|
|
|
|
if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))
|
|
{
|
|
macroblock_modes |= UBITS(bit_buf, 1) * DCT_TYPE_INTERLACED;
|
|
DUMPBITS(bit_buf, bits, 1);
|
|
}
|
|
|
|
return macroblock_modes;
|
|
}
|
|
|
|
case B_TYPE:
|
|
macroblock_modes = UBITS(bit_buf, 6);
|
|
|
|
if (macroblock_modes == 0) return 0; // error
|
|
|
|
tab = MB_B + macroblock_modes;
|
|
DUMPBITS(bit_buf, bits, tab->len);
|
|
macroblock_modes = tab->modes;
|
|
|
|
if (decoder->picture_structure != FRAME_PICTURE)
|
|
{
|
|
if (!(macroblock_modes & MACROBLOCK_INTRA))
|
|
{
|
|
macroblock_modes |= UBITS(bit_buf, 2) * MOTION_TYPE_BASE;
|
|
DUMPBITS(bit_buf, bits, 2);
|
|
}
|
|
|
|
return macroblock_modes;
|
|
}
|
|
else if (decoder->frame_pred_frame_dct)
|
|
{
|
|
/* if (! (macroblock_modes & MACROBLOCK_INTRA)) */
|
|
macroblock_modes |= MC_FRAME;
|
|
return macroblock_modes;
|
|
}
|
|
else
|
|
{
|
|
if (macroblock_modes & MACROBLOCK_INTRA) goto intra;
|
|
|
|
macroblock_modes |= UBITS(bit_buf, 2) * MOTION_TYPE_BASE;
|
|
DUMPBITS(bit_buf, bits, 2);
|
|
|
|
if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))
|
|
{
|
|
intra:
|
|
macroblock_modes |= UBITS(bit_buf, 1) * DCT_TYPE_INTERLACED;
|
|
DUMPBITS(bit_buf, bits, 1);
|
|
}
|
|
|
|
return macroblock_modes;
|
|
}
|
|
|
|
case D_TYPE:
|
|
macroblock_modes = UBITS(bit_buf, 1);
|
|
|
|
if (macroblock_modes == 0) return 0; // error
|
|
|
|
DUMPBITS(bit_buf, bits, 1);
|
|
return MACROBLOCK_INTRA;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
#undef bit_buf
|
|
#undef bits
|
|
#undef bit_ptr
|
|
}
|
|
|
|
static __forceinline int get_quantizer_scale(decoder_t * const decoder)
|
|
{
|
|
int quantizer_scale_code;
|
|
|
|
quantizer_scale_code = UBITS(decoder->bitstream_buf, 5);
|
|
DUMPBITS(decoder->bitstream_buf, decoder->bitstream_bits, 5);
|
|
|
|
if (decoder->q_scale_type)
|
|
return non_linear_quantizer_scale [quantizer_scale_code];
|
|
else
|
|
return quantizer_scale_code << 1;
|
|
}
|
|
|
|
static __forceinline int get_coded_block_pattern(decoder_t * const decoder)
|
|
{
|
|
const CBPtab * tab;
|
|
|
|
NEEDBITS(decoder->bitstream_buf, decoder->bitstream_bits, decoder->bitstream_ptr);
|
|
|
|
if (decoder->bitstream_buf >= 0x20000000)
|
|
tab = CBP_7 + (UBITS(decoder->bitstream_buf, 7) - 16);
|
|
else
|
|
tab = CBP_9 + UBITS(decoder->bitstream_buf, 9);
|
|
|
|
DUMPBITS(decoder->bitstream_buf, decoder->bitstream_bits, tab->len);
|
|
return tab->cbp;
|
|
}
|
|
|
|
static __forceinline int get_luma_dc_dct_diff(decoder_t * const decoder)
|
|
{
|
|
#define bit_buf (decoder->bitstream_buf)
|
|
#define bits (decoder->bitstream_bits)
|
|
#define bit_ptr (decoder->bitstream_ptr)
|
|
|
|
const DCtab * tab;
|
|
int size;
|
|
int dc_diff;
|
|
|
|
if (bit_buf < 0xf8000000)
|
|
{
|
|
tab = DC_lum_5 + UBITS(bit_buf, 5);
|
|
size = tab->size;
|
|
|
|
if (size)
|
|
{
|
|
DUMPBITS(bit_buf, bits, tab->len);
|
|
bits += size;
|
|
dc_diff = UBITS(bit_buf, size) - UBITS(SBITS(~bit_buf, 1), size);
|
|
bit_buf <<= size;
|
|
return dc_diff;
|
|
}
|
|
else
|
|
{
|
|
DUMPBITS(bit_buf, bits, 3);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
tab = DC_long + (UBITS(bit_buf, 9) - 0x1e0); //0x1e0);
|
|
|
|
size = tab->size;
|
|
DUMPBITS(bit_buf, bits, tab->len);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
dc_diff = UBITS(bit_buf, size) - UBITS(SBITS(~bit_buf, 1), size);
|
|
DUMPBITS(bit_buf, bits, size);
|
|
return dc_diff;
|
|
#undef bit_buf
|
|
#undef bits
|
|
#undef bit_ptr
|
|
}
|
|
|
|
static __forceinline int get_chroma_dc_dct_diff(decoder_t * const decoder)
|
|
{
|
|
#define bit_buf (decoder->bitstream_buf)
|
|
#define bits (decoder->bitstream_bits)
|
|
#define bit_ptr (decoder->bitstream_ptr)
|
|
|
|
const DCtab * tab;
|
|
int size;
|
|
int dc_diff;
|
|
|
|
if (bit_buf < 0xf8000000)
|
|
{
|
|
tab = DC_chrom_5 + UBITS(bit_buf, 5);
|
|
size = tab->size;
|
|
|
|
if (size)
|
|
{
|
|
DUMPBITS(bit_buf, bits, tab->len);
|
|
bits += size;
|
|
dc_diff = UBITS(bit_buf, size) - UBITS(SBITS(~bit_buf, 1), size);
|
|
bit_buf <<= size;
|
|
return dc_diff;
|
|
}
|
|
else
|
|
{
|
|
DUMPBITS(bit_buf, bits, 2);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
tab = DC_long + (UBITS(bit_buf, 10) - 0x3e0);
|
|
|
|
size = tab->size;
|
|
DUMPBITS(bit_buf, bits, tab->len + 1);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
dc_diff = UBITS(bit_buf, size) - UBITS(SBITS(~bit_buf, 1), size);
|
|
DUMPBITS(bit_buf, bits, size);
|
|
return dc_diff;
|
|
#undef bit_buf
|
|
#undef bits
|
|
#undef bit_ptr
|
|
}
|
|
|
|
#define SATURATE(val) \
|
|
do { \
|
|
if (((u32)(val + 2048) > 4095)) \
|
|
val = SBITS (val, 1) ^ 2047; \
|
|
} while (0)
|
|
|
|
static __forceinline void get_intra_block_B14(decoder_t * const decoder)
|
|
{
|
|
int i;
|
|
int j;
|
|
int val;
|
|
const u8 * scan = decoder->scan;
|
|
const u8 * quant_matrix = decoder->intra_quantizer_matrix;
|
|
int quantizer_scale = decoder->quantizer_scale;
|
|
int mismatch;
|
|
const DCTtab * tab;
|
|
u32 bit_buf;
|
|
u8 * bit_ptr;
|
|
int bits;
|
|
s16 * dest;
|
|
|
|
dest = decoder->DCTblock;
|
|
i = 0;
|
|
mismatch = ~dest[0];
|
|
|
|
bit_buf = decoder->bitstream_buf;
|
|
bits = decoder->bitstream_bits;
|
|
bit_ptr = decoder->bitstream_ptr;
|
|
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
|
|
while (1)
|
|
{
|
|
if (bit_buf >= 0x28000000)
|
|
{
|
|
tab = DCT_B14AC_5 + (UBITS(bit_buf, 5) - 5);
|
|
i += tab->run;
|
|
if (i >= 64) break; /* end of block */
|
|
|
|
normal_code:
|
|
j = scan[i];
|
|
bit_buf <<= tab->len;
|
|
bits += tab->len + 1;
|
|
|
|
/* JayteeMaster: 10 points! Replaced quant_matrix[j] by quant_matrix[i] as should be */
|
|
val = (tab->level * quantizer_scale * quant_matrix[i]) >> 4;
|
|
|
|
/* if (bitstream_get (1)) val = -val; */
|
|
val = (val ^ SBITS(bit_buf, 1)) - SBITS(bit_buf, 1);
|
|
|
|
SATURATE(val);
|
|
dest[j] = val;
|
|
mismatch ^= val;
|
|
bit_buf <<= 1;
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
continue;
|
|
}
|
|
else if (bit_buf >= 0x04000000)
|
|
{
|
|
tab = DCT_B14_8 + (UBITS(bit_buf, 8) - 4);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
|
|
/* escape code */
|
|
|
|
i += UBITS(bit_buf << 6, 6) - 64;
|
|
|
|
if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */
|
|
|
|
j = scan[i];
|
|
|
|
DUMPBITS(bit_buf, bits, 12);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
|
|
/* JayteeMaster: 10 points! Replaced quant_matrix[j] by quant_matrix[i] as should be */
|
|
val = (SBITS(bit_buf, 12) * quantizer_scale * quant_matrix[i]) / 16;
|
|
|
|
SATURATE(val);
|
|
dest[j] = val;
|
|
mismatch ^= val;
|
|
DUMPBITS(bit_buf, bits, 12);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
continue;
|
|
|
|
}
|
|
else if (bit_buf >= 0x02000000)
|
|
{
|
|
tab = DCT_B14_10 + (UBITS(bit_buf, 10) - 8);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else if (bit_buf >= 0x00800000)
|
|
{
|
|
tab = DCT_13 + (UBITS(bit_buf, 13) - 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else if (bit_buf >= 0x00200000)
|
|
{
|
|
tab = DCT_15 + (UBITS(bit_buf, 15) - 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else
|
|
{
|
|
tab = DCT_16 + UBITS(bit_buf, 16);
|
|
bit_buf <<= 16;
|
|
GETWORD(&bit_buf, bits + 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
|
|
break; /* illegal, check needed to avoid buffer overflow */
|
|
}
|
|
|
|
dest[63] ^= mismatch & 1;
|
|
|
|
if ((bit_buf >> 30) != 0x2) ipuRegs->ctrl.ECD = 1;
|
|
|
|
DUMPBITS(bit_buf, bits, tab->len); /* dump end of block code */
|
|
|
|
decoder->bitstream_buf = bit_buf;
|
|
decoder->bitstream_bits = bits;
|
|
}
|
|
|
|
static __forceinline void get_intra_block_B15(decoder_t * const decoder)
|
|
{
|
|
int i;
|
|
int j;
|
|
int val;
|
|
const u8 * scan = decoder->scan;
|
|
const u8 * quant_matrix = decoder->intra_quantizer_matrix;
|
|
int quantizer_scale = decoder->quantizer_scale;
|
|
int mismatch;
|
|
const DCTtab * tab;
|
|
u32 bit_buf;
|
|
u8 * bit_ptr;
|
|
int bits;
|
|
s16 * dest;
|
|
|
|
dest = decoder->DCTblock;
|
|
i = 0;
|
|
mismatch = ~dest[0];
|
|
|
|
bit_buf = decoder->bitstream_buf;
|
|
bits = decoder->bitstream_bits;
|
|
bit_ptr = decoder->bitstream_ptr;
|
|
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
|
|
while (1)
|
|
{
|
|
if (bit_buf >= 0x04000000)
|
|
{
|
|
tab = DCT_B15_8 + (UBITS(bit_buf, 8) - 4);
|
|
i += tab->run;
|
|
|
|
if (i < 64)
|
|
{
|
|
normal_code:
|
|
j = scan[i];
|
|
bit_buf <<= tab->len;
|
|
bits += tab->len + 1;
|
|
/* JayteeMaster: 10 points! Replaced quant_matrix[j] by quant_matrix[i] as should be */
|
|
val = (tab->level * quantizer_scale * quant_matrix[i]) >> 4;
|
|
|
|
/* if (bitstream_get (1)) val = -val; */
|
|
val = (val ^ SBITS(bit_buf, 1)) - SBITS(bit_buf, 1);
|
|
|
|
SATURATE(val);
|
|
dest[j] = val;
|
|
mismatch ^= val;
|
|
|
|
bit_buf <<= 1;
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
|
|
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(bit_buf << 6, 6) - 64;
|
|
|
|
if (i >= 64) break; /* illegal, check against buffer overflow */
|
|
|
|
j = scan[i];
|
|
DUMPBITS(bit_buf, bits, 12);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
|
|
/* JayteeMaster: 10 points! Replaced quant_matrix[j] by quant_matrix[i] as should be */
|
|
val = (SBITS(bit_buf, 12) * quantizer_scale * quant_matrix[i]) / 16;
|
|
|
|
SATURATE(val);
|
|
dest[j] = val;
|
|
mismatch ^= val;
|
|
DUMPBITS(bit_buf, bits, 12);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
continue;
|
|
}
|
|
}
|
|
else if (bit_buf >= 0x02000000)
|
|
{
|
|
tab = DCT_B15_10 + (UBITS(bit_buf, 10) - 8);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else if (bit_buf >= 0x00800000)
|
|
{
|
|
tab = DCT_13 + (UBITS(bit_buf, 13) - 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else if (bit_buf >= 0x00200000)
|
|
{
|
|
tab = DCT_15 + (UBITS(bit_buf, 15) - 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else
|
|
{
|
|
tab = DCT_16 + UBITS(bit_buf, 16);
|
|
bit_buf <<= 16;
|
|
GETWORD(&bit_buf, bits + 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
|
|
break; /* illegal, check needed to avoid buffer overflow */
|
|
}
|
|
|
|
dest[63] ^= mismatch & 1;
|
|
|
|
if ((bit_buf >> 28) != 0x6)
|
|
ipuRegs->ctrl.ECD = 1;
|
|
|
|
DUMPBITS(bit_buf, bits, tab->len); /* dump end of block code */
|
|
|
|
decoder->bitstream_buf = bit_buf;
|
|
|
|
decoder->bitstream_bits = bits;
|
|
}
|
|
|
|
static __forceinline int get_non_intra_block(decoder_t * const decoder)
|
|
{
|
|
#define bit_buf (decoder->bitstream_buf)
|
|
#define bits (decoder->bitstream_bits)
|
|
#define bit_ptr (decoder->bitstream_ptr)
|
|
int i;
|
|
int j;
|
|
int val;
|
|
const u8 * scan = decoder->scan;
|
|
const u8 * quant_matrix = decoder->non_intra_quantizer_matrix;
|
|
int quantizer_scale = decoder->quantizer_scale;
|
|
int mismatch;
|
|
const DCTtab * tab;
|
|
s16 * dest;
|
|
|
|
i = -1;
|
|
mismatch = -1;
|
|
dest = decoder->DCTblock;
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
|
|
if (bit_buf >= 0x28000000)
|
|
{
|
|
tab = DCT_B14DC_5 + (UBITS(bit_buf, 5) - 5);
|
|
goto entry_1;
|
|
}
|
|
else
|
|
goto entry_2;
|
|
|
|
while (1)
|
|
{
|
|
if (bit_buf >= 0x28000000)
|
|
{
|
|
tab = DCT_B14AC_5 + (UBITS(bit_buf, 5) - 5);
|
|
entry_1:
|
|
i += tab->run;
|
|
|
|
if (i >= 64) break; /* end of block */
|
|
normal_code:
|
|
j = scan[i];
|
|
bit_buf <<= tab->len;
|
|
bits += tab->len + 1;
|
|
|
|
/* JayteeMaster: 10 points! Replaced quant_matrix[j] by quant_matrix[i] as should be */
|
|
val = ((2 * tab->level + 1) * quantizer_scale * quant_matrix[i]) >> 5;
|
|
|
|
/* if (bitstream_get (1)) val = -val; */
|
|
val = (val ^ SBITS(bit_buf, 1)) - SBITS(bit_buf, 1);
|
|
|
|
SATURATE(val);
|
|
dest[j] = val;
|
|
mismatch ^= val;
|
|
bit_buf <<= 1;
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
continue;
|
|
}
|
|
entry_2:
|
|
|
|
if (bit_buf >= 0x04000000)
|
|
{
|
|
tab = DCT_B14_8 + (UBITS(bit_buf, 8) - 4);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
|
|
/* escape code */
|
|
|
|
i += UBITS(bit_buf << 6, 6) - 64;
|
|
|
|
if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */
|
|
|
|
j = scan[i];
|
|
DUMPBITS(bit_buf, bits, 12);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
val = 2 * (SBITS(bit_buf, 12) + SBITS(bit_buf, 1)) + 1;
|
|
|
|
/* JayteeMaster: 10 points! Replaced quant_matrix[j] by quant_matrix[i] as should be */
|
|
val = (val * quantizer_scale * quant_matrix[i]) / 32;
|
|
|
|
SATURATE(val);
|
|
dest[j] = val;
|
|
mismatch ^= val;
|
|
DUMPBITS(bit_buf, bits, 12);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
continue;
|
|
}
|
|
else if (bit_buf >= 0x02000000)
|
|
{
|
|
tab = DCT_B14_10 + (UBITS(bit_buf, 10) - 8);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else if (bit_buf >= 0x00800000)
|
|
{
|
|
tab = DCT_13 + (UBITS(bit_buf, 13) - 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else if (bit_buf >= 0x00200000)
|
|
{
|
|
tab = DCT_15 + (UBITS(bit_buf, 15) - 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else
|
|
{
|
|
tab = DCT_16 + UBITS(bit_buf, 16);
|
|
bit_buf <<= 16;
|
|
GETWORD(&bit_buf, bits + 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
break; /* illegal, check needed to avoid buffer overflow */
|
|
}
|
|
|
|
dest[63] ^= mismatch & 1;
|
|
|
|
if ((bit_buf >> 30) != 0x2) ipuRegs->ctrl.ECD = 1;
|
|
|
|
DUMPBITS(bit_buf, bits, tab->len); /* dump end of block code */
|
|
|
|
decoder->bitstream_buf = bit_buf;
|
|
decoder->bitstream_bits = bits;
|
|
return i;
|
|
|
|
#undef bit_buf
|
|
#undef bits
|
|
#undef bit_ptr
|
|
}
|
|
|
|
static __forceinline void get_mpeg1_intra_block(decoder_t * const decoder)
|
|
{
|
|
int i;
|
|
int j;
|
|
int val;
|
|
const u8 * scan = decoder->scan;
|
|
const u8 * quant_matrix = decoder->intra_quantizer_matrix;
|
|
int quantizer_scale = decoder->quantizer_scale;
|
|
const DCTtab * tab;
|
|
u32 bit_buf;
|
|
int bits;
|
|
u8 * bit_ptr;
|
|
s16 * dest;
|
|
|
|
i = 0;
|
|
dest = decoder->DCTblock;
|
|
bit_buf = decoder->bitstream_buf;
|
|
bits = decoder->bitstream_bits;
|
|
bit_ptr = decoder->bitstream_ptr;
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
|
|
while (1)
|
|
{
|
|
if (bit_buf >= 0x28000000)
|
|
{
|
|
tab = DCT_B14AC_5 + (UBITS(bit_buf, 5) - 5);
|
|
i += tab->run;
|
|
|
|
if (i >= 64) break; /* end of block */
|
|
|
|
normal_code:
|
|
j = scan[i];
|
|
bit_buf <<= tab->len;
|
|
bits += tab->len + 1;
|
|
|
|
/* JayteeMaster: 10 points! Replaced quant_matrix[j] by quant_matrix[i] as should be */
|
|
val = (tab->level * quantizer_scale * quant_matrix[i]) >> 4;
|
|
|
|
/* oddification */
|
|
val = (val - 1) | 1;
|
|
|
|
/* if (bitstream_get (1)) val = -val; */
|
|
val = (val ^ SBITS(bit_buf, 1)) - SBITS(bit_buf, 1);
|
|
|
|
SATURATE(val);
|
|
dest[j] = val;
|
|
bit_buf <<= 1;
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
continue;
|
|
|
|
}
|
|
else if (bit_buf >= 0x04000000)
|
|
{
|
|
tab = DCT_B14_8 + (UBITS(bit_buf, 8) - 4);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
|
|
/* escape code */
|
|
|
|
i += UBITS(bit_buf << 6, 6) - 64;
|
|
|
|
if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */
|
|
|
|
j = scan[i];
|
|
DUMPBITS(bit_buf, bits, 12);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
val = SBITS(bit_buf, 8);
|
|
|
|
if (!(val & 0x7f))
|
|
{
|
|
DUMPBITS(bit_buf, bits, 8);
|
|
val = UBITS(bit_buf, 8) + 2 * val;
|
|
}
|
|
|
|
/* JayteeMaster: 10 points! Replaced quant_matrix[j] by quant_matrix[i] as should be */
|
|
val = (val * quantizer_scale * quant_matrix[i]) >> 4;
|
|
|
|
/* oddification */
|
|
val = (val + ~SBITS(val, 1)) | 1;
|
|
|
|
SATURATE(val);
|
|
dest[j] = val;
|
|
DUMPBITS(bit_buf, bits, 8);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
continue;
|
|
}
|
|
else if (bit_buf >= 0x02000000)
|
|
{
|
|
tab = DCT_B14_10 + (UBITS(bit_buf, 10) - 8);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else if (bit_buf >= 0x00800000)
|
|
{
|
|
tab = DCT_13 + (UBITS(bit_buf, 13) - 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else if (bit_buf >= 0x00200000)
|
|
{
|
|
tab = DCT_15 + (UBITS(bit_buf, 15) - 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else
|
|
{
|
|
tab = DCT_16 + UBITS(bit_buf, 16);
|
|
bit_buf <<= 16;
|
|
GETWORD(&bit_buf, bits + 16);
|
|
i += tab->run;
|
|
goto normal_code;
|
|
}
|
|
|
|
break; /* illegal, check needed to avoid buffer overflow */
|
|
}
|
|
|
|
if ((bit_buf >> 30) != 0x2) ipuRegs->ctrl.ECD = 1;
|
|
|
|
DUMPBITS(bit_buf, bits, 2); /* dump end of block code */
|
|
decoder->bitstream_buf = bit_buf;
|
|
decoder->bitstream_bits = bits;
|
|
}
|
|
|
|
static __forceinline int get_mpeg1_non_intra_block(decoder_t * const decoder)
|
|
{
|
|
int i;
|
|
int j;
|
|
int val;
|
|
const u8 * scan = decoder->scan;
|
|
const u8 * quant_matrix = decoder->non_intra_quantizer_matrix;
|
|
int quantizer_scale = decoder->quantizer_scale;
|
|
const DCTtab * tab;
|
|
u32 bit_buf;
|
|
int bits;
|
|
u8 * bit_ptr;
|
|
s16 * dest;
|
|
|
|
i = -1;
|
|
dest = decoder->DCTblock;
|
|
|
|
bit_buf = decoder->bitstream_buf;
|
|
bits = decoder->bitstream_bits;
|
|
bit_ptr = decoder->bitstream_ptr;
|
|
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
|
|
if (bit_buf >= 0x28000000)
|
|
{
|
|
tab = DCT_B14DC_5 + (UBITS(bit_buf, 5) - 5);
|
|
goto entry_1;
|
|
}
|
|
else
|
|
goto entry_2;
|
|
|
|
while (1)
|
|
{
|
|
if (bit_buf >= 0x28000000)
|
|
{
|
|
tab = DCT_B14AC_5 + (UBITS(bit_buf, 5) - 5);
|
|
entry_1:
|
|
i += tab->run;
|
|
|
|
if (i >= 64) break; /* end of block */
|
|
|
|
normal_code:
|
|
j = scan[i];
|
|
bit_buf <<= tab->len;
|
|
bits += tab->len + 1;
|
|
|
|
/* JayteeMaster: 10 points! Replaced quant_matrix[j] by quant_matrix[i] as should be */
|
|
val = ((2 * tab->level + 1) * quantizer_scale * quant_matrix[i]) >> 5;
|
|
|
|
/* oddification */
|
|
val = (val - 1) | 1;
|
|
|
|
/* if (bitstream_get (1)) val = -val; */
|
|
val = (val ^ SBITS(bit_buf, 1)) - SBITS(bit_buf, 1);
|
|
|
|
SATURATE(val);
|
|
dest[j] = val;
|
|
bit_buf <<= 1;
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
continue;
|
|
}
|
|
entry_2:
|
|
if (bit_buf >= 0x04000000)
|
|
{
|
|
tab = DCT_B14_8 + (UBITS(bit_buf, 8) - 4);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
|
|
/* escape code */
|
|
|
|
i += UBITS(bit_buf << 6, 6) - 64;
|
|
|
|
if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */
|
|
|
|
j = scan[i];
|
|
DUMPBITS(bit_buf, bits, 12);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
val = SBITS(bit_buf, 8);
|
|
|
|
if (!(val & 0x7f))
|
|
{
|
|
DUMPBITS(bit_buf, bits, 8);
|
|
val = UBITS(bit_buf, 8) + 2 * val;
|
|
}
|
|
|
|
val = 2 * (val + SBITS(val, 1)) + 1;
|
|
|
|
/* JayteeMaster: 10 points! Replaced quant_matrix[j] by quant_matrix[i] as should be */
|
|
val = (val * quantizer_scale * quant_matrix[i]) / 32;
|
|
|
|
/* oddification */
|
|
val = (val + ~SBITS(val, 1)) | 1;
|
|
|
|
SATURATE(val);
|
|
dest[j] = val;
|
|
DUMPBITS(bit_buf, bits, 8);
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
continue;
|
|
}
|
|
else if (bit_buf >= 0x02000000)
|
|
{
|
|
tab = DCT_B14_10 + (UBITS(bit_buf, 10) - 8);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else if (bit_buf >= 0x00800000)
|
|
{
|
|
tab = DCT_13 + (UBITS(bit_buf, 13) - 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else if (bit_buf >= 0x00200000)
|
|
{
|
|
tab = DCT_15 + (UBITS(bit_buf, 15) - 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
else
|
|
{
|
|
tab = DCT_16 + UBITS(bit_buf, 16);
|
|
bit_buf <<= 16;
|
|
GETWORD(&bit_buf, bits + 16);
|
|
i += tab->run;
|
|
|
|
if (i < 64) goto normal_code;
|
|
}
|
|
|
|
break; /* illegal, check needed to avoid buffer overflow */
|
|
}
|
|
|
|
if ((bit_buf >> 30) != 0x2) ipuRegs->ctrl.ECD = 1;
|
|
|
|
DUMPBITS(bit_buf, bits, 2); /* dump end of block code */
|
|
decoder->bitstream_buf = bit_buf;
|
|
decoder->bitstream_bits = bits;
|
|
return i;
|
|
}
|
|
|
|
static void __fastcall slice_intra_DCT(decoder_t * const decoder, const int cc,
|
|
u8 * const dest, const int stride)
|
|
{
|
|
NEEDBITS(decoder->bitstream_buf, decoder->bitstream_bits, decoder->bitstream_ptr);
|
|
/* Get the intra DC coefficient and inverse quantize it */
|
|
|
|
if (cc == 0)
|
|
decoder->dc_dct_pred[0] += get_luma_dc_dct_diff(decoder);
|
|
else
|
|
decoder->dc_dct_pred[cc] += get_chroma_dc_dct_diff(decoder);
|
|
|
|
decoder->DCTblock[0] = decoder->dc_dct_pred[cc] << (3 - decoder->intra_dc_precision);
|
|
|
|
if (decoder->mpeg1)
|
|
{
|
|
get_mpeg1_intra_block(decoder);
|
|
}
|
|
else if (decoder->intra_vlc_format)
|
|
{
|
|
get_intra_block_B15(decoder);
|
|
}
|
|
else
|
|
{
|
|
get_intra_block_B14(decoder);
|
|
}
|
|
|
|
mpeg2_idct_copy(decoder->DCTblock, dest, stride);
|
|
}
|
|
|
|
/* JayteeMaster: changed dest to 16 bit signed */
|
|
static void __fastcall slice_non_intra_DCT(decoder_t * const decoder,
|
|
/*u8*/s16 * const dest, const int stride)
|
|
{
|
|
int last;
|
|
memzero_obj(decoder->DCTblock);
|
|
|
|
if (decoder->mpeg1)
|
|
last = get_mpeg1_non_intra_block(decoder);
|
|
else
|
|
last = get_non_intra_block(decoder);
|
|
|
|
mpeg2_idct_add(last, decoder->DCTblock, dest, stride);
|
|
}
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma pack(1)
|
|
#endif
|
|
|
|
struct TGA_HEADER
|
|
{
|
|
u8 identsize; // size of ID field that follows 18 u8 header (0 usually)
|
|
u8 colourmaptype; // type of colour map 0=none, 1=has palette
|
|
u8 imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
|
|
|
|
s16 colourmapstart; // first colour map entry in palette
|
|
s16 colourmaplength; // number of colours in palette
|
|
u8 colourmapbits; // number of bits per palette entry 15,16,24,32
|
|
|
|
s16 xstart; // image x origin
|
|
s16 ystart; // image y origin
|
|
s16 width; // image width in pixels
|
|
s16 height; // image height in pixels
|
|
u8 bits; // image bits per pixel 8,16,24,32
|
|
u8 descriptor; // image descriptor bits (vh flip bits)
|
|
|
|
// pixel data follows header
|
|
#if defined(_MSC_VER)
|
|
};
|
|
|
|
#pragma pack()
|
|
#else
|
|
} __attribute__((packed));
|
|
|
|
#endif
|
|
|
|
void SaveTGA(const char* filename, int width, int height, void* pdata)
|
|
{
|
|
TGA_HEADER hdr;
|
|
FILE* f = fopen(filename, "wb");
|
|
|
|
if (f == NULL) return;
|
|
|
|
assert(sizeof(TGA_HEADER) == 18 && sizeof(hdr) == 18);
|
|
|
|
memzero_obj(hdr);
|
|
hdr.imagetype = 2;
|
|
hdr.bits = 32;
|
|
hdr.width = width;
|
|
hdr.height = height;
|
|
hdr.descriptor |= 8 | (1 << 5); // 8bit alpha, flip vertical
|
|
fwrite(&hdr, sizeof(hdr), 1, f);
|
|
fwrite(pdata, width*height*4, 1, f);
|
|
fclose(f);
|
|
}
|
|
|
|
static int s_index = 0; //, s_frame = 0;
|
|
|
|
void SaveRGB32(u8* ptr)
|
|
{
|
|
char filename[255];
|
|
sprintf(filename, "frames/frame%.4d.tga", s_index++);
|
|
SaveTGA(filename, 16, 16, ptr);
|
|
}
|
|
|
|
void waitForSCD()
|
|
{
|
|
u8 bit8 = 1;
|
|
|
|
while (!getBits8((u8*)&bit8, 0))
|
|
{
|
|
so_resume();
|
|
}
|
|
|
|
if (bit8 == 0)
|
|
{
|
|
if (g_BP.BP & 7) g_BP.BP += 8 - (g_BP.BP & 7);
|
|
|
|
ipuRegs->ctrl.SCD = 1;
|
|
}
|
|
|
|
while (!getBits32((u8*)&ipuRegs->top, 0))
|
|
{
|
|
so_resume();
|
|
}
|
|
|
|
BigEndian(ipuRegs->top, ipuRegs->top);
|
|
|
|
/*if(ipuRegs->ctrl.SCD)
|
|
{
|
|
switch(ipuRegs->top & 0xFFFFFFF0)
|
|
{
|
|
case 0x100:
|
|
case 0x1A0:
|
|
break;
|
|
case 0x1B0:
|
|
ipuRegs->ctrl.SCD = 0;
|
|
if(ipuRegs->top == 0x1b4) ipuRegs->ctrl.ECD = 1;
|
|
//else
|
|
//{
|
|
// do
|
|
// {
|
|
// while(!getBits32((u8*)&ipuRegs->top, 1))
|
|
// {
|
|
// so_resume();
|
|
// }
|
|
|
|
// BigEndian(ipuRegs->top, ipuRegs->top);
|
|
// }
|
|
// while((ipuRegs->top & 0xfffffff0) != 0x100);
|
|
//}
|
|
break;
|
|
default:
|
|
ipuRegs->ctrl.SCD = 0;
|
|
break;
|
|
}
|
|
}*/
|
|
}
|
|
|
|
void __forceinline finishmpeg2sliceIDEC(decoder_t* &decoder)
|
|
{
|
|
ipuRegs->ctrl.SCD = 0;
|
|
coded_block_pattern = decoder->coded_block_pattern;
|
|
|
|
g_BP.BP += decoder->bitstream_bits - 16;
|
|
|
|
if ((int)g_BP.BP < 0)
|
|
{
|
|
g_BP.BP = 128 + (int)g_BP.BP;
|
|
|
|
// After BP is positioned correctly, we need to reload the old buffer
|
|
// so that reading may continue properly
|
|
ReorderBitstream();
|
|
}
|
|
|
|
FillInternalBuffer(&g_BP.BP, 1, 0);
|
|
|
|
waitForSCD();
|
|
}
|
|
|
|
// This fixes Mana Khemia if uncommented, but needs testing.
|
|
// Breaks Figital Devil Saga.
|
|
//#define ALWAYS_RESUME_BEFORE_EXITING
|
|
void mpeg2sliceIDEC(void* pdone)
|
|
{
|
|
u32 read;
|
|
|
|
bool resumed = false;
|
|
decoder_t *decoder = &g_decoder;
|
|
|
|
*(int*)pdone = 0;
|
|
bitstream_init(decoder);
|
|
|
|
decoder->dc_dct_pred[0] =
|
|
decoder->dc_dct_pred[1] =
|
|
decoder->dc_dct_pred[2] = 128 << decoder->intra_dc_precision;
|
|
|
|
decoder->mbc = 0;
|
|
ipuRegs->ctrl.ECD = 0;
|
|
|
|
if (UBITS(decoder->bitstream_buf, 2) == 0)
|
|
{
|
|
ipuRegs->ctrl.SCD = 0;
|
|
}
|
|
else
|
|
{
|
|
while (1)
|
|
{
|
|
int DCT_offset, DCT_stride;
|
|
int mba_inc;
|
|
const MBAtab * mba;
|
|
|
|
NEEDBITS(decoder->bitstream_buf, decoder->bitstream_bits, decoder->bitstream_ptr);
|
|
decoder->macroblock_modes = get_macroblock_modes(decoder);
|
|
|
|
/* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */
|
|
|
|
if (decoder->macroblock_modes & MACROBLOCK_QUANT) //only IDEC
|
|
{
|
|
decoder->quantizer_scale = get_quantizer_scale(decoder);
|
|
}
|
|
|
|
if (decoder->macroblock_modes & DCT_TYPE_INTERLACED)
|
|
{
|
|
DCT_offset = decoder->stride;
|
|
DCT_stride = decoder->stride * 2;
|
|
}
|
|
else
|
|
{
|
|
DCT_offset = decoder->stride * 8;
|
|
DCT_stride = decoder->stride;
|
|
}
|
|
|
|
if (decoder->macroblock_modes & MACROBLOCK_INTRA)
|
|
{
|
|
decoder->coded_block_pattern = 0x3F;//all 6 blocks
|
|
//ipuRegs->ctrl.CBP = 0x3f;
|
|
|
|
memzero_obj(*decoder->mb8);
|
|
memzero_obj(*decoder->rgb32);
|
|
|
|
slice_intra_DCT(decoder, 0, (u8*)decoder->mb8->Y, DCT_stride);
|
|
slice_intra_DCT(decoder, 0, (u8*)decoder->mb8->Y + 8, DCT_stride);
|
|
slice_intra_DCT(decoder, 0, (u8*)decoder->mb8->Y + DCT_offset, DCT_stride);
|
|
slice_intra_DCT(decoder, 0, (u8*)decoder->mb8->Y + DCT_offset + 8, DCT_stride);
|
|
slice_intra_DCT(decoder, 1, (u8*)decoder->mb8->Cb, decoder->stride >> 1);
|
|
slice_intra_DCT(decoder, 2, (u8*)decoder->mb8->Cr, decoder->stride >> 1);
|
|
|
|
// Send The MacroBlock via DmaIpuFrom
|
|
|
|
if (decoder->ofm == 0)
|
|
{
|
|
ipu_csc(decoder->mb8, decoder->rgb32, decoder->sgn);
|
|
|
|
g_nIPU0Data = 64;
|
|
g_pIPU0Pointer = (u8*)decoder->rgb32;
|
|
//if ( s_frame >= 39 ) SaveRGB32(g_pIPU0Pointer);
|
|
}
|
|
else
|
|
{
|
|
//ipu_dither(decoder->mb8, decoder->rgb16, decoder->dte);
|
|
ipu_csc(decoder->mb8, decoder->rgb32, decoder->dte);
|
|
ipu_dither2(decoder->rgb32, decoder->rgb16, decoder->dte);
|
|
|
|
g_nIPU0Data = 32;
|
|
g_pIPU0Pointer = (u8*)decoder->rgb16;
|
|
//if ( s_frame >= 39 ) SaveRGB32(g_pIPU0Pointer);
|
|
}
|
|
|
|
while (g_nIPU0Data > 0)
|
|
{
|
|
read = FIFOfrom_write((u32*)g_pIPU0Pointer, g_nIPU0Data);
|
|
|
|
if (read == 0)
|
|
{
|
|
so_resume();
|
|
resumed = true;
|
|
}
|
|
else
|
|
{
|
|
g_pIPU0Pointer += read * 16;
|
|
g_nIPU0Data -= read;
|
|
|
|
}
|
|
}
|
|
|
|
decoder->mbc++;
|
|
}
|
|
|
|
NEEDBITS(decoder->bitstream_buf, decoder->bitstream_bits, decoder->bitstream_ptr);
|
|
mba_inc = 0;
|
|
|
|
while (1)
|
|
{
|
|
if (decoder->bitstream_buf >= 0x10000000)
|
|
{
|
|
mba = MBA_5 + (UBITS(decoder->bitstream_buf, 5) - 2);
|
|
break;
|
|
}
|
|
else if (decoder->bitstream_buf >= 0x03000000)
|
|
{
|
|
mba = MBA_11 + (UBITS(decoder->bitstream_buf, 11) - 24);
|
|
break;
|
|
}
|
|
else switch (UBITS(decoder->bitstream_buf, 11))
|
|
{
|
|
|
|
case 8: /* macroblock_escape */
|
|
mba_inc += 33;
|
|
/* pass through */
|
|
|
|
case 15: /* macroblock_stuffing (MPEG1 only) */
|
|
DUMPBITS(decoder->bitstream_buf, decoder->bitstream_bits, 11);
|
|
NEEDBITS(decoder->bitstream_buf, decoder->bitstream_bits, decoder->bitstream_ptr);
|
|
continue;
|
|
|
|
default: /* end of slice/frame, or error? */
|
|
{
|
|
#ifdef ALWAYS_RESUME_BEFORE_EXITING
|
|
if (!resumed) so_resume();
|
|
#endif
|
|
|
|
finishmpeg2sliceIDEC(decoder);
|
|
|
|
*(int*)pdone = 1;
|
|
so_exit();
|
|
}
|
|
}
|
|
}
|
|
|
|
DUMPBITS(decoder->bitstream_buf, decoder->bitstream_bits, mba->len);
|
|
mba_inc += mba->mba;
|
|
|
|
if (mba_inc)
|
|
{
|
|
decoder->dc_dct_pred[0] =
|
|
decoder->dc_dct_pred[1] =
|
|
decoder->dc_dct_pred[2] = 128 << decoder->intra_dc_precision;
|
|
|
|
do
|
|
{
|
|
decoder->mbc++;
|
|
}
|
|
while (--mba_inc);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef ALWAYS_RESUME_BEFORE_EXITING
|
|
if (!resumed) so_resume();
|
|
#endif
|
|
|
|
finishmpeg2sliceIDEC(decoder);
|
|
|
|
*(int*)pdone = 1;
|
|
so_exit();
|
|
}
|
|
|
|
void mpeg2_slice(void* pdone)
|
|
{
|
|
int DCT_offset, DCT_stride;
|
|
//u8 bit8=0;
|
|
//u32 fp = g_BP.FP;
|
|
u32 bp;
|
|
decoder_t * decoder = &g_decoder;
|
|
u32 size = 0;
|
|
|
|
*(int*)pdone = 0;
|
|
ipuRegs->ctrl.ECD = 0;
|
|
|
|
memzero_obj(*decoder->mb8);
|
|
memzero_obj(*decoder->mb16);
|
|
|
|
bitstream_init(decoder);
|
|
|
|
if (decoder->dcr)
|
|
{
|
|
decoder->dc_dct_pred[0] =
|
|
decoder->dc_dct_pred[1] =
|
|
decoder->dc_dct_pred[2] = 128 << decoder->intra_dc_precision;
|
|
}
|
|
|
|
if (decoder->macroblock_modes & DCT_TYPE_INTERLACED)
|
|
{
|
|
DCT_offset = decoder->stride;
|
|
DCT_stride = decoder->stride * 2;
|
|
}
|
|
else
|
|
{
|
|
DCT_offset = decoder->stride * 8;
|
|
DCT_stride = decoder->stride;
|
|
}
|
|
|
|
if (decoder->macroblock_modes & MACROBLOCK_INTRA)
|
|
{
|
|
decoder->coded_block_pattern = 0x3F;//all 6 blocks
|
|
slice_intra_DCT(decoder, 0, (u8*)decoder->mb8->Y, DCT_stride);
|
|
slice_intra_DCT(decoder, 0, (u8*)decoder->mb8->Y + 8, DCT_stride);
|
|
slice_intra_DCT(decoder, 0, (u8*)decoder->mb8->Y + DCT_offset, DCT_stride);
|
|
slice_intra_DCT(decoder, 0, (u8*)decoder->mb8->Y + DCT_offset + 8, DCT_stride);
|
|
slice_intra_DCT(decoder, 1, (u8*)decoder->mb8->Cb, decoder->stride >> 1);
|
|
slice_intra_DCT(decoder, 2, (u8*)decoder->mb8->Cr, decoder->stride >> 1);
|
|
ipu_copy(decoder->mb8, decoder->mb16);
|
|
}
|
|
else
|
|
{
|
|
if (decoder->macroblock_modes & MACROBLOCK_PATTERN)
|
|
{
|
|
decoder->coded_block_pattern = get_coded_block_pattern(decoder);
|
|
/* JayteeMaster: changed from mb8 to mb16 and from u8 to s16 */
|
|
|
|
if (decoder->coded_block_pattern & 0x20) slice_non_intra_DCT(decoder, (s16*)decoder->mb16->Y, DCT_stride);
|
|
if (decoder->coded_block_pattern & 0x10) slice_non_intra_DCT(decoder, (s16*)decoder->mb16->Y + 8, DCT_stride);
|
|
if (decoder->coded_block_pattern & 0x08) slice_non_intra_DCT(decoder, (s16*)decoder->mb16->Y + DCT_offset, DCT_stride);
|
|
if (decoder->coded_block_pattern & 0x04) slice_non_intra_DCT(decoder, (s16*)decoder->mb16->Y + DCT_offset + 8, DCT_stride);
|
|
if (decoder->coded_block_pattern & 0x2) slice_non_intra_DCT(decoder, (s16*)decoder->mb16->Cb, decoder->stride >> 1);
|
|
if (decoder->coded_block_pattern & 0x1) slice_non_intra_DCT(decoder, (s16*)decoder->mb16->Cr, decoder->stride >> 1);
|
|
|
|
}
|
|
}
|
|
|
|
//Send The MacroBlock via DmaIpuFrom
|
|
|
|
size = 0; // Reset
|
|
ipuRegs->ctrl.SCD = 0;
|
|
coded_block_pattern = decoder->coded_block_pattern;
|
|
bp = g_BP.BP;
|
|
g_BP.BP += ((int)decoder->bitstream_bits - 16);
|
|
|
|
// BP goes from 0 to 128, so negative values mean to read old buffer
|
|
// so we minus from 128 to get the correct BP
|
|
if ((int)g_BP.BP < 0)
|
|
{
|
|
g_BP.BP = 128 + (int)g_BP.BP;
|
|
|
|
// After BP is positioned correctly, we need to reload the old buffer
|
|
// so that reading may continue properly
|
|
ReorderBitstream();
|
|
}
|
|
|
|
FillInternalBuffer(&g_BP.BP, 1, 0);
|
|
|
|
decoder->mbc = 1;
|
|
g_nIPU0Data = 48;
|
|
g_pIPU0Pointer = (u8*)decoder->mb16;
|
|
|
|
while (g_nIPU0Data > 0)
|
|
{
|
|
size = FIFOfrom_write((u32*)g_pIPU0Pointer, g_nIPU0Data);
|
|
|
|
if (size == 0)
|
|
{
|
|
so_resume();
|
|
}
|
|
else
|
|
{
|
|
g_pIPU0Pointer += size * 16;
|
|
g_nIPU0Data -= size;
|
|
}
|
|
}
|
|
waitForSCD();
|
|
|
|
decoder->bitstream_bits = 0;
|
|
*(int*)pdone = 1;
|
|
so_exit();
|
|
}
|
|
|
|
int __forceinline get_motion_delta(decoder_t * const decoder,
|
|
const int f_code)
|
|
{
|
|
#define bit_buf (decoder->bitstream_buf)
|
|
#define bits (decoder->bitstream_bits)
|
|
#define bit_ptr (decoder->bitstream_ptr)
|
|
|
|
int delta;
|
|
int sign;
|
|
const MVtab * tab;
|
|
|
|
if ((bit_buf & 0x80000000))
|
|
{
|
|
DUMPBITS(bit_buf, bits, 1);
|
|
return 0x00010000;
|
|
}
|
|
else if ((bit_buf & 0xf0000000) || ((bit_buf & 0xfc000000) == 0x0c000000))
|
|
{
|
|
|
|
tab = MV_4 + UBITS(bit_buf, 4);
|
|
delta = (tab->delta << f_code) + 1;
|
|
bits += tab->len + f_code + 1;
|
|
bit_buf <<= tab->len;
|
|
|
|
sign = SBITS(bit_buf, 1);
|
|
bit_buf <<= 1;
|
|
|
|
if (f_code) delta += UBITS(bit_buf, f_code);
|
|
|
|
bit_buf <<= f_code;
|
|
|
|
return (delta ^ sign) - sign;
|
|
|
|
}
|
|
else
|
|
{
|
|
tab = MV_10 + UBITS(bit_buf, 10);
|
|
delta = (tab->delta << f_code) + 1;
|
|
bits += tab->len + 1;
|
|
bit_buf <<= tab->len;
|
|
|
|
sign = SBITS(bit_buf, 1);
|
|
bit_buf <<= 1;
|
|
|
|
if (f_code)
|
|
{
|
|
NEEDBITS(bit_buf, bits, bit_ptr);
|
|
delta += UBITS(bit_buf, f_code);
|
|
DUMPBITS(bit_buf, bits, f_code);
|
|
}
|
|
|
|
return (delta ^ sign) - sign;
|
|
|
|
}
|
|
|
|
#undef bit_buf
|
|
#undef bits
|
|
#undef bit_ptr
|
|
}
|
|
|
|
int __forceinline get_dmv(decoder_t * const decoder)
|
|
{
|
|
#define bit_buf (decoder->bitstream_buf)
|
|
#define bits (decoder->bitstream_bits)
|
|
#define bit_ptr (decoder->bitstream_ptr)
|
|
|
|
const DMVtab * tab;
|
|
|
|
tab = DMV_2 + UBITS(bit_buf, 2);
|
|
DUMPBITS(bit_buf, bits, tab->len);
|
|
return tab->dmv;
|
|
#undef bit_buf
|
|
#undef bits
|
|
#undef bit_ptr
|
|
}
|
|
|
|
int get_macroblock_address_increment(decoder_t * const decoder)
|
|
{
|
|
const MBAtab *mba;
|
|
|
|
if (decoder->bitstream_buf >= 0x10000000)
|
|
mba = MBA_5 + (UBITS(decoder->bitstream_buf, 5) - 2);
|
|
else if (decoder->bitstream_buf >= 0x03000000)
|
|
mba = MBA_11 + (UBITS(decoder->bitstream_buf, 11) - 24);
|
|
else switch (UBITS(decoder->bitstream_buf, 11))
|
|
{
|
|
|
|
case 8: /* macroblock_escape */
|
|
DUMPBITS(decoder->bitstream_buf, decoder->bitstream_bits, 11);
|
|
return 0x23;
|
|
|
|
case 15: /* macroblock_stuffing (MPEG1 only) */
|
|
if (decoder->mpeg1)
|
|
{
|
|
DUMPBITS(decoder->bitstream_buf, decoder->bitstream_bits, 11);
|
|
return 0x22;
|
|
}
|
|
|
|
default:
|
|
return 0;//error
|
|
}
|
|
|
|
DUMPBITS(decoder->bitstream_buf, decoder->bitstream_bits, mba->len);
|
|
|
|
return mba->mba + 1;
|
|
}
|