📄 slice.c
字号:
/* * slice.c * 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. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "config.h"#include <inttypes.h>#include "mpeg2.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);extern void (* mpeg2_idct_add) (int last, int16_t * block, uint8_t * dest, int stride);extern void (* mpeg2_cpu_state_save) (cpu_state_t * state);extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state);#include "vlc.h"static inline int get_macroblock_modes (mpeg2_decoder_t * const decoder){#define bit_buf (decoder->bitstream_buf)#define bits (decoder->bitstream_bits)#define bit_ptr (decoder->bitstream_ptr) int macroblock_modes; const MBtab * tab; switch (decoder->coding_type) { case I_TYPE: tab = MB_I + UBITS (bit_buf, 1); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if ((! (decoder->frame_pred_frame_dct)) && (decoder->picture_structure == FRAME_PICTURE)) { macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes; case P_TYPE: tab = MB_P + UBITS (bit_buf, 5); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if (decoder->picture_structure != FRAME_PICTURE) { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT; DUMPBITS (bit_buf, bits, 2); } return macroblock_modes | MACROBLOCK_MOTION_FORWARD; } else if (decoder->frame_pred_frame_dct) { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) 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_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 | MACROBLOCK_MOTION_FORWARD; } case B_TYPE: tab = MB_B + UBITS (bit_buf, 6); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if (decoder->picture_structure != FRAME_PICTURE) { if (! (macroblock_modes & MACROBLOCK_INTRA)) { 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 << MOTION_TYPE_SHIFT; return macroblock_modes; } else { if (macroblock_modes & MACROBLOCK_INTRA) goto intra; macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT; DUMPBITS (bit_buf, bits, 2); if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { intra: macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes; } case D_TYPE: DUMPBITS (bit_buf, bits, 1); return MACROBLOCK_INTRA; default: return 0; }#undef bit_buf#undef bits#undef bit_ptr}static inline void get_quantizer_scale (mpeg2_decoder_t * const decoder){#define bit_buf (decoder->bitstream_buf)#define bits (decoder->bitstream_bits)#define bit_ptr (decoder->bitstream_ptr) int quantizer_scale_code; quantizer_scale_code = UBITS (bit_buf, 5); DUMPBITS (bit_buf, bits, 5); 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 (mpeg2_decoder_t * const decoder, const int f_code){#define bit_buf (decoder->bitstream_buf)#define bits (decoder->bitstream_bits)#define bit_ptr (decoder->bitstream_ptr) int delta; int sign; const MVtab * tab; if (bit_buf & 0x80000000) { DUMPBITS (bit_buf, bits, 1); return 0; } else if (bit_buf >= 0x0c000000) { tab = MV_4 + UBITS (bit_buf, 4); delta = (tab->delta << f_code) + 1; bits += tab->len + f_code + 1; bit_buf <<= tab->len; sign = SBITS (bit_buf, 1); bit_buf <<= 1; if (f_code) delta += UBITS (bit_buf, f_code); bit_buf <<= f_code; return (delta ^ sign) - sign; } else { tab = MV_10 + UBITS (bit_buf, 10); delta = (tab->delta << f_code) + 1; bits += tab->len + 1; bit_buf <<= tab->len; sign = SBITS (bit_buf, 1); bit_buf <<= 1; if (f_code) { NEEDBITS (bit_buf, bits, bit_ptr); delta += UBITS (bit_buf, f_code); DUMPBITS (bit_buf, bits, f_code); } return (delta ^ sign) - sign; }#undef bit_buf#undef bits#undef bit_ptr}static inline int bound_motion_vector (const int vector, const int f_code){ return ((int32_t)vector << (27 - f_code)) >> (27 - f_code);}static inline int get_dmv (mpeg2_decoder_t * const decoder){#define bit_buf (decoder->bitstream_buf)#define bits (decoder->bitstream_bits)#define bit_ptr (decoder->bitstream_ptr) const DMVtab * tab; tab = DMV_2 + UBITS (bit_buf, 2); DUMPBITS (bit_buf, bits, tab->len); return tab->dmv;#undef bit_buf#undef bits#undef bit_ptr}static inline int get_coded_block_pattern (mpeg2_decoder_t * const decoder){#define bit_buf (decoder->bitstream_buf)#define bits (decoder->bitstream_bits)#define bit_ptr (decoder->bitstream_ptr) const CBPtab * tab; NEEDBITS (bit_buf, bits, bit_ptr); if (bit_buf >= 0x20000000) { tab = CBP_7 + (UBITS (bit_buf, 7) - 16); DUMPBITS (bit_buf, bits, tab->len); return tab->cbp; } else { tab = CBP_9 + UBITS (bit_buf, 9); DUMPBITS (bit_buf, bits, tab->len); return tab->cbp; }#undef bit_buf#undef bits#undef bit_ptr}static inline int get_luma_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; int dc_diff; if (bit_buf < 0xf8000000) { tab = DC_lum_5 + UBITS (bit_buf, 5); size = tab->size; if (size) { bits += tab->len + size; bit_buf <<= tab->len; dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); bit_buf <<= size; return dc_diff << decoder->intra_dc_precision; } else { DUMPBITS (bit_buf, bits, 3); return 0; } } else { tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); size = tab->size; DUMPBITS (bit_buf, bits, tab->len); 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 << decoder->intra_dc_precision; }#undef bit_buf#undef bits#undef bit_ptr}static inline int get_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; int dc_diff; 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; dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); bit_buf <<= size; return dc_diff << decoder->intra_dc_precision; } else { DUMPBITS (bit_buf, bits, 2); return 0; } } 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); dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); DUMPBITS (bit_buf, bits, size); return dc_diff << decoder->intra_dc_precision; }#undef bit_buf#undef bits#undef bit_ptr}#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 (mpeg2_decoder_t * const decoder, const uint16_t * const quant_matrix){ int i; 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); 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: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = (tab->level * quant_matrix[j]) >> 4; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; mismatch ^= val; bit_buf <<= 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -