pcsx2/IPU/mpeg2lib/Mpeg.c
zerofrog df521ae24f 0.9.4 release
git-svn-id: http://pcsx2.googlecode.com/svn/branches/pcsx2_0.9.4@186 96395faa-99c1-11dd-bbfe-3dabce05a288
2007-11-11 02:55:00 +00:00

1384 lines
38 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "Mpeg.h"
#include "Vlc.h"
#include "coroutine.h"
extern void (* mpeg2_idct_copy) (s16 * block, u8* dest, int stride);
/* JayteeMaster: changed dest to 16 bit signed */
extern void (* mpeg2_idct_add) (int last, s16 * block,
/*u8*/s16* dest, int stride);
extern int FIFOfrom_write(u32* value, int size);
/* JayteeMaster: remove static attribute */
/*static */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
};
extern tIPU_BP g_BP;
/* Bitstream and buffer needs to be realocated inorder for sucessful
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 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 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);
DUMPBITS (decoder->bitstream_buf, decoder->bitstream_bits, tab->len);
return tab->cbp;
}
tab = CBP_9 + UBITS (decoder->bitstream_buf, 9);
DUMPBITS (decoder->bitstream_buf, decoder->bitstream_bits, tab->len);
return tab->cbp;
}
static 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) {
bits += tab->len + size;
bit_buf <<= tab->len;
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);
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 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) {
bits += tab->len + size;
bit_buf <<= tab->len;
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 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, 2); /* dump end of block code */
decoder->bitstream_buf = bit_buf;
decoder->bitstream_bits = bits;
}
static 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, 4); /* dump end of block code */
decoder->bitstream_buf = bit_buf;
decoder->bitstream_bits = bits;
}
static 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, 2); /* 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 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;
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;
}
static 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 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 slice_non_intra_DCT (decoder_t * const decoder,
/*u8*/s16 * const dest, const int stride){
int last;
memset(decoder->DCTblock,0,sizeof(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);
}
extern int coded_block_pattern;
extern u8 FillInternalBuffer(u32 * pointer, u32 advance);
extern decoder_t g_decoder;
extern int g_nIPU0Data; // or 0x80000000 whenever transferring
extern u8* g_pIPU0Pointer;
#if defined(_MSC_VER)
#pragma pack(push, 1)
#endif
typedef 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)
} TGA_HEADER;
#pragma pack(pop)
#else
} TGA_HEADER __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 );
memset(&hdr, 0, sizeof(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;
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 ) {
while( !(ipuRegs->top & 0x100) ) {
while(!getBits8((u8*)&bit8, 1))
so_resume();
while(!getBits32((u8*)&ipuRegs->top, 0))
so_resume();
BigEndian(ipuRegs->top, ipuRegs->top);
}
if( ipuRegs->top == 0x1b3 ) {
// fixes srs
SysPrintf("bad start code %x, will manuall skip stream\n", ipuRegs->top);
while( ipuRegs->top != 0x100 ) {
while(!getBits8((u8*)&bit8, 1))
so_resume();
while(!getBits32((u8*)&ipuRegs->top, 0))
so_resume();
BigEndian(ipuRegs->top, ipuRegs->top);
}
}
}
}
void mpeg2sliceIDEC(void* pdone)
{
u32 read;
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;
memset(decoder->mb8,0,sizeof(struct macroblock_8));
memset(decoder->rgb32,0,sizeof(struct 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);
while(g_nIPU0Data > 0) {
read = FIFOfrom_write((u32*)g_pIPU0Pointer,g_nIPU0Data);
if( read == 0 )
so_resume();
else {
g_pIPU0Pointer += read*16;
g_nIPU0Data -= read;
}
}
}
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();
}
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? */
{
//int i;
ipuRegs->ctrl.SCD = 0;
coded_block_pattern=decoder->coded_block_pattern;
// for (i=0; i<2; i++) {
// u8 byte;
// while(!getBits8(&byte, 0))
// so_resume();
// if (byte == 0) break;
// g_BP.BP+= 8;
// }
g_BP.BP+=decoder->bitstream_bits-16;
//g_BP.BP-=32;//bitstream_init takes 32 bits
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();
}
waitForSCD();
if( ipuRegs->ctrl.SCD ) {
//SysPrintf("top %d: %8.8x\n", s_frame++, ipuRegs->top);
}
*(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);
}
}
}
ipuRegs->ctrl.SCD = 0;
coded_block_pattern=decoder->coded_block_pattern;
//ipuRegs->ctrl.ECD=!ipuRegs->ctrl.SCD;
//g_BP.BP-=32;//bitstream_init takes 32 bits
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();
}
waitForSCD();
if( ipuRegs->ctrl.SCD ) {
//SysPrintf("idectop: %8.8x, bp = %x\n", ipuRegs->top, g_BP.BP);
}
*(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;
memset(decoder->mb8,0,sizeof(struct macroblock_8));
memset(decoder->mb16,0,sizeof(struct macroblock_16));
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;
NEEDBITS (decoder->bitstream_buf, decoder->bitstream_bits, decoder->bitstream_ptr);
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;
//FillInternalBuffer(&g_BP.BP, 1);
bp = g_BP.BP;
g_BP.BP+=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();
}
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;
}
}
IPU_LOG("BDEC %x, %d\n",g_BP.BP,g_BP.FP);
waitForSCD();
if( ipuRegs->ctrl.SCD ) {
//SysPrintf("bdectop: %8.8x, bp = %x\n", ipuRegs->top, g_BP.BP);
}
*(int*)pdone = 1;
so_exit();
}
int 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 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;
}