diff options
| author | Michael Sevakis <jethead71@rockbox.org> | 2008-01-16 01:22:56 +0000 |
|---|---|---|
| committer | Michael Sevakis <jethead71@rockbox.org> | 2008-01-16 01:22:56 +0000 |
| commit | 0c7f2372d5887f6a1e9d76f04cd4ddbd1b5e402b (patch) | |
| tree | 2dac505f17d2ec7a8fb63b8f1009f4c385b10ab1 /apps/plugins/mpegplayer/slice.c | |
| parent | 74d61058dcaf1c0d036a708fd3fcdc35139a1fab (diff) | |
| download | rockbox-0c7f2372d5887f6a1e9d76f04cd4ddbd1b5e402b.zip rockbox-0c7f2372d5887f6a1e9d76f04cd4ddbd1b5e402b.tar.gz rockbox-0c7f2372d5887f6a1e9d76f04cd4ddbd1b5e402b.tar.bz2 rockbox-0c7f2372d5887f6a1e9d76f04cd4ddbd1b5e402b.tar.xz | |
libmpeg2: Decode only Y on grayscale targets. The chroma skip code is probably less than optimal since it's basically the decoding code with minimum reading of the bitstream but it does the trick for now and gets some more FPS.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16093 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/mpegplayer/slice.c')
| -rw-r--r-- | apps/plugins/mpegplayer/slice.c | 700 |
1 files changed, 616 insertions, 84 deletions
diff --git a/apps/plugins/mpegplayer/slice.c b/apps/plugins/mpegplayer/slice.c index a039eb8..3b6df97 100644 --- a/apps/plugins/mpegplayer/slice.c +++ b/apps/plugins/mpegplayer/slice.c @@ -326,6 +326,7 @@ static inline int get_luma_dc_dct_diff (mpeg2_decoder_t * const decoder) #undef bit_ptr } +#if MPEG2_COLOR static inline int get_chroma_dc_dct_diff (mpeg2_decoder_t * const decoder) { #define bit_buf (decoder->bitstream_buf) @@ -371,6 +372,7 @@ static inline int get_chroma_dc_dct_diff (mpeg2_decoder_t * const decoder) #undef bits #undef bit_ptr } +#endif /* MPEG2_COLOR */ #define SATURATE(val) \ do { \ @@ -382,23 +384,16 @@ static inline int get_chroma_dc_dct_diff (mpeg2_decoder_t * const decoder) static void get_intra_block_B14 (mpeg2_decoder_t * const decoder, const uint16_t * const quant_matrix) { - int i; + uint32_t bit_buf = decoder->bitstream_buf; + int bits = decoder->bitstream_bits; + const uint8_t * bit_ptr = decoder->bitstream_ptr; + const uint8_t * const scan = decoder->scan; + int16_t * const dest = decoder->DCTblock; + int mismatch = ~dest[0]; + int i = 0; int j; int val; - const uint8_t * const scan = decoder->scan; - int mismatch; const DCTtab * tab; - uint32_t bit_buf; - int bits; - const uint8_t * bit_ptr; - int16_t * const 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); @@ -502,23 +497,16 @@ static void get_intra_block_B14 (mpeg2_decoder_t * const decoder, static void get_intra_block_B15 (mpeg2_decoder_t * const decoder, const uint16_t * const quant_matrix) { - int i; + uint32_t bit_buf = decoder->bitstream_buf; + int bits = decoder->bitstream_bits; + const uint8_t * bit_ptr = decoder->bitstream_ptr; + const uint8_t * const scan = decoder->scan; + int16_t * const dest = decoder->DCTblock; + int mismatch = ~dest[0]; + int i = 0; int j; int val; - const uint8_t * const scan = decoder->scan; - int mismatch; const DCTtab * tab; - uint32_t bit_buf; - int bits; - const uint8_t * bit_ptr; - int16_t * const 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); @@ -622,23 +610,16 @@ static void get_intra_block_B15 (mpeg2_decoder_t * const decoder, static int get_non_intra_block (mpeg2_decoder_t * const decoder, const uint16_t * const quant_matrix) { - int i; + uint32_t bit_buf = decoder->bitstream_buf; + int bits = decoder->bitstream_bits; + const uint8_t * bit_ptr = decoder->bitstream_ptr; + const uint8_t * const scan = decoder->scan; + int16_t * const dest = decoder->DCTblock; + int mismatch = -1; + int i = -1; int j; int val; - const uint8_t * const scan = decoder->scan; - int mismatch; const DCTtab * tab; - uint32_t bit_buf; - int bits; - const uint8_t * bit_ptr; - int16_t * const dest = decoder->DCTblock; - - i = -1; - mismatch = -1; - - bit_buf = decoder->bitstream_buf; - bits = decoder->bitstream_bits; - bit_ptr = decoder->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); @@ -756,22 +737,16 @@ static int get_non_intra_block (mpeg2_decoder_t * const decoder, static void get_mpeg1_intra_block (mpeg2_decoder_t * const decoder) { - int i; - int j; - int val; + uint32_t bit_buf = decoder->bitstream_buf; + int bits = decoder->bitstream_bits; + const uint8_t * bit_ptr = decoder->bitstream_ptr; const uint8_t * const scan = decoder->scan; const uint16_t * const quant_matrix = decoder->quantizer_matrix[0]; - const DCTtab * tab; - uint32_t bit_buf; - int bits; - const uint8_t * bit_ptr; int16_t * const dest = decoder->DCTblock; - - i = 0; - - bit_buf = decoder->bitstream_buf; - bits = decoder->bitstream_bits; - bit_ptr = decoder->bitstream_ptr; + int i = 0; + int j; + int val; + const DCTtab * tab; NEEDBITS (bit_buf, bits, bit_ptr); @@ -1043,11 +1018,13 @@ static inline void slice_intra_DCT (mpeg2_decoder_t * const decoder, decoder->DCTblock[0] = decoder->dc_dct_pred[0]; } +#if MPEG2_COLOR else { decoder->dc_dct_pred[cc] += get_chroma_dc_dct_diff (decoder); decoder->DCTblock[0] = decoder->dc_dct_pred[cc]; } +#endif if (decoder->mpeg1) { @@ -1089,6 +1066,482 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, mpeg2_idct_add (last, decoder->DCTblock, dest, stride); } +#if !MPEG2_COLOR +static void skip_mpeg1_intra_block (mpeg2_decoder_t * const decoder) +{ + uint32_t bit_buf = decoder->bitstream_buf; + int bits = decoder->bitstream_bits; + const uint8_t * bit_ptr = decoder->bitstream_ptr; + int i = 0; + const DCTtab * tab; + + 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: + bit_buf <<= tab->len + 1; + bits += tab->len + 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 */ + + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + if (!(SBITS (bit_buf, 8) & 0x7f)) + DUMPBITS (bit_buf, bits, 8); + + 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, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + decoder->bitstream_buf = bit_buf; + decoder->bitstream_bits = bits; + decoder->bitstream_ptr = bit_ptr; +} + +static void skip_intra_block_B14 (mpeg2_decoder_t * const decoder) +{ + uint32_t bit_buf = decoder->bitstream_buf; + int bits = decoder->bitstream_bits; + const uint8_t * bit_ptr = decoder->bitstream_ptr; + int i = 0; + const DCTtab * tab; + + 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: + bit_buf <<= tab->len + 1; + bits += tab->len + 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 */ + + DUMPBITS (bit_buf, bits, 12); /* Can't dump more than 16 atm */ + NEEDBITS (bit_buf, bits, bit_ptr); + 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, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + decoder->bitstream_buf = bit_buf; + decoder->bitstream_bits = bits; + decoder->bitstream_ptr = bit_ptr; +} + +static void skip_intra_block_B15 (mpeg2_decoder_t * const decoder) +{ + uint32_t bit_buf = decoder->bitstream_buf; + int bits = decoder->bitstream_bits; + const uint8_t * bit_ptr = decoder->bitstream_ptr; + int i = 0; + const DCTtab * tab; + + 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: + bit_buf <<= tab->len + 1; + bits += tab->len + 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 */ + + DUMPBITS (bit_buf, bits, 12); /* Can't dump more than 16 atm */ + NEEDBITS (bit_buf, bits, bit_ptr); + 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, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + + DUMPBITS (bit_buf, bits, 4); /* dump end of block code */ + decoder->bitstream_buf = bit_buf; + decoder->bitstream_bits = bits; + decoder->bitstream_ptr = bit_ptr; +} + +static void skip_non_intra_block (mpeg2_decoder_t * const decoder) +{ + uint32_t bit_buf = decoder->bitstream_buf; + int bits = decoder->bitstream_bits; + const uint8_t * bit_ptr = decoder->bitstream_ptr; + int i = -1; + const DCTtab * tab; + + 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: + bit_buf <<= tab->len + 1; + bits += tab->len + 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 */ + + if (decoder->mpeg1) + { + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + + if (!(SBITS (bit_buf, 8) & 0x7f)) + DUMPBITS (bit_buf, bits, 8); + + DUMPBITS (bit_buf, bits, 8); + } + else + { + DUMPBITS (bit_buf, bits, 12); + NEEDBITS (bit_buf, bits, bit_ptr); + 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, bit_ptr); + i += tab->run; + if (i < 64) + goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + decoder->bitstream_buf = bit_buf; + decoder->bitstream_bits = bits; + decoder->bitstream_ptr = bit_ptr; +} + +static void skip_chroma_dc_dct_diff (mpeg2_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; + + 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; + bit_buf <<= size; + } + else + { + DUMPBITS (bit_buf, bits, 2); + } + } + else + { + tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0); + size = tab->size; + DUMPBITS (bit_buf, bits, tab->len + 1); + NEEDBITS (bit_buf, bits, bit_ptr); + DUMPBITS (bit_buf, bits, size); + } + +#undef bit_buf +#undef bits +#undef bit_ptr +} + +static void skip_chroma_non_intra (mpeg2_decoder_t * const decoder, + uint32_t coded_block_pattern) +{ + static const uint32_t cbp_mask[3] = + { + 0x00000030, + 0xc0000030, + 0xfc000030, + }; + + uint32_t cbp = coded_block_pattern & + cbp_mask[MIN((unsigned)decoder->chroma_format, 2u)]; + + while (cbp) + { + skip_non_intra_block (decoder); + cbp &= (cbp - 1); + } +} + +static void skip_chroma_intra (mpeg2_decoder_t * const decoder) +{ +#define bit_buf (decoder->bitstream_buf) +#define bits (decoder->bitstream_bits) +#define bit_ptr (decoder->bitstream_ptr) + int i = 2 << decoder->chroma_format; + + if ((unsigned)i > 8) + i = 8; + + while (i-- > 0) + { + NEEDBITS (bit_buf, bits, bit_ptr); + + skip_chroma_dc_dct_diff (decoder); + + if (decoder->mpeg1) + { + if (decoder->coding_type != D_TYPE) + skip_mpeg1_intra_block (decoder); + } + else if (decoder->intra_vlc_format) + { + skip_intra_block_B15 (decoder); + } + else + { + skip_intra_block_B14 (decoder); + } + } + + if (decoder->chroma_format == 0 && decoder->coding_type == D_TYPE) + { + NEEDBITS (bit_buf, bits, bit_ptr); + DUMPBITS (bit_buf, bits, 1); + } + +#undef bit_buf +#undef bits +#undef bit_ptr +} +#endif /* !MPEG2_COLOR */ + #define MOTION_420(table, ref, motion_x, motion_y, size, y) \ pos_x = 2 * decoder->offset + motion_x; \ pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \ @@ -1110,6 +1563,8 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, ref[0] + (pos_x >> 1) + (pos_y >> 1) * decoder->stride, \ decoder->stride, size); \ \ + if (MPEG2_COLOR) \ + { \ motion_x /= 2; \ motion_y /= 2; \ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ @@ -1122,7 +1577,8 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, decoder->uv_stride, size/2); \ table[4+xy_half] (decoder->dest[2] + y/2 * decoder->uv_stride + \ (decoder->offset >> 1), ref[2] + offset, \ - decoder->uv_stride, size/2) + decoder->uv_stride, size/2); \ + } #define MOTION_FIELD_420(table, ref, motion_x, motion_y, \ dest_field, op, src_field) \ @@ -1148,6 +1604,8 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, ((pos_y op) + src_field) * decoder->stride), \ 2 * decoder->stride, 8); \ \ + if (MPEG2_COLOR) \ + { \ motion_x /= 2; \ motion_y /= 2; \ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ @@ -1160,7 +1618,8 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, 2 * decoder->uv_stride, 4); \ table[4+xy_half] (decoder->dest[2] + dest_field * decoder->uv_stride + \ (decoder->offset >> 1), ref[2] + offset, \ - 2 * decoder->uv_stride, 4) + 2 * decoder->uv_stride, 4); \ + } #define MOTION_DMV_420(table, ref, motion_x, motion_y) \ pos_x = 2 * decoder->offset + motion_x; \ @@ -1186,6 +1645,8 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, ref[0] + decoder->stride + offset, \ 2 * decoder->stride, 8); \ \ + if (MPEG2_COLOR) \ + { \ motion_x /= 2; \ motion_y /= 2; \ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ @@ -1204,20 +1665,24 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, table[4+xy_half] (decoder->dest[2] + decoder->uv_stride + \ (decoder->offset >> 1), \ ref[2] + decoder->uv_stride + offset, \ - 2 * decoder->uv_stride, 4) + 2 * decoder->uv_stride, 4); \ + } #define MOTION_ZERO_420(table, ref) \ table[0] (decoder->dest[0] + decoder->offset, \ (ref[0] + decoder->offset + \ decoder->v_offset * decoder->stride), decoder->stride, 16); \ \ + if (MPEG2_COLOR) \ + { \ offset = ((decoder->offset >> 1) + \ (decoder->v_offset >> 1) * decoder->uv_stride); \ \ table[4] (decoder->dest[1] + (decoder->offset >> 1), \ ref[1] + offset, decoder->uv_stride, 8); \ table[4] (decoder->dest[2] + (decoder->offset >> 1), \ - ref[2] + offset, decoder->uv_stride, 8) + ref[2] + offset, decoder->uv_stride, 8); \ + } #define MOTION_422(table, ref, motion_x, motion_y, size, y) \ pos_x = 2 * decoder->offset + motion_x; \ @@ -1241,6 +1706,8 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \ ref[0] + offset, decoder->stride, size); \ \ + if (MPEG2_COLOR) \ + { \ offset = (offset + (motion_x & (motion_x < 0))) >> 1; \ motion_x /= 2; \ xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \ @@ -1250,7 +1717,8 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, decoder->uv_stride, size); \ table[4+xy_half] (decoder->dest[2] + y * decoder->uv_stride + \ (decoder->offset >> 1), ref[2] + offset, \ - decoder->uv_stride, size) + decoder->uv_stride, size); \ + } #define MOTION_FIELD_422(table, ref, motion_x, motion_y, \ dest_field, op, src_field) \ @@ -1276,6 +1744,8 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, decoder->offset, ref[0] + offset, \ 2 * decoder->stride, 8); \ \ + if (MPEG2_COLOR) \ + { \ offset = (offset + (motion_x & (motion_x < 0))) >> 1; \ motion_x /= 2; \ xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \ @@ -1285,7 +1755,8 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, 2 * decoder->uv_stride, 8); \ table[4+xy_half] (decoder->dest[2] + dest_field * decoder->uv_stride + \ (decoder->offset >> 1), ref[2] + offset, \ - 2 * decoder->uv_stride, 8) + 2 * decoder->uv_stride, 8); \ + } #define MOTION_DMV_422(table, ref, motion_x, motion_y) \ pos_x = 2 * decoder->offset + motion_x; \ @@ -1312,6 +1783,8 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, ref[0] + decoder->stride + offset, \ 2 * decoder->stride, 8); \ \ + if (MPEG2_COLOR) \ + { \ offset = (offset + (motion_x & (motion_x < 0))) >> 1; \ motion_x /= 2; \ xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \ @@ -1327,17 +1800,22 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, table[4+xy_half] (decoder->dest[2] + decoder->uv_stride + \ (decoder->offset >> 1), \ ref[2] + decoder->uv_stride + offset, \ - 2 * decoder->uv_stride, 8) + 2 * decoder->uv_stride, 8); \ + } #define MOTION_ZERO_422(table, ref) \ offset = decoder->offset + decoder->v_offset * decoder->stride; \ table[0] (decoder->dest[0] + decoder->offset, \ ref[0] + offset, decoder->stride, 16); \ + \ + if (MPEG2_COLOR) \ + { \ offset >>= 1; \ table[4] (decoder->dest[1] + (decoder->offset >> 1), \ ref[1] + offset, decoder->uv_stride, 16); \ table[4] (decoder->dest[2] + (decoder->offset >> 1), \ - ref[2] + offset, decoder->uv_stride, 16) + ref[2] + offset, decoder->uv_stride, 16); \ + } #define MOTION_444(table, ref, motion_x, motion_y, size, y) \ pos_x = 2 * decoder->offset + motion_x; \ @@ -1360,10 +1838,14 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, \ table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \ ref[0] + offset, decoder->stride, size); \ + \ + if (MPEG2_COLOR) \ + { \ table[xy_half] (decoder->dest[1] + y * decoder->stride + decoder->offset, \ ref[1] + offset, decoder->stride, size); \ table[xy_half] (decoder->dest[2] + y * decoder->stride + decoder->offset, \ - ref[2] + offset, decoder->stride, size) + ref[2] + offset, decoder->stride, size); \ + } #define MOTION_FIELD_444(table, ref, motion_x, motion_y, \ dest_field, op, src_field) \ @@ -1388,12 +1870,16 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \ decoder->offset, ref[0] + offset, \ 2 * decoder->stride, 8); \ + \ + if (MPEG2_COLOR) \ + { \ table[xy_half] (decoder->dest[1] + dest_field * decoder->stride + \ decoder->offset, ref[1] + offset, \ 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[2] + dest_field * decoder->stride + \ decoder->offset, ref[2] + offset, \ - 2 * decoder->stride, 8) + 2 * decoder->stride, 8); \ + } #define MOTION_DMV_444(table, ref, motion_x, motion_y) \ pos_x = 2 * decoder->offset + motion_x; \ @@ -1419,6 +1905,9 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \ ref[0] + decoder->stride + offset, \ 2 * decoder->stride, 8); \ + \ + if (MPEG2_COLOR) \ + { \ table[xy_half] (decoder->dest[1] + decoder->offset, \ ref[1] + offset, 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[1] + decoder->stride + decoder->offset, \ @@ -1428,17 +1917,22 @@ static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, ref[2] + offset, 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[2] + decoder->stride + decoder->offset, \ ref[2] + decoder->stride + offset, \ - 2 * decoder->stride, 8) + 2 * decoder->stride, 8); \ + } #define MOTION_ZERO_444(table, ref) \ offset = decoder->offset + decoder->v_offset * decoder->stride; \ \ table[0] (decoder->dest[0] + decoder->offset, \ ref[0] + offset, decoder->stride, 16); \ + \ + if (MPEG2_COLOR) \ + { \ table[4] (decoder->dest[1] + decoder->offset, \ ref[1] + offset, decoder->stride, 16); \ table[4] (decoder->dest[2] + (decoder->offset >> 1), \ - ref[2] + offset, decoder->stride, 16) + ref[2] + offset, decoder->stride, 16); \ + } #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) @@ -1779,8 +2273,11 @@ do { \ } \ \ decoder->dest[0] += decoder->slice_stride; \ + if (MPEG2_COLOR) \ + { \ decoder->dest[1] += decoder->slice_uv_stride; \ decoder->dest[2] += decoder->slice_uv_stride; \ + } \ } while (0); \ \ decoder->v_offset += 16; \ @@ -1792,8 +2289,10 @@ do { \ } \ } while (0) -void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, uint8_t * current_fbuf[3], - uint8_t * forward_fbuf[3], uint8_t * backward_fbuf[3]) +void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, + uint8_t * current_fbuf[MPEG2_COMPONENTS], + uint8_t * forward_fbuf[MPEG2_COMPONENTS], + uint8_t * backward_fbuf[MPEG2_COMPONENTS]) { int offset, stride, height, bottom_field; @@ -1803,16 +2302,22 @@ void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, uint8_t * current_fbuf[3], height = decoder->height; decoder->picture_dest[0] = current_fbuf[0] + offset; +#if MPEG2_COLOR decoder->picture_dest[1] = current_fbuf[1] + (offset >> 1); decoder->picture_dest[2] = current_fbuf[2] + (offset >> 1); +#endif decoder->f_motion.ref[0][0] = forward_fbuf[0] + offset; +#if MPEG2_COLOR decoder->f_motion.ref[0][1] = forward_fbuf[1] + (offset >> 1); decoder->f_motion.ref[0][2] = forward_fbuf[2] + (offset >> 1); +#endif decoder->b_motion.ref[0][0] = backward_fbuf[0] + offset; +#if MPEG2_COLOR decoder->b_motion.ref[0][1] = backward_fbuf[1] + (offset >> 1); decoder->b_motion.ref[0][2] = backward_fbuf[2] + (offset >> 1); +#endif if (decoder->picture_structure != FRAME_PICTURE) { @@ -1827,22 +2332,26 @@ void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, uint8_t * current_fbuf[3], forward_fbuf = current_fbuf; decoder->f_motion.ref[1][0] = forward_fbuf[0] + offset; +#if MPEG2_COLOR decoder->f_motion.ref[1][1] = forward_fbuf[1] + (offset >> 1); decoder->f_motion.ref[1][2] = forward_fbuf[2] + (offset >> 1); - +#endif decoder->b_motion.ref[1][0] = backward_fbuf[0] + offset; +#if MPEG2_COLOR decoder->b_motion.ref[1][1] = backward_fbuf[1] + (offset >> 1); decoder->b_motion.ref[1][2] = backward_fbuf[2] + (offset >> 1); - +#endif stride <<= 1; height >>= 1; } decoder->stride = stride; - decoder->uv_stride = stride >> 1; decoder->slice_stride = 16 * stride; +#if MPEG2_COLOR + decoder->uv_stride = stride >> 1; decoder->slice_uv_stride = decoder->slice_stride >> (2 - decoder->chroma_format); +#endif decoder->limit_x = 2 * decoder->width - 32; decoder->limit_y_16 = 2 * height - 32; decoder->limit_y_8 = 2 * height - 16; @@ -1919,8 +2428,12 @@ static inline int slice_init (mpeg2_decoder_t * const decoder, int code) int offset; const MBAtab * mba; +#if MPEG2_COLOR decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] = decoder->dc_dct_pred[2] = 16384; +#else + decoder->dc_dct_pred[0] = 16384; +#endif decoder->f_motion.pmv[0][0] = decoder->f_motion.pmv[0][1] = 0; decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[1][1] = 0; @@ -1942,9 +2455,11 @@ static inline int slice_init (mpeg2_decoder_t * const decoder, int code) } decoder->dest[0] = decoder->picture_dest[0] + offset; +#if MPEG2_COLOR offset >>= (2 - decoder->chroma_format); decoder->dest[1] = decoder->picture_dest[1] + offset; decoder->dest[2] = decoder->picture_dest[2] + offset; +#endif get_quantizer_scale (decoder); @@ -1999,8 +2514,10 @@ static inline int slice_init (mpeg2_decoder_t * const decoder, int code) if (!(decoder->convert) || decoder->coding_type != B_TYPE) { decoder->dest[0] += decoder->slice_stride; +#if MPEG2_COLOR decoder->dest[1] += decoder->slice_uv_stride; decoder->dest[2] += decoder->slice_uv_stride; +#endif } decoder->v_offset += 16; @@ -2081,6 +2598,7 @@ void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code, slice_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride); slice_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); +#if MPEG2_COLOR if (likely (decoder->chroma_format == 0)) { slice_intra_DCT (decoder, 1, decoder->dest[1] + (offset >> 1), @@ -2123,6 +2641,9 @@ void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code, slice_intra_DCT (decoder, 2, dest_v + DCT_offset + 8, DCT_stride); } +#else + skip_chroma_intra(decoder); +#endif /* MPEG2_COLOR */ } else { @@ -2170,7 +2691,7 @@ void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code, slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); - +#if MPEG2_COLOR if (coded_block_pattern & 16) slice_non_intra_DCT (decoder, 1, decoder->dest[1] + (offset >> 1), @@ -2180,6 +2701,7 @@ void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code, slice_non_intra_DCT (decoder, 2, decoder->dest[2] + (offset >> 1), decoder->uv_stride); +#endif /* MPEG2_COLOR */ } else if (likely (decoder->chroma_format == 1)) { @@ -2207,7 +2729,7 @@ void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code, slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); - +#if MPEG2_COLOR DCT_stride >>= 1; DCT_offset = (DCT_offset + offset) >> 1; @@ -2230,20 +2752,19 @@ void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code, slice_non_intra_DCT (decoder, 2, decoder->dest[2] + DCT_offset, DCT_stride); +#endif /* MPEG2_COLOR */ } else { - int offset; - uint8_t * dest_y, * dest_u, * dest_v; - + int offset = decoder->offset; + uint8_t * dest_y = decoder->dest[0] + offset; +#if MPEG2_COLOR + uint8_t * dest_u = decoder->dest[1] + offset; + uint8_t * dest_v = decoder->dest[2] + offset; +#endif coded_block_pattern |= bit_buf & (63 << 26); DUMPBITS (bit_buf, bits, 6); - offset = decoder->offset; - dest_y = decoder->dest[0] + offset; - dest_u = decoder->dest[1] + offset; - dest_v = decoder->dest[2] + offset; - if (coded_block_pattern & 1) slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride); @@ -2259,7 +2780,7 @@ void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code, slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); - +#if MPEG2_COLOR if (coded_block_pattern & 16) slice_non_intra_DCT (decoder, 1, dest_u, DCT_stride); @@ -2291,11 +2812,19 @@ void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code, slice_non_intra_DCT (decoder, 2, dest_v + DCT_offset + 8, DCT_stride); +#endif /* MPEG2_COLOR */ } +#if !MPEG2_COLOR + skip_chroma_non_intra(decoder, coded_block_pattern); +#endif } +#if MPEG2_COLOR decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] = decoder->dc_dct_pred[2] = 16384; +#else + decoder->dc_dct_pred[0] = 16384; +#endif } NEXT_MACROBLOCK; @@ -2337,9 +2866,12 @@ void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code, if (mba_inc) { +#if MPEG2_COLOR decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] = decoder->dc_dct_pred[2] = 16384; - +#else + decoder->dc_dct_pred[0] = 16384; +#endif if (decoder->coding_type == P_TYPE) { do |