📄 slice.c
字号:
MOTION (mpeg2_mc.avg, motion->ref[1], other_x, other_y, 16, 0); \
} \
MOTION_FUNCTIONS (420, MOTION_420, MOTION_FIELD_420, MOTION_DMV_420,
MOTION_ZERO_420)
MOTION_FUNCTIONS (422, MOTION_422, MOTION_FIELD_422, MOTION_DMV_422,
MOTION_ZERO_422)
MOTION_FUNCTIONS (444, MOTION_444, MOTION_FIELD_444, MOTION_DMV_444,
MOTION_ZERO_444)
/* like motion_frame, but parsing without actual motion compensation */
static void motion_fr_conceal (mpeg2_decoder_t * const decoder)
{
int tmp;
NEEDBITS (bit_buf, bits, bit_ptr);
tmp = (decoder->f_motion.pmv[0][0] +
get_motion_delta (decoder, decoder->f_motion.f_code[0]));
tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[0]);
decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[0][0] = tmp;
NEEDBITS (bit_buf, bits, bit_ptr);
tmp = (decoder->f_motion.pmv[0][1] +
get_motion_delta (decoder, decoder->f_motion.f_code[1]));
tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[1]);
decoder->f_motion.pmv[1][1] = decoder->f_motion.pmv[0][1] = tmp;
DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */
}
static void motion_fi_conceal (mpeg2_decoder_t * const decoder)
{
int tmp;
NEEDBITS (bit_buf, bits, bit_ptr);
DUMPBITS (bit_buf, bits, 1); /* remove field_select */
tmp = (decoder->f_motion.pmv[0][0] +
get_motion_delta (decoder, decoder->f_motion.f_code[0]));
tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[0]);
decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[0][0] = tmp;
NEEDBITS (bit_buf, bits, bit_ptr);
tmp = (decoder->f_motion.pmv[0][1] +
get_motion_delta (decoder, decoder->f_motion.f_code[1]));
tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[1]);
decoder->f_motion.pmv[1][1] = decoder->f_motion.pmv[0][1] = tmp;
DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */
}
#undef bit_buf
#undef bits
#undef bit_ptr
#define MOTION_CALL(routine,direction) \
do { \
if ((direction) & MACROBLOCK_MOTION_FORWARD) \
routine (decoder, &(decoder->f_motion), mpeg2_mc.put); \
if ((direction) & MACROBLOCK_MOTION_BACKWARD) \
routine (decoder, &(decoder->b_motion), \
((direction) & MACROBLOCK_MOTION_FORWARD ? \
mpeg2_mc.avg : mpeg2_mc.put)); \
} while (0)
#define NEXT_MACROBLOCK \
do { \
if(decoder->quant_store) \
decoder->quant_store[decoder->quant_stride*(decoder->v_offset>>4) \
+(decoder->offset>>4)] = decoder->quantizer_scale; \
decoder->offset += 16; \
if (decoder->offset == decoder->width) { \
do { /* just so we can use the break statement */ \
if (decoder->convert) { \
decoder->convert (decoder->convert_id, decoder->dest, \
decoder->v_offset); \
if (decoder->coding_type == B_TYPE) \
break; \
} \
decoder->dest[0] += decoder->slice_stride; \
decoder->dest[1] += decoder->slice_uv_stride; \
decoder->dest[2] += decoder->slice_uv_stride; \
} while (0); \
decoder->v_offset += 16; \
if (decoder->v_offset > decoder->limit_y) { \
_mm_empty(); \
return; \
} \
decoder->offset = 0; \
} \
} 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])
{
int offset, stride, height, bottom_field;
stride = decoder->stride_frame;
bottom_field = (decoder->picture_structure == BOTTOM_FIELD);
offset = bottom_field ? stride : 0;
height = decoder->height;
decoder->picture_dest[0] = current_fbuf[0] + offset;
decoder->picture_dest[1] = current_fbuf[1] + (offset >> 1);
decoder->picture_dest[2] = current_fbuf[2] + (offset >> 1);
decoder->f_motion.ref[0][0] = forward_fbuf[0] + offset;
decoder->f_motion.ref[0][1] = forward_fbuf[1] + (offset >> 1);
decoder->f_motion.ref[0][2] = forward_fbuf[2] + (offset >> 1);
decoder->b_motion.ref[0][0] = backward_fbuf[0] + offset;
decoder->b_motion.ref[0][1] = backward_fbuf[1] + (offset >> 1);
decoder->b_motion.ref[0][2] = backward_fbuf[2] + (offset >> 1);
if (decoder->picture_structure != FRAME_PICTURE) {
decoder->dmv_offset = bottom_field ? 1 : -1;
decoder->f_motion.ref2[0] = decoder->f_motion.ref[bottom_field];
decoder->f_motion.ref2[1] = decoder->f_motion.ref[!bottom_field];
decoder->b_motion.ref2[0] = decoder->b_motion.ref[bottom_field];
decoder->b_motion.ref2[1] = decoder->b_motion.ref[!bottom_field];
offset = stride - offset;
if (decoder->second_field && (decoder->coding_type != B_TYPE))
forward_fbuf = current_fbuf;
decoder->f_motion.ref[1][0] = forward_fbuf[0] + offset;
decoder->f_motion.ref[1][1] = forward_fbuf[1] + (offset >> 1);
decoder->f_motion.ref[1][2] = forward_fbuf[2] + (offset >> 1);
decoder->b_motion.ref[1][0] = backward_fbuf[0] + offset;
decoder->b_motion.ref[1][1] = backward_fbuf[1] + (offset >> 1);
decoder->b_motion.ref[1][2] = backward_fbuf[2] + (offset >> 1);
stride <<= 1;
height >>= 1;
}
decoder->stride = stride;
decoder->uv_stride = stride >> 1;
decoder->slice_stride = 16 * stride;
decoder->slice_uv_stride =
decoder->slice_stride >> (2 - decoder->chroma_format);
decoder->limit_x = 2 * decoder->width - 32;
decoder->limit_y_16 = 2 * height - 32;
decoder->limit_y_8 = 2 * height - 16;
decoder->limit_y = height - 16;
if (decoder->mpeg1) {
decoder->motion_parser[0] = motion_zero_420;
decoder->motion_parser[MC_FRAME] = motion_mp1;
decoder->motion_parser[4] = motion_reuse_420;
} else if (decoder->picture_structure == FRAME_PICTURE) {
if (decoder->chroma_format == 0) {
decoder->motion_parser[0] = motion_zero_420;
decoder->motion_parser[MC_FIELD] = motion_fr_field_420;
decoder->motion_parser[MC_FRAME] = motion_fr_frame_420;
decoder->motion_parser[MC_DMV] = motion_fr_dmv_420;
decoder->motion_parser[4] = motion_reuse_420;
} else if (decoder->chroma_format == 1) {
decoder->motion_parser[0] = motion_zero_422;
decoder->motion_parser[MC_FIELD] = motion_fr_field_422;
decoder->motion_parser[MC_FRAME] = motion_fr_frame_422;
decoder->motion_parser[MC_DMV] = motion_fr_dmv_422;
decoder->motion_parser[4] = motion_reuse_422;
} else {
decoder->motion_parser[0] = motion_zero_444;
decoder->motion_parser[MC_FIELD] = motion_fr_field_444;
decoder->motion_parser[MC_FRAME] = motion_fr_frame_444;
decoder->motion_parser[MC_DMV] = motion_fr_dmv_444;
decoder->motion_parser[4] = motion_reuse_444;
}
} else {
if (decoder->chroma_format == 0) {
decoder->motion_parser[0] = motion_zero_420;
decoder->motion_parser[MC_FIELD] = motion_fi_field_420;
decoder->motion_parser[MC_16X8] = motion_fi_16x8_420;
decoder->motion_parser[MC_DMV] = motion_fi_dmv_420;
decoder->motion_parser[4] = motion_reuse_420;
} else if (decoder->chroma_format == 1) {
decoder->motion_parser[0] = motion_zero_422;
decoder->motion_parser[MC_FIELD] = motion_fi_field_422;
decoder->motion_parser[MC_16X8] = motion_fi_16x8_422;
decoder->motion_parser[MC_DMV] = motion_fi_dmv_422;
decoder->motion_parser[4] = motion_reuse_422;
} else {
decoder->motion_parser[0] = motion_zero_444;
decoder->motion_parser[MC_FIELD] = motion_fi_field_444;
decoder->motion_parser[MC_16X8] = motion_fi_16x8_444;
decoder->motion_parser[MC_DMV] = motion_fi_dmv_444;
decoder->motion_parser[4] = motion_reuse_444;
}
}
}
static inline int slice_init (mpeg2_decoder_t * const decoder, int code)
{
#define bit_buf (decoder->bitstream_buf)
#define bits (decoder->bitstream_bits)
#define bit_ptr (decoder->bitstream_ptr)
int offset;
const MBAtab * mba;
decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] =
decoder->dc_dct_pred[2] = 16384;
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;
decoder->b_motion.pmv[0][0] = decoder->b_motion.pmv[0][1] = 0;
decoder->b_motion.pmv[1][0] = decoder->b_motion.pmv[1][1] = 0;
if (decoder->vertical_position_extension) {
code += UBITS (bit_buf, 3) << 7;
DUMPBITS (bit_buf, bits, 3);
}
decoder->v_offset = (code - 1) * 16;
offset = 0;
if (!(decoder->convert) || decoder->coding_type != B_TYPE)
offset = (code - 1) * decoder->slice_stride;
decoder->dest[0] = decoder->picture_dest[0] + offset;
offset >>= (2 - decoder->chroma_format);
decoder->dest[1] = decoder->picture_dest[1] + offset;
decoder->dest[2] = decoder->picture_dest[2] + offset;
get_quantizer_scale (decoder);
/* ignore intra_slice and all the extra data */
while (bit_buf & 0x80000000) {
DUMPBITS (bit_buf, bits, 9);
NEEDBITS (bit_buf, bits, bit_ptr);
}
/* decode initial macroblock address increment */
offset = 0;
while (1) {
if (bit_buf >= 0x08000000) {
mba = MBA_5 + (UBITS (bit_buf, 6) - 2);
break;
} else if (bit_buf >= 0x01800000) {
mba = MBA_11 + (UBITS (bit_buf, 12) - 24);
break;
} else switch (UBITS (bit_buf, 12)) {
case 8: /* macroblock_escape */
offset += 33;
DUMPBITS (bit_buf, bits, 11);
NEEDBITS (bit_buf, bits, bit_ptr);
continue;
case 15: /* macroblock_stuffing (MPEG1 only) */
bit_buf &= 0xfffff;
DUMPBITS (bit_buf, bits, 11);
NEEDBITS (bit_buf, bits, bit_ptr);
continue;
default: /* error */
return 1;
}
}
DUMPBITS (bit_buf, bits, mba->len + 1);
decoder->offset = (offset + mba->mba) << 4;
while (decoder->offset - decoder->width >= 0) {
decoder->offset -= decoder->width;
if (!(decoder->convert) || decoder->coding_type != B_TYPE) {
decoder->dest[0] += decoder->slice_stride;
decoder->dest[1] += decoder->slice_uv_stride;
decoder->dest[2] += decoder->slice_uv_stride;
}
decoder->v_offset += 16;
}
if (decoder->v_offset > decoder->limit_y)
return 1;
return 0;
#undef bit_buf
#undef bits
#undef bit_ptr
}
void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code,
const uint8_t * const buffer)
{
#define bit_buf (decoder->bitstream_buf)
#define bits (decoder->bitstream_bits)
#define bit_ptr (decoder->bitstream_ptr)
bitstream_init (decoder, buffer);
if (slice_init (decoder, code))
return;
_mm_empty();
while (1) {
int macroblock_modes;
int mba_inc;
const MBAtab * mba;
NEEDBITS (bit_buf, bits, bit_ptr);
macroblock_modes = get_macroblock_modes (decoder);
/* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */
if (macroblock_modes & MACROBLOCK_QUANT)
get_quantizer_scale (decoder);
if (macroblock_modes & MACROBLOCK_INTRA) {
int DCT_offset, DCT_stride;
int offset;
uint8_t * dest_y;
if (decoder->concealment_motion_vectors) {
if (decoder->picture_structure == FRAME_PICTURE)
motion_fr_conceal (decoder);
else
motion_fi_conceal (decoder);
} else {
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;
decoder->b_motion.pmv[0][0] = decoder->b_motion.pmv[0][1] = 0;
decoder->b_motion.pmv[1][0] = decoder->b_motion.pmv[1][1] = 0;
}
if (macroblock_modes & DCT_TYPE_INTERLACED) {
DCT_offset = decoder->stride;
DCT_stride = decoder->stride * 2;
} else {
DCT_offset = decoder->stride * 8;
DCT_stride = decoder->stride;
}
offset = decoder->offset;
dest_y = decoder->dest[0] + offset;
slice_intra_DCT (decoder, 0, dest_y, DCT_stride);
slice_intra_DCT (decoder, 0, dest_y + 8, DCT_stride);
slice_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride);
slice_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride);
if (likely (decoder->chroma_format == 0)) {
slice_intra_DCT (decoder, 1, decoder->dest[1] + (offset >> 1),
decoder->uv_stride);
slice_intra_DCT (decoder, 2, decoder->dest[2] + (offset >> 1),
decoder->uv_stride);
if (decoder->coding_type == D_TYPE) {
NEEDBITS (bit_buf, bits, bit_ptr);
DUMPBITS (bit_buf, bits, 1);
}
} else if (likely (decoder->chroma_format == 1)) {
uint8_t * dest_u = decoder->dest[1] + (offset >> 1);
uint8_t * dest_v = decoder->dest[2] + (offset >> 1);
DCT_stride >>= 1;
DCT_offset >>= 1;
slice_intra_DCT (decoder, 1, dest_u, DCT_stride);
slice_intra_DCT (decoder, 2, dest_v, DCT_stride);
slice_intra_DCT (decoder, 1, dest_u + DCT_offset, DCT_stride);
slice_intra_DCT (decoder, 2, dest_v + DCT_offset, DCT_stride);
} else {
uint8_t * dest_u = decoder->dest[1] + offset;
uint8_t * dest_v = decoder->dest[2] + offset;
slice_intra_DCT (decoder, 1, dest_u, DCT_stride);
slice_intra_DCT (decoder, 2, dest_v, DCT_stride);
slice_intra_DCT (decoder, 1, dest_u + DCT_offset, DCT_stride);
slice_intra_DCT (decoder, 2, dest_v + DCT_offset, DCT_stride);
slice_intra_DCT (decoder, 1, dest_u + 8, DCT_stride);
slice_intra_DCT (decoder, 2, dest_v + 8, DCT_stride);
slice_intra_DCT (decoder, 1, dest_u + DCT_offset + 8,
DCT_stride);
slice_intra_DCT (decoder, 2, dest_v + DCT_offset + 8,
DCT_stride);
}
} else {
motion_parser_t * parser;
parser =
decoder->motion_parser[macroblock_modes >> MOTION_TYPE_SHIFT];
MOTION_CALL (parser, macroblo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -