📄 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 <stdio.h>#include <stdlib.h>#include <string.h>#include "mpeg2.h"#include "attributes.h"#include "mpeg2_internal.h"// $PP#include "mae_pass_thru.h"#include "defines.h"#include "sliceMAE.h"#ifdef UNDER_CE#include <windows.h>#define MSG_INFO 0#define NO_ASM#else //!UNDER_CE#include "cmodelif.h"#endif //UNDER_CE// $PP#ifdef NO_PERFextern mpeg2_mc_t mpeg2_mc;#elsempeg2_mc_t mpeg2_mc = { { 0,0,0,0,0,0,0,0 }, { 0,0,0,0,0,0,0,0 }};#endif //#ifdef NO_PERFextern void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride, mpeg2_decoder_t*, int);extern void (* mpeg2_idct_add) (int last, int16_t * block, uint8_t * dest, int stride, mpeg2_decoder_t *, int);extern void (* mpeg2_cpu_state_save) (cpu_state_t * state);extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state);// $PPextern void motion_mp1 (mpeg2_decoder_t * const, motion_t * const, mpeg2_mc_fct * const *const);extern void motion_fr_frame_420 (mpeg2_decoder_t * const, motion_t * const, mpeg2_mc_fct * const *const);extern void motion_fr_field_420 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fr_dmv_420 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_reuse_420 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_zero_420 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fi_field_420 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fi_16x8_420 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fi_dmv_420 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fr_frame_422 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fr_field_422 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fr_dmv_422 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_reuse_422 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_zero_422 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fi_field_422 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fi_16x8_422 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fi_dmv_422 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fr_frame_444 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fr_field_444 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fr_dmv_444 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_reuse_444 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_zero_444 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fi_field_444 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fi_16x8_444 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fi_dmv_444 (mpeg2_decoder_t * const , motion_t * const , mpeg2_mc_fct * const *const );extern void motion_fr_conceal (mpeg2_decoder_t * const );extern void motion_fi_conceal (mpeg2_decoder_t * const );#ifdef NO_PERF#define STATIC_INLINE static inline#else#define STATIC_INLINE inline#endif //#ifdef NO_PERFSTATIC_INLINE int get_mpeg1_non_intra_block (mpeg2_decoder_t * const , short int *);STATIC_INLINE void get_mpeg1_intra_block (mpeg2_decoder_t * const , short int *);#ifdef NO_PERFvoid WriteFrame (mpeg2_decoder_t * const decoder, unsigned char ucAction, unsigned long ulField);#endif //#ifdef NO_PERF// $PPextern uint8_t my_mpeg2_scan_norm[64];extern uint8_t my_mpeg2_scan_alt[64];extern uint8_t mpeg2_scan_norm[64];extern uint8_t mpeg2_scan_alt[64];// KK - rev2#ifdef NEW_MAE_DRIVERextern int nDMVUpdate;extern int nDMVUpdate1;#endif// ~KK - rev2#include "vlc.h"unsigned char ucMarkFrameSet = 0;unsigned char ucMarkFieldSet = 0;header_words local_header;#if !defined(NO_ASM) && (defined(MIPS) || defined(__mips__))/* for mips - these routines are optimized in slice_asm.S */#define COPY_128B_16A(_src_, _dst_) copy_32_aligned_words(_src_, _dst_)#define SWIZ_64B_8A(_src_, _dst_) swizzle_64b_8a(_src_,_dst_)#define SWIZ_128B_16A(_src_, _dst_) swizzle_128b_16a(_src_,_dst_)#define ZERO_128B(_src_) zero_128b_32a(_src_)#define COPY_16B(_src_, _dst_) copy_16b_32a(_src_, _dst_)#else#define SWIZ_64B_8A(_src_, _dst_) memcpy(_dst_, _src_, 64)#define SWIZ_128B_16A(_src_, _dst_) memcpy(_dst_, _src_, 128)#define COPY_128B_16A(_src_, _dst_) if (_dst_) memcpy(_dst_, _src_, 32*4);#define ZERO_128B(_src_) if (_src_) memset(_src_, 0, 128);#define COPY_16B(_src_, _dst_) if (_dst_) memcpy(_dst_, _src_, 16);#endif// $PPstatic 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};voidswizzle_64b_8a(char *src, char *dst) { int i; for (i = 0;i < 64;i+=4) { dst[i+3] = src[i+0]; dst[i+2] = src[i+1]; dst[i+1] = src[i+2]; dst[i+0] = src[i+3]; }}voidswizzle_128b_16a(uint16 *src, uint16 *dst) { int i; for (i = 0;i < 64;i+=2) { dst[i+1] = src[i+0]; dst[i+0] = src[i+1]; }}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); // $PP if (decoder->iQuant_Scale_Type) decoder->iQuant_Scale = non_linear_quantizer_scale [quantizer_scale_code]; else decoder->iQuant_Scale = 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_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; // $PP if (decoder->bUseMAE) return dc_diff; else 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); // $PP if (decoder->bUseMAE) return dc_diff; else 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; // $PP if (decoder->bUseMAE) return dc_diff; else 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); // $PP if (decoder->bUseMAE) return dc_diff; else 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; \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -