From 0c7f2372d5887f6a1e9d76f04cd4ddbd1b5e402b Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Wed, 16 Jan 2008 01:22:56 +0000 Subject: [PATCH] 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 --- apps/plugins/mpegplayer/alloc.c | 2 +- apps/plugins/mpegplayer/decode.c | 15 +- apps/plugins/mpegplayer/header.c | 32 +- apps/plugins/mpegplayer/mpeg2.h | 15 +- apps/plugins/mpegplayer/mpeg2_internal.h | 18 +- apps/plugins/mpegplayer/mpeg2dec_config.h | 13 + apps/plugins/mpegplayer/slice.c | 700 +++++++++++++++++++--- 7 files changed, 680 insertions(+), 115 deletions(-) diff --git a/apps/plugins/mpegplayer/alloc.c b/apps/plugins/mpegplayer/alloc.c index 1ff75d4d64..f6661d4632 100644 --- a/apps/plugins/mpegplayer/alloc.c +++ b/apps/plugins/mpegplayer/alloc.c @@ -144,7 +144,7 @@ bool mpeg_alloc_init(unsigned char *buf, size_t mallocsize) return false; } - IF_COP(flush_icache()); + IF_COP(invalidate_icache()); return true; } diff --git a/apps/plugins/mpegplayer/decode.c b/apps/plugins/mpegplayer/decode.c index 2176cad601..ab3a800d9b 100644 --- a/apps/plugins/mpegplayer/decode.c +++ b/apps/plugins/mpegplayer/decode.c @@ -37,6 +37,10 @@ extern struct plugin_api* rb; /* twice as large as on other targets because coldfire uses * a secondary, transposed buffer for optimisation */ static int16_t static_dct_block[128] IBSS_ATTR ATTR_ALIGN(16); +#define DCT_BLOCKSIZE (128 * sizeof (int16_t)) +#else +static int16_t static_dct_block[64] IBSS_ATTR ATTR_ALIGN(16); +#define DCT_BLOCKSIZE (64 * sizeof (int16_t)) #endif const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec) @@ -410,7 +414,7 @@ int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride) return stride; } -void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id) +void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[MPEG2_COMPONENTS], void * id) { mpeg2_fbuf_t * fbuf; @@ -434,8 +438,10 @@ void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id) } fbuf->buf[0] = buf[0]; +#if MPEG2_COLOR fbuf->buf[1] = buf[1]; fbuf->buf[2] = buf[2]; +#endif fbuf->id = id; } @@ -502,12 +508,11 @@ mpeg2dec_t * mpeg2_init (void) if (mpeg2dec == NULL) return NULL; -#ifdef CPU_COLDFIRE mpeg2dec->decoder.DCTblock = static_dct_block; -#endif - rb->memset (mpeg2dec->decoder.DCTblock, 0, 64 * sizeof (int16_t)); - rb->memset (mpeg2dec->quantizer_matrix, 0, 4 * 64 * sizeof (uint8_t)); + rb->memset (mpeg2dec->decoder.DCTblock, 0, DCT_BLOCKSIZE); + + DEBUGF("DCTblock: %p\n", mpeg2dec->decoder.DCTblock); mpeg2dec->chunk_buffer = (uint8_t *)mpeg2_bufalloc(BUFFER_SIZE + 4, MPEG2_ALLOC_CHUNK); diff --git a/apps/plugins/mpegplayer/header.c b/apps/plugins/mpegplayer/header.c index 9e6e6de03d..3dd3d280dd 100644 --- a/apps/plugins/mpegplayer/header.c +++ b/apps/plugins/mpegplayer/header.c @@ -102,8 +102,10 @@ void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec) i < mpeg2dec->alloc_index; i++) { mpeg2_free(mpeg2dec->fbuf_alloc[i].fbuf.buf[0]); +#if MPEG2_COLOR mpeg2_free(mpeg2dec->fbuf_alloc[i].fbuf.buf[1]); mpeg2_free(mpeg2dec->fbuf_alloc[i].fbuf.buf[2]); +#endif } } @@ -113,8 +115,10 @@ void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec) for (i = 0; i < 3; i++) { mpeg2_free(mpeg2dec->yuv_buf[i][0]); +#if MPEG2_COLOR mpeg2_free(mpeg2dec->yuv_buf[i][1]); mpeg2_free(mpeg2dec->yuv_buf[i][2]); +#endif } } @@ -840,8 +844,6 @@ void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec) if (!mpeg2dec->convert_start) { - int y_size, uv_size; - mpeg2dec->decoder.convert_id = mpeg2_malloc (mpeg2dec->convert_id_size, MPEG2_ALLOC_CONVERT_ID); @@ -855,32 +857,39 @@ void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec) mpeg2dec->convert_start = convert_init.start; mpeg2dec->decoder.convert = convert_init.copy; - y_size = decoder->stride_frame * mpeg2dec->sequence.height; - uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format); + int y_size = decoder->stride_frame * mpeg2dec->sequence.height; mpeg2dec->yuv_buf[0][0] = (uint8_t *) mpeg2_malloc(y_size, MPEG2_ALLOC_YUV); +#if MPEG2_COLOR + int uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format); + mpeg2dec->yuv_buf[0][1] = (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[0][2] = (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV); +#endif mpeg2dec->yuv_buf[1][0] = (uint8_t *) mpeg2_malloc(y_size, MPEG2_ALLOC_YUV); +#if MPEG2_COLOR mpeg2dec->yuv_buf[1][1] = (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[1][2] = (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV); - +#endif y_size = decoder->stride_frame * 32; - uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format); mpeg2dec->yuv_buf[2][0] = (uint8_t *) mpeg2_malloc(y_size, MPEG2_ALLOC_YUV); +#if MPEG2_COLOR + uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format); + mpeg2dec->yuv_buf[2][1] = (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[2][2] = (uint8_t *) mpeg2_malloc(uv_size, MPEG2_ALLOC_YUV); +#endif } if (!mpeg2dec->custom_fbuf) @@ -895,13 +904,16 @@ void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec) fbuf->buf[0] = (uint8_t *) mpeg2_malloc (convert_init.buf_size[0], MPEG2_ALLOC_CONVERTED); +#if MPEG2_COLOR fbuf->buf[1] = (uint8_t *) mpeg2_malloc (convert_init.buf_size[1], MPEG2_ALLOC_CONVERTED); fbuf->buf[2] = (uint8_t *) mpeg2_malloc (convert_init.buf_size[2], MPEG2_ALLOC_CONVERTED); +#endif } + mpeg2_set_fbuf (mpeg2dec, (decoder->coding_type == B_TYPE)); } } @@ -910,21 +922,23 @@ void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec) while (mpeg2dec->alloc_index < 3) { mpeg2_fbuf_t * fbuf; - int y_size, uv_size; fbuf = &mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index++].fbuf; fbuf->id = NULL; - y_size = decoder->stride_frame * mpeg2dec->sequence.height; - uv_size = y_size >> (2 - decoder->chroma_format); + int y_size = decoder->stride_frame * mpeg2dec->sequence.height; fbuf->buf[0] = (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV); +#if MPEG2_COLOR + int uv_size = y_size >> (2 - decoder->chroma_format); + fbuf->buf[1] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); fbuf->buf[2] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); +#endif } mpeg2_set_fbuf (mpeg2dec, (decoder->coding_type == B_TYPE)); diff --git a/apps/plugins/mpegplayer/mpeg2.h b/apps/plugins/mpegplayer/mpeg2.h index 824454feab..48e4aab66a 100644 --- a/apps/plugins/mpegplayer/mpeg2.h +++ b/apps/plugins/mpegplayer/mpeg2.h @@ -24,6 +24,8 @@ #ifndef MPEG2_H #define MPEG2_H +#include "mpeg2dec_config.h" + #define MPEG2_VERSION(a,b,c) (((a)<<16)|((b)<<8)|(c)) #define MPEG2_RELEASE MPEG2_VERSION (0, 4, 0) /* 0.4.0 */ @@ -100,7 +102,7 @@ typedef struct mpeg2_picture_s typedef struct mpeg2_fbuf_s { - uint8_t * buf[3]; + uint8_t * buf[MPEG2_COMPONENTS]; void * id; } mpeg2_fbuf_t; @@ -140,7 +142,7 @@ typedef enum typedef struct mpeg2_convert_init_s { unsigned int id_size; - unsigned int buf_size[3]; + unsigned int buf_size[MPEG2_COMPONENTS]; void (* start)(void * id, const mpeg2_fbuf_t * fbuf, const mpeg2_picture_t * picture, const mpeg2_gop_t * gop); void (* copy)(void * id, uint8_t * const * src, unsigned int v_offset); @@ -158,7 +160,8 @@ typedef int mpeg2_convert_t (int stage, void * id, void * arg, mpeg2_convert_init_t * result); int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg); int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride); -void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id); +void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[MPEG2_COMPONENTS], + void * id); void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf); mpeg2dec_t * mpeg2_init (void); @@ -175,8 +178,10 @@ void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end); void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2); -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]); void mpeg2_slice (mpeg2_decoder_t * decoder, int code, const uint8_t * buffer); typedef enum diff --git a/apps/plugins/mpegplayer/mpeg2_internal.h b/apps/plugins/mpegplayer/mpeg2_internal.h index ba46b85ac4..062100c85a 100644 --- a/apps/plugins/mpegplayer/mpeg2_internal.h +++ b/apps/plugins/mpegplayer/mpeg2_internal.h @@ -54,7 +54,7 @@ typedef void mpeg2_mc_fct (uint8_t *, const uint8_t *, int, int); typedef struct { - uint8_t * ref[2][3]; + uint8_t * ref[2][MPEG2_COMPONENTS]; uint8_t ** ref2[2]; int pmv[2][2]; int f_code[2]; @@ -74,7 +74,7 @@ struct mpeg2_decoder_s int bitstream_bits; /* used bits in working set */ const uint8_t * bitstream_ptr; /* buffer with stream data */ - uint8_t * dest[3]; + uint8_t * dest[MPEG2_COMPONENTS]; int offset; int stride; @@ -95,16 +95,12 @@ struct mpeg2_decoder_s motion_parser_t * motion_parser[5]; /* predictor for DC coefficients in intra blocks */ - int16_t dc_dct_pred[3]; + int16_t dc_dct_pred[MPEG2_COMPONENTS]; /* DCT coefficients */ -#ifdef CPU_COLDFIRE - int16_t *DCTblock; /* put buffer separately to have it in IRAM */ -#else - int16_t DCTblock[64] ATTR_ALIGN(64); -#endif + int16_t * ATTR_ALIGN(16) DCTblock; /* put buffer separately to have it in IRAM */ - uint8_t * picture_dest[3]; + uint8_t * picture_dest[MPEG2_COMPONENTS]; void (* convert) (void * convert_id, uint8_t * const * src, unsigned int v_offset); void * convert_id; @@ -174,7 +170,7 @@ struct mpeg2dec_s uint32_t ext_state; /* allocated in init - gcc has problems allocating such big structures */ - uint8_t * chunk_buffer; + uint8_t * ATTR_ALIGN(4) chunk_buffer; /* pointer to start of the current chunk */ uint8_t * chunk_start; /* pointer to current position in chunk_buffer */ @@ -207,7 +203,7 @@ struct mpeg2dec_s fbuf_alloc_t fbuf_alloc[3]; int custom_fbuf; - uint8_t * yuv_buf[3][3]; + uint8_t * yuv_buf[3][MPEG2_COMPONENTS]; int yuv_index; mpeg2_convert_t * convert; void * convert_arg; diff --git a/apps/plugins/mpegplayer/mpeg2dec_config.h b/apps/plugins/mpegplayer/mpeg2dec_config.h index b8ad11664a..dff19e6ac4 100644 --- a/apps/plugins/mpegplayer/mpeg2dec_config.h +++ b/apps/plugins/mpegplayer/mpeg2dec_config.h @@ -1,2 +1,15 @@ +/* $Id$ */ +#ifndef MPEG2DEC_CONFIG_H +#define MPEG2DEC_CONFIG_H + #define ATTRIBUTE_ALIGNED_MAX 16 +#ifdef HAVE_LCD_COLOR +#define MPEG2_COLOR 1 +#define MPEG2_COMPONENTS 3 +#else +#define MPEG2_COLOR 0 +#define MPEG2_COMPONENTS 1 +#endif + +#endif /* MPEG2DEC_CONFIG_H */ diff --git a/apps/plugins/mpegplayer/slice.c b/apps/plugins/mpegplayer/slice.c index a039eb8a25..3b6df97950 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