summaryrefslogtreecommitdiffstats
path: root/libmpeg2/slice.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmpeg2/slice.c')
-rw-r--r--libmpeg2/slice.c1299
1 files changed, 779 insertions, 520 deletions
diff --git a/libmpeg2/slice.c b/libmpeg2/slice.c
index 327612e0e4..15740e1151 100644
--- a/libmpeg2/slice.c
+++ b/libmpeg2/slice.c
@@ -1,6 +1,7 @@
/*
* slice.c
- * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
+ * Copyright (C) 2003 Peter Gubanov <peter@elecard.net.ru>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
@@ -26,8 +27,8 @@
#include <inttypes.h>
#include "mpeg2.h"
-#include "mpeg2_internal.h"
#include "attributes.h"
+#include "mpeg2_internal.h"
extern mpeg2_mc_t mpeg2_mc;
extern void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride);
@@ -38,14 +39,7 @@ extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state);
#include "vlc.h"
-static int non_linear_quantizer_scale [] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 10, 12, 14, 16, 18, 20, 22,
- 24, 28, 32, 36, 40, 44, 48, 52,
- 56, 64, 72, 80, 88, 96, 104, 112
-};
-
-static inline int get_macroblock_modes (decoder_t * const decoder)
+static inline int get_macroblock_modes (mpeg2_decoder_t * const decoder)
{
#define bit_buf (decoder->bitstream_buf)
#define bits (decoder->bitstream_bits)
@@ -76,24 +70,24 @@ static inline int get_macroblock_modes (decoder_t * const decoder)
if (decoder->picture_structure != FRAME_PICTURE) {
if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) {
- macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
DUMPBITS (bit_buf, bits, 2);
}
- return macroblock_modes;
+ return macroblock_modes | MACROBLOCK_MOTION_FORWARD;
} else if (decoder->frame_pred_frame_dct) {
if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
- macroblock_modes |= MC_FRAME;
- return macroblock_modes;
+ macroblock_modes |= MC_FRAME << MOTION_TYPE_SHIFT;
+ return macroblock_modes | MACROBLOCK_MOTION_FORWARD;
} else {
if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) {
- macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
DUMPBITS (bit_buf, bits, 2);
}
if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) {
macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
DUMPBITS (bit_buf, bits, 1);
}
- return macroblock_modes;
+ return macroblock_modes | MACROBLOCK_MOTION_FORWARD;
}
case B_TYPE:
@@ -104,18 +98,18 @@ static inline int get_macroblock_modes (decoder_t * const decoder)
if (decoder->picture_structure != FRAME_PICTURE) {
if (! (macroblock_modes & MACROBLOCK_INTRA)) {
- macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
DUMPBITS (bit_buf, bits, 2);
}
return macroblock_modes;
} else if (decoder->frame_pred_frame_dct) {
/* if (! (macroblock_modes & MACROBLOCK_INTRA)) */
- macroblock_modes |= MC_FRAME;
+ macroblock_modes |= MC_FRAME << MOTION_TYPE_SHIFT;
return macroblock_modes;
} else {
if (macroblock_modes & MACROBLOCK_INTRA)
goto intra;
- macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT;
DUMPBITS (bit_buf, bits, 2);
if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) {
intra:
@@ -138,7 +132,7 @@ static inline int get_macroblock_modes (decoder_t * const decoder)
#undef bit_ptr
}
-static inline int get_quantizer_scale (decoder_t * const decoder)
+static inline void get_quantizer_scale (mpeg2_decoder_t * const decoder)
{
#define bit_buf (decoder->bitstream_buf)
#define bits (decoder->bitstream_bits)
@@ -149,16 +143,20 @@ static inline int get_quantizer_scale (decoder_t * const decoder)
quantizer_scale_code = UBITS (bit_buf, 5);
DUMPBITS (bit_buf, bits, 5);
- if (decoder->q_scale_type)
- return non_linear_quantizer_scale [quantizer_scale_code];
- else
- return quantizer_scale_code << 1;
+ decoder->quantizer_matrix[0] =
+ decoder->quantizer_prescale[0][quantizer_scale_code];
+ decoder->quantizer_matrix[1] =
+ decoder->quantizer_prescale[1][quantizer_scale_code];
+ decoder->quantizer_matrix[2] =
+ decoder->chroma_quantizer[0][quantizer_scale_code];
+ decoder->quantizer_matrix[3] =
+ decoder->chroma_quantizer[1][quantizer_scale_code];
#undef bit_buf
#undef bits
#undef bit_ptr
}
-static inline int get_motion_delta (decoder_t * const decoder,
+static inline int get_motion_delta (mpeg2_decoder_t * const decoder,
const int f_code)
{
#define bit_buf (decoder->bitstream_buf)
@@ -214,24 +212,10 @@ static inline int get_motion_delta (decoder_t * const decoder,
static inline int bound_motion_vector (const int vector, const int f_code)
{
-#if 0
- unsigned int limit;
- int sign;
-
- limit = 16 << f_code;
-
- if ((unsigned int)(vector + limit) < 2 * limit)
- return vector;
- else {
- sign = ((int32_t)vector) >> 31;
- return vector - ((2 * limit) ^ sign) + sign;
- }
-#else
return ((int32_t)vector << (27 - f_code)) >> (27 - f_code);
-#endif
}
-static inline int get_dmv (decoder_t * const decoder)
+static inline int get_dmv (mpeg2_decoder_t * const decoder)
{
#define bit_buf (decoder->bitstream_buf)
#define bits (decoder->bitstream_bits)
@@ -247,7 +231,7 @@ static inline int get_dmv (decoder_t * const decoder)
#undef bit_ptr
}
-static inline int get_coded_block_pattern (decoder_t * const decoder)
+static inline int get_coded_block_pattern (mpeg2_decoder_t * const decoder)
{
#define bit_buf (decoder->bitstream_buf)
#define bits (decoder->bitstream_bits)
@@ -275,7 +259,7 @@ static inline int get_coded_block_pattern (decoder_t * const decoder)
#undef bit_ptr
}
-static inline int get_luma_dc_dct_diff (decoder_t * const decoder)
+static inline int get_luma_dc_dct_diff (mpeg2_decoder_t * const decoder)
{
#define bit_buf (decoder->bitstream_buf)
#define bits (decoder->bitstream_bits)
@@ -293,7 +277,7 @@ static inline int get_luma_dc_dct_diff (decoder_t * const decoder)
dc_diff =
UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
bit_buf <<= size;
- return dc_diff;
+ return dc_diff << decoder->intra_dc_precision;
} else {
DUMPBITS (bit_buf, bits, 3);
return 0;
@@ -305,14 +289,14 @@ static inline int get_luma_dc_dct_diff (decoder_t * const decoder)
NEEDBITS (bit_buf, bits, bit_ptr);
dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
DUMPBITS (bit_buf, bits, size);
- return dc_diff;
+ return dc_diff << decoder->intra_dc_precision;
}
#undef bit_buf
#undef bits
#undef bit_ptr
}
-static inline int get_chroma_dc_dct_diff (decoder_t * const decoder)
+static inline int get_chroma_dc_dct_diff (mpeg2_decoder_t * const decoder)
{
#define bit_buf (decoder->bitstream_buf)
#define bits (decoder->bitstream_bits)
@@ -330,7 +314,7 @@ static inline int get_chroma_dc_dct_diff (decoder_t * const decoder)
dc_diff =
UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
bit_buf <<= size;
- return dc_diff;
+ return dc_diff << decoder->intra_dc_precision;
} else {
DUMPBITS (bit_buf, bits, 2);
return 0;
@@ -342,35 +326,34 @@ static inline int get_chroma_dc_dct_diff (decoder_t * const decoder)
NEEDBITS (bit_buf, bits, bit_ptr);
dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
DUMPBITS (bit_buf, bits, size);
- return dc_diff;
+ return dc_diff << decoder->intra_dc_precision;
}
#undef bit_buf
#undef bits
#undef bit_ptr
}
-#define SATURATE(val) \
-do { \
- if (unlikely ((uint32_t)(val + 2048) > 4095)) \
- val = SBITS (val, 1) ^ 2047; \
+#define SATURATE(val) \
+do { \
+ val <<= 4; \
+ if (unlikely (val != (int16_t) val)) \
+ val = (SBITS (val, 1) ^ 2047) << 4; \
} while (0)
-static void get_intra_block_B14 (decoder_t * const decoder)
+static void get_intra_block_B14 (mpeg2_decoder_t * const decoder,
+ const uint16_t * const quant_matrix)
{
int i;
int j;
int val;
- const uint8_t * scan = decoder->scan;
- const uint8_t * quant_matrix = decoder->intra_quantizer_matrix;
- int quantizer_scale = decoder->quantizer_scale;
+ 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 * dest;
+ int16_t * const dest = decoder->DCTblock;
- dest = decoder->DCTblock;
i = 0;
mismatch = ~dest[0];
@@ -393,7 +376,7 @@ static void get_intra_block_B14 (decoder_t * const decoder)
j = scan[i];
bit_buf <<= tab->len;
bits += tab->len + 1;
- val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4;
+ val = (tab->level * quant_matrix[j]) >> 4;
/* if (bitstream_get (1)) val = -val; */
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
@@ -425,8 +408,7 @@ static void get_intra_block_B14 (decoder_t * const decoder)
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits, bit_ptr);
- val = (SBITS (bit_buf, 12) *
- quantizer_scale * quant_matrix[j]) / 16;
+ val = (SBITS (bit_buf, 12) * quant_matrix[j]) / 16;
SATURATE (val);
dest[j] = val;
@@ -462,29 +444,27 @@ static void get_intra_block_B14 (decoder_t * const decoder)
}
break; /* illegal, check needed to avoid buffer overflow */
}
- dest[63] ^= mismatch & 1;
+ dest[63] ^= mismatch & 16;
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 get_intra_block_B15 (decoder_t * const decoder)
+static void get_intra_block_B15 (mpeg2_decoder_t * const decoder,
+ const uint16_t * const quant_matrix)
{
int i;
int j;
int val;
- const uint8_t * scan = decoder->scan;
- const uint8_t * quant_matrix = decoder->intra_quantizer_matrix;
- int quantizer_scale = decoder->quantizer_scale;
+ 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 * dest;
+ int16_t * const dest = decoder->DCTblock;
- dest = decoder->DCTblock;
i = 0;
mismatch = ~dest[0];
@@ -506,7 +486,7 @@ static void get_intra_block_B15 (decoder_t * const decoder)
j = scan[i];
bit_buf <<= tab->len;
bits += tab->len + 1;
- val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4;
+ val = (tab->level * quant_matrix[j]) >> 4;
/* if (bitstream_get (1)) val = -val; */
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
@@ -537,8 +517,7 @@ static void get_intra_block_B15 (decoder_t * const decoder)
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits, bit_ptr);
- val = (SBITS (bit_buf, 12) *
- quantizer_scale * quant_matrix[j]) / 16;
+ val = (SBITS (bit_buf, 12) * quant_matrix[j]) / 16;
SATURATE (val);
dest[j] = val;
@@ -575,31 +554,29 @@ static void get_intra_block_B15 (decoder_t * const decoder)
}
break; /* illegal, check needed to avoid buffer overflow */
}
- dest[63] ^= mismatch & 1;
+ dest[63] ^= mismatch & 16;
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 int get_non_intra_block (decoder_t * const decoder)
+static int get_non_intra_block (mpeg2_decoder_t * const decoder,
+ const uint16_t * const quant_matrix)
{
int i;
int j;
int val;
- const uint8_t * scan = decoder->scan;
- const uint8_t * quant_matrix = decoder->non_intra_quantizer_matrix;
- int quantizer_scale = decoder->quantizer_scale;
+ 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 * dest;
+ int16_t * const dest = decoder->DCTblock;
i = -1;
- mismatch = 1;
- dest = decoder->DCTblock;
+ mismatch = -1;
bit_buf = decoder->bitstream_buf;
bits = decoder->bitstream_bits;
@@ -626,7 +603,7 @@ static int get_non_intra_block (decoder_t * const decoder)
j = scan[i];
bit_buf <<= tab->len;
bits += tab->len + 1;
- val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5;
+ val = ((2 * tab->level + 1) * quant_matrix[j]) >> 5;
/* if (bitstream_get (1)) val = -val; */
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
@@ -662,7 +639,7 @@ static int get_non_intra_block (decoder_t * const decoder)
DUMPBITS (bit_buf, bits, 12);
NEEDBITS (bit_buf, bits, bit_ptr);
val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1;
- val = (val * quantizer_scale * quant_matrix[j]) / 32;
+ val = (val * quant_matrix[j]) / 32;
SATURATE (val);
dest[j] = val;
@@ -698,7 +675,7 @@ static int get_non_intra_block (decoder_t * const decoder)
}
break; /* illegal, check needed to avoid buffer overflow */
}
- dest[63] ^= mismatch & 1;
+ dest[63] ^= mismatch & 16;
DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
decoder->bitstream_buf = bit_buf;
decoder->bitstream_bits = bits;
@@ -706,22 +683,20 @@ static int get_non_intra_block (decoder_t * const decoder)
return i;
}
-static void get_mpeg1_intra_block (decoder_t * const decoder)
+static void get_mpeg1_intra_block (mpeg2_decoder_t * const decoder)
{
int i;
int j;
int val;
- const uint8_t * scan = decoder->scan;
- const uint8_t * quant_matrix = decoder->intra_quantizer_matrix;
- int quantizer_scale = decoder->quantizer_scale;
+ 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 * dest;
+ int16_t * const dest = decoder->DCTblock;
i = 0;
- dest = decoder->DCTblock;
bit_buf = decoder->bitstream_buf;
bits = decoder->bitstream_bits;
@@ -742,7 +717,7 @@ static void get_mpeg1_intra_block (decoder_t * const decoder)
j = scan[i];
bit_buf <<= tab->len;
bits += tab->len + 1;
- val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4;
+ val = (tab->level * quant_matrix[j]) >> 4;
/* oddification */
val = (val - 1) | 1;
@@ -781,7 +756,7 @@ static void get_mpeg1_intra_block (decoder_t * const decoder)
DUMPBITS (bit_buf, bits, 8);
val = UBITS (bit_buf, 8) + 2 * val;
}
- val = (val * quantizer_scale * quant_matrix[j]) / 16;
+ val = (val * quant_matrix[j]) / 16;
/* oddification */
val = (val + ~SBITS (val, 1)) | 1;
@@ -825,22 +800,20 @@ static void get_mpeg1_intra_block (decoder_t * const decoder)
decoder->bitstream_ptr = bit_ptr;
}
-static int get_mpeg1_non_intra_block (decoder_t * const decoder)
+static int get_mpeg1_non_intra_block (mpeg2_decoder_t * const decoder)
{
int i;
int j;
int val;
- const uint8_t * scan = decoder->scan;
- const uint8_t * quant_matrix = decoder->non_intra_quantizer_matrix;
- int quantizer_scale = decoder->quantizer_scale;
+ const uint8_t * const scan = decoder->scan;
+ const uint16_t * const quant_matrix = decoder->quantizer_matrix[1];
const DCTtab * tab;
uint32_t bit_buf;
int bits;
const uint8_t * bit_ptr;
- int16_t * dest;
+ int16_t * const dest = decoder->DCTblock;
i = -1;
- dest = decoder->DCTblock;
bit_buf = decoder->bitstream_buf;
bits = decoder->bitstream_bits;
@@ -867,7 +840,7 @@ static int get_mpeg1_non_intra_block (decoder_t * const decoder)
j = scan[i];
bit_buf <<= tab->len;
bits += tab->len + 1;
- val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5;
+ val = ((2 * tab->level + 1) * quant_matrix[j]) >> 5;
/* oddification */
val = (val - 1) | 1;
@@ -910,7 +883,7 @@ static int get_mpeg1_non_intra_block (decoder_t * const decoder)
val = UBITS (bit_buf, 8) + 2 * val;
}
val = 2 * (val + SBITS (val, 1)) + 1;
- val = (val * quantizer_scale * quant_matrix[j]) / 32;
+ val = (val * quant_matrix[j]) / 32;
/* oddification */
val = (val + ~SBITS (val, 1)) | 1;
@@ -955,7 +928,8 @@ static int get_mpeg1_non_intra_block (decoder_t * const decoder)
return i;
}
-static inline void slice_intra_DCT (decoder_t * const decoder, const int cc,
+static inline void slice_intra_DCT (mpeg2_decoder_t * const decoder,
+ const int cc,
uint8_t * const dest, const int stride)
{
#define bit_buf (decoder->bitstream_buf)
@@ -964,26 +938,27 @@ static inline void slice_intra_DCT (decoder_t * const decoder, const int cc,
NEEDBITS (bit_buf, bits, bit_ptr);
/* Get the intra DC coefficient and inverse quantize it */
if (cc == 0)
- decoder->dc_dct_pred[0] += get_luma_dc_dct_diff (decoder);
+ decoder->DCTblock[0] =
+ decoder->dc_dct_pred[0] += get_luma_dc_dct_diff (decoder);
else
- decoder->dc_dct_pred[cc] += get_chroma_dc_dct_diff (decoder);
- decoder->DCTblock[0] =
- decoder->dc_dct_pred[cc] << (3 - decoder->intra_dc_precision);
+ decoder->DCTblock[0] =
+ decoder->dc_dct_pred[cc] += get_chroma_dc_dct_diff (decoder);
if (decoder->mpeg1) {
if (decoder->coding_type != D_TYPE)
get_mpeg1_intra_block (decoder);
} else if (decoder->intra_vlc_format)
- get_intra_block_B15 (decoder);
+ get_intra_block_B15 (decoder, decoder->quantizer_matrix[cc ? 2 : 0]);
else
- get_intra_block_B14 (decoder);
+ get_intra_block_B14 (decoder, decoder->quantizer_matrix[cc ? 2 : 0]);
mpeg2_idct_copy (decoder->DCTblock, dest, stride);
#undef bit_buf
#undef bits
#undef bit_ptr
}
-static inline void slice_non_intra_DCT (decoder_t * const decoder,
+static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder,
+ const int cc,
uint8_t * const dest, const int stride)
{
int last;
@@ -991,15 +966,22 @@ static inline void slice_non_intra_DCT (decoder_t * const decoder,
if (decoder->mpeg1)
last = get_mpeg1_non_intra_block (decoder);
else
- last = get_non_intra_block (decoder);
+ last = get_non_intra_block (decoder,
+ decoder->quantizer_matrix[cc ? 3 : 1]);
mpeg2_idct_add (last, decoder->DCTblock, dest, stride);
}
-#define MOTION(table,ref,motion_x,motion_y,size,y) \
+#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; \
- if ((pos_x > decoder->limit_x) || (pos_y > decoder->limit_y_ ## size)) \
- return; \
+ if (unlikely (pos_x > decoder->limit_x)) { \
+ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
+ motion_x = pos_x - 2 * decoder->offset; \
+ } \
+ if (unlikely (pos_y > decoder->limit_y_ ## size)) { \
+ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \
+ motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \
+ } \
xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \
ref[0] + (pos_x >> 1) + (pos_y >> 1) * decoder->stride, \
@@ -1016,11 +998,17 @@ static inline void slice_non_intra_DCT (decoder_t * const decoder,
(decoder->offset >> 1), ref[2] + offset, \
decoder->uv_stride, size/2)
-#define MOTION_FIELD(table,ref,motion_x,motion_y,dest_field,op,src_field) \
+#define MOTION_FIELD_420(table,ref,motion_x,motion_y,dest_field,op,src_field) \
pos_x = 2 * decoder->offset + motion_x; \
pos_y = decoder->v_offset + motion_y; \
- if ((pos_x > decoder->limit_x) || (pos_y > decoder->limit_y)) \
- return; \
+ if (unlikely (pos_x > decoder->limit_x)) { \
+ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
+ motion_x = pos_x - 2 * decoder->offset; \
+ } \
+ if (unlikely (pos_y > decoder->limit_y)) { \
+ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
+ motion_y = pos_y - decoder->v_offset; \
+ } \
xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \
decoder->offset, \
@@ -1039,12 +1027,237 @@ static inline void slice_non_intra_DCT (decoder_t * const decoder,
(decoder->offset >> 1), ref[2] + offset, \
2 * decoder->uv_stride, 4)
-static void motion_mp1 (decoder_t * const decoder, motion_t * const motion,
- mpeg2_mc_fct * const * const table)
-{
+#define MOTION_DMV_420(table,ref,motion_x,motion_y) \
+ pos_x = 2 * decoder->offset + motion_x; \
+ pos_y = decoder->v_offset + motion_y; \
+ if (unlikely (pos_x > decoder->limit_x)) { \
+ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
+ motion_x = pos_x - 2 * decoder->offset; \
+ } \
+ if (unlikely (pos_y > decoder->limit_y)) { \
+ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
+ motion_y = pos_y - decoder->v_offset; \
+ } \
+ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
+ offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \
+ table[xy_half] (decoder->dest[0] + decoder->offset, \
+ ref[0] + offset, 2 * decoder->stride, 8); \
+ table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \
+ ref[0] + decoder->stride + offset, \
+ 2 * decoder->stride, 8); \
+ motion_x /= 2; motion_y /= 2; \
+ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \
+ offset = (((decoder->offset + motion_x) >> 1) + \
+ (((decoder->v_offset >> 1) + (motion_y & ~1)) * \
+ decoder->uv_stride)); \
+ table[4+xy_half] (decoder->dest[1] + (decoder->offset >> 1), \
+ ref[1] + offset, 2 * decoder->uv_stride, 4); \
+ table[4+xy_half] (decoder->dest[1] + decoder->uv_stride + \
+ (decoder->offset >> 1), \
+ ref[1] + decoder->uv_stride + offset, \
+ 2 * decoder->uv_stride, 4); \
+ table[4+xy_half] (decoder->dest[2] + (decoder->offset >> 1), \
+ ref[2] + offset, 2 * decoder->uv_stride, 4); \
+ table[4+xy_half] (decoder->dest[2] + decoder->uv_stride + \
+ (decoder->offset >> 1), \
+ ref[2] + decoder->uv_stride + offset, \
+ 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); \
+ 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)
+
+#define MOTION_422(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; \
+ if (unlikely (pos_x > decoder->limit_x)) { \
+ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
+ motion_x = pos_x - 2 * decoder->offset; \
+ } \
+ if (unlikely (pos_y > decoder->limit_y_ ## size)) { \
+ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \
+ motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \
+ } \
+ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
+ offset = (pos_x >> 1) + (pos_y >> 1) * decoder->stride; \
+ table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \
+ ref[0] + offset, decoder->stride, size); \
+ offset = (offset + (motion_x & (motion_x < 0))) >> 1; \
+ motion_x /= 2; \
+ xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \
+ table[4+xy_half] (decoder->dest[1] + y * decoder->uv_stride + \
+ (decoder->offset >> 1), ref[1] + offset, \
+ 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)
+
+#define MOTION_FIELD_422(table,ref,motion_x,motion_y,dest_field,op,src_field) \
+ pos_x = 2 * decoder->offset + motion_x; \
+ pos_y = decoder->v_offset + motion_y; \
+ if (unlikely (pos_x > decoder->limit_x)) { \
+ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
+ motion_x = pos_x - 2 * decoder->offset; \
+ } \
+ if (unlikely (pos_y > decoder->limit_y)) { \
+ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
+ motion_y = pos_y - decoder->v_offset; \
+ } \
+ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
+ offset = (pos_x >> 1) + ((pos_y op) + src_field) * decoder->stride; \
+ table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \
+ decoder->offset, ref[0] + offset, \
+ 2 * decoder->stride, 8); \
+ offset = (offset + (motion_x & (motion_x < 0))) >> 1; \
+ motion_x /= 2; \
+ xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \
+ table[4+xy_half] (decoder->dest[1] + dest_field * decoder->uv_stride + \
+ (decoder->offset >> 1), ref[1] + offset, \
+ 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)
+
+#define MOTION_DMV_422(table,ref,motion_x,motion_y) \
+ pos_x = 2 * decoder->offset + motion_x; \
+ pos_y = decoder->v_offset + motion_y; \
+ if (unlikely (pos_x > decoder->limit_x)) { \
+ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
+ motion_x = pos_x - 2 * decoder->offset; \
+ } \
+ if (unlikely (pos_y > decoder->limit_y)) { \
+ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
+ motion_y = pos_y - decoder->v_offset; \
+ } \
+ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
+ offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \
+ table[xy_half] (decoder->dest[0] + decoder->offset, \
+ ref[0] + offset, 2 * decoder->stride, 8); \
+ table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \
+ ref[0] + decoder->stride + offset, \
+ 2 * decoder->stride, 8); \
+ offset = (offset + (motion_x & (motion_x < 0))) >> 1; \
+ motion_x /= 2; \
+ xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \
+ table[4+xy_half] (decoder->dest[1] + (decoder->offset >> 1), \
+ ref[1] + offset, 2 * decoder->uv_stride, 8); \
+ table[4+xy_half] (decoder->dest[1] + decoder->uv_stride + \
+ (decoder->offset >> 1), \
+ ref[1] + decoder->uv_stride + offset, \
+ 2 * decoder->uv_stride, 8); \
+ table[4+xy_half] (decoder->dest[2] + (decoder->offset >> 1), \
+ ref[2] + offset, 2 * decoder->uv_stride, 8); \
+ table[4+xy_half] (decoder->dest[2] + decoder->uv_stride + \
+ (decoder->offset >> 1), \
+ ref[2] + decoder->uv_stride + offset, \
+ 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); \
+ 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)
+
+#define MOTION_444(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; \
+ if (unlikely (pos_x > decoder->limit_x)) { \
+ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
+ motion_x = pos_x - 2 * decoder->offset; \
+ } \
+ if (unlikely (pos_y > decoder->limit_y_ ## size)) { \
+ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \
+ motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \
+ } \
+ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
+ offset = (pos_x >> 1) + (pos_y >> 1) * decoder->stride; \
+ table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \
+ ref[0] + offset, decoder->stride, size); \
+ 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)
+
+#define MOTION_FIELD_444(table,ref,motion_x,motion_y,dest_field,op,src_field) \
+ pos_x = 2 * decoder->offset + motion_x; \
+ pos_y = decoder->v_offset + motion_y; \
+ if (unlikely (pos_x > decoder->limit_x)) { \
+ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
+ motion_x = pos_x - 2 * decoder->offset; \
+ } \
+ if (unlikely (pos_y > decoder->limit_y)) { \
+ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
+ motion_y = pos_y - decoder->v_offset; \
+ } \
+ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
+ offset = (pos_x >> 1) + ((pos_y op) + src_field) * decoder->stride; \
+ table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \
+ decoder->offset, ref[0] + offset, \
+ 2 * decoder->stride, 8); \
+ 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)
+
+#define MOTION_DMV_444(table,ref,motion_x,motion_y) \
+ pos_x = 2 * decoder->offset + motion_x; \
+ pos_y = decoder->v_offset + motion_y; \
+ if (unlikely (pos_x > decoder->limit_x)) { \
+ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \
+ motion_x = pos_x - 2 * decoder->offset; \
+ } \
+ if (unlikely (pos_y > decoder->limit_y)) { \
+ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \
+ motion_y = pos_y - decoder->v_offset; \
+ } \
+ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \
+ offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \
+ table[xy_half] (decoder->dest[0] + decoder->offset, \
+ ref[0] + offset, 2 * decoder->stride, 8); \
+ table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \
+ ref[0] + decoder->stride + offset, \
+ 2 * decoder->stride, 8); \
+ 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, \
+ ref[1] + decoder->stride + offset, \
+ 2 * decoder->stride, 8); \
+ table[xy_half] (decoder->dest[2] + decoder->offset, \
+ 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)
+
+#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); \
+ 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)
+
#define bit_buf (decoder->bitstream_buf)
#define bits (decoder->bitstream_bits)
#define bit_ptr (decoder->bitstream_ptr)
+
+static void motion_mp1 (mpeg2_decoder_t * const decoder,
+ motion_t * const motion,
+ mpeg2_mc_fct * const * const table)
+{
int motion_x, motion_y;
unsigned int pos_x, pos_y, xy_half, offset;
@@ -1064,192 +1277,239 @@ static void motion_mp1 (decoder_t * const decoder, motion_t * const motion,
motion->f_code[0] + motion->f_code[1]);
motion->pmv[0][1] = motion_y;
- MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0);
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-static void motion_fr_frame (decoder_t * const decoder,
- motion_t * const motion,
- mpeg2_mc_fct * const * const table)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
- int motion_x, motion_y;
- unsigned int pos_x, pos_y, xy_half, offset;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- motion_x = motion->pmv[0][0] + get_motion_delta (decoder,
- motion->f_code[0]);
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
- motion->pmv[1][0] = motion->pmv[0][0] = motion_x;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- motion_y = motion->pmv[0][1] + get_motion_delta (decoder,
- motion->f_code[1]);
- motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
- motion->pmv[1][1] = motion->pmv[0][1] = motion_y;
-
- MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0);
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-static void motion_fr_field (decoder_t * const decoder,
- motion_t * const motion,
- mpeg2_mc_fct * const * const table)
-{
-#define bit_buf (decoder->bitstream_buf)
-#define bits (decoder->bitstream_bits)
-#define bit_ptr (decoder->bitstream_ptr)
- int motion_x, motion_y, field;
- unsigned int pos_x, pos_y, xy_half, offset;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- field = UBITS (bit_buf, 1);
- DUMPBITS (bit_buf, bits, 1);
-
- motion_x = motion->pmv[0][0] + get_motion_delta (decoder,
- motion->f_code[0]);
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
- motion->pmv[0][0] = motion_x;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (decoder,
- motion->f_code[1]);
- /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */
- motion->pmv[0][1] = motion_y << 1;
-
- MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 0, & ~1, field);
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- field = UBITS (bit_buf, 1);
- DUMPBITS (bit_buf, bits, 1);
-
- motion_x = motion->pmv[1][0] + get_motion_delta (decoder,
- motion->f_code[0]);
- motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
- motion->pmv[1][0] = motion_x;
-
- NEEDBITS (bit_buf, bits, bit_ptr);
- motion_y = (motion->pmv[1][1] >> 1) + get_motion_delta (decoder,
- motion->f_code[1]);
- /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */
- motion->pmv[1][1] = motion_y << 1;
-
- MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 1, & ~1, field);
-#undef bit_buf
-#undef bits
-#undef bit_ptr
-}
-
-static void motion_fr_dmv (decoder_t * const decoder, motion_t * const motion,
- mpeg2_mc_fct * const