📄 slice.c
字号:
#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 { \ 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) { \ if (mpeg2_cpu_state_restore) \ mpeg2_cpu_state_restore (&cpu_state); \ 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) cpu_state_t cpu_state; bitstream_init (decoder, buffer); if (slice_init (decoder, code)) return; if (mpeg2_cpu_state_save) mpeg2_cpu_state_save (&cpu_state); 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, macroblock_modes); if (macroblock_modes & MACROBLOCK_PATTERN) { int coded_block_pattern; int DCT_offset, DCT_stride; 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; } coded_block_pattern = get_coded_block_pattern (decoder); if (likely (decoder->chroma_format == 0)) { int offset = decoder->offset; uint8_t * dest_y = decoder->dest[0] + offset; if (coded_block_pattern & 1) slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride); if (coded_block_pattern & 2) slice_non_intra_DCT (decoder, 0, dest_y + 8, DCT_stride); if (coded_block_pattern & 4) slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride); if (coded_block_pattern & 8) slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); if (coded_block_pattern & 16) slice_non_intra_DCT (decoder, 1, decoder->dest[1] + (offset >> 1), decoder->uv_stride); if (coded_block_pattern & 32) slice_non_intra_DCT (decoder, 2, decoder->dest[2] + (offset >> 1), decoder->uv_stride); } else if (likely (decoder->chroma_format == 1)) { int offset; uint8_t * dest_y; coded_block_pattern |= bit_buf & (3 << 30); DUMPBITS (bit_buf, bits, 2); offset = decoder->offset; dest_y = decoder->dest[0] + offset; if (coded_block_pattern & 1) slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride); if (coded_block_pattern & 2) slice_non_intra_DCT (decoder, 0, dest_y + 8, DCT_stride); if (coded_block_pattern & 4) slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride); if (coded_block_pattern & 8) slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); DCT_stride >>= 1; DCT_offset = (DCT_offset + offset) >> 1; if
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -