summaryrefslogtreecommitdiff
path: root/apps/plugins/mpegplayer/slice.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/mpegplayer/slice.c')
-rw-r--r--apps/plugins/mpegplayer/slice.c700
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