📄 umc_mpeg2_dec_mb.cpp
字号:
/*////////////////////////////////////////////////////////////////////////////////// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright(c) 2003-2005 Intel Corporation. All Rights Reserved.//*/#include "umc_mpeg2_dec_base.h"#pragma warning(disable: 4244)using namespace UMC;static short zero_memory[64*6] = {0};static const int _offsetsFrame[6] = {0, 8, 128, 128+8, 256, 320};static const int _offsetsField[6] = {0, 8, 16, 24, 256, 320};Status MPEG2VideoDecoderBase::ReconstructIntraMB(int threadID, int num_blk, int dct_type){ IppVideoContext *video = &Video[threadID]; sMacroblock *pMacro = &Video[threadID].macroblock; sSlice *pSlice = &Video[threadID].slice; int blk; int curr_index = video->frame_buffer.curr_index; Ipp8u *cur_Y_data = video->frame_buffer.frame_p_c_n[curr_index].Y_comp_data; Ipp8u *cur_U_data = video->frame_buffer.frame_p_c_n[curr_index].U_comp_data; Ipp8u *cur_V_data = video->frame_buffer.frame_p_c_n[curr_index].V_comp_data; if (dct_type != 2) { int pitch_l = video->frame_buffer.Y_comp_pitch; int pitch_c = video->frame_buffer.U_comp_pitch; pMacro->offset_l = (pSlice->mb_row * pitch_l + pSlice->mb_col) << 4; pMacro->offset_c = (pSlice->mb_row * pitch_c + pSlice->mb_col) << 3; } short *pDC[3] = {&pSlice->dct_dc_y_past, &pSlice->dct_dc_cb_past, &pSlice->dct_dc_cr_past}; int *pitch = blkPitches[dct_type]; int *offsets = blkOffsets[dct_type]; Ipp8u* yuv[3] = { cur_Y_data + pMacro->offset_l, cur_U_data + pMacro->offset_c, cur_V_data + pMacro->offset_c }; for (blk = 0; blk < 6; blk++) { int chromaFlag, cc; chromaFlag = blk >> 2; cc = chromaFlag + (blk & chromaFlag); ippiDecodeIntra8x8IDCT_MPEG2_1u8u( &video->bs_curr_ptr, &video->bs_bit_offset, decodeIntraSpec, pSlice->cur_q_scale, chromaFlag, pDC[cc], yuv[cc] + offsets[blk], pitch[chromaFlag]); } return UMC_OK;}Status MPEG2VideoDecoderBase::ReconstuctInterMB(int threadID, int dct_type){ IppVideoContext* video = &Video[threadID]; int code; sSlice *pSlice = &Video[threadID].slice; int blk; int pitch = 32; const int *offsets = _offsetsFrame; DECODE_VLC(code, video->bs, vlcMBPattern); if(dct_type) { pitch = 64; offsets = _offsetsField; } for (blk = 0; blk < 6; blk++) { Ipp16s* pDst = video->block.idct + offsets[blk]; if (blk == 4) { pitch = 16; } if (code & (32 >> blk)) { int i, ret; ret = _mp2_ReconstructDCTBlock_MPEG2_32s( &video->bs_curr_ptr, &video->bs_bit_offset, decodeInterSpec->scanMatrix, pSlice->cur_q_scale, decodeInterSpec->quantMatrix, video->block.dq, &i); if(ret) return UMC_BAD_STREAM; DCT8x8INV(video->block.dq, pDst, pitch, i); } else { int i; for (i = 0; i < 8; i++) { ((Ipp32s*)pDst)[0] = 0; ((Ipp32s*)pDst)[1] = 0; ((Ipp32s*)pDst)[2] = 0; ((Ipp32s*)pDst)[3] = 0; pDst = (Ipp16s*)((Ipp8u*)pDst + pitch); } } } return UMC_OK;}Status MPEG2VideoDecoderBase::Macroblock_420_I_frame(int threadID){ unsigned int dct_type = 0; Ipp32s macroblock_type, code; IppVideoContext* video = &Video[threadID]; sMacroblock *pMacro = &Video[threadID].macroblock; sSlice *pSlice = &Video[threadID].slice; DECODE_VLC(macroblock_type, video->bs, vlcMBType[PictureHeader.picture_coding_type - 1]); if(!PictureHeader.frame_pred_frame_dct) GET_1BIT(video->bs,dct_type); if(macroblock_type & 0x10) { GET_TO9BITS(video->bs, 5, pSlice->quantizer_scale) if(pSlice->quantizer_scale < 1) return UMC_BAD_STREAM; pSlice->cur_q_scale = q_scale[PictureHeader.q_scale_type][pSlice->quantizer_scale]; } if(PictureHeader.concealment_motion_vectors) { pMacro->prediction_type = IPPVC_MC_FRAME; pMacro->motion_vector_count = 1; mv_decode(0, 0, threadID); pMacro->PMV[4] = pMacro->PMV[0]; pMacro->PMV[5] = pMacro->PMV[1]; GET_1BIT(video->bs,code); pSlice->macroblock_motion_forward_prev = 1; pSlice->macroblock_motion_backward_prev = 0; } return ReconstructIntraMB(threadID, 6, dct_type);}//Macroblock_420_IStatus MPEG2VideoDecoderBase::Macroblock_420_frame(int threadID){ Status umcRes = UMC_OK; IppVideoContext* video = &Video[threadID]; Ipp32s code; Ipp32s macroblock_type; unsigned int dct_type = 0; sSlice *pSlice = &Video[threadID].slice; sMacroblock *pMacro = &Video[threadID].macroblock; sPictureHeader *pPic = &PictureHeader; // skipped macroblocks if (pSlice->mb_address_increment > 1) { int pitch_l = video->frame_buffer.Y_comp_pitch; int pitch_c = video->frame_buffer.U_comp_pitch; int offset_l = (pSlice->mb_row_prev*pitch_l + pSlice->mb_col_prev) << 4; int offset_c = (pSlice->mb_row_prev*pitch_c + pSlice->mb_col_prev) << 3; int id_his_old, id_his_new; int prev_index = video->frame_buffer.prev_index; if (PictureHeader.picture_coding_type == P_FRAME) { RESET_PMV(pMacro->PMV) id_his_old = id_his_new = 1; } else { id_his_new = 0; pMacro->prediction_type = IPPVC_MC_FRAME; COPY_PMV(pMacro->vector, pMacro->PMV) pSlice->macroblock_motion_forward_prev = pMacro->macroblock_motion_forward; pSlice->macroblock_motion_backward_prev = pMacro->macroblock_motion_backward; if (!pMacro->macroblock_motion_backward) { if (!pMacro->PMV[0] && !pMacro->PMV[1]) { id_his_new = 2; } } else if (!pMacro->macroblock_motion_forward) { if (!pMacro->PMV[2] && !pMacro->PMV[3]) { id_his_new = 3; prev_index = video->frame_buffer.next_index; } } id_his_old = id_his_new; if (sequenceHeader.b_curr_number == 1) id_his_old = -1; // first B frame } if (id_his_new) { int curr_index = video->frame_buffer.curr_index; Ipp8u *ref_Y_data = video->frame_buffer.frame_p_c_n[prev_index].Y_comp_data; Ipp8u *ref_U_data = video->frame_buffer.frame_p_c_n[prev_index].U_comp_data; Ipp8u *ref_V_data = video->frame_buffer.frame_p_c_n[prev_index].V_comp_data; Ipp8u *cur_Y_data = video->frame_buffer.frame_p_c_n[curr_index].Y_comp_data; Ipp8u *cur_U_data = video->frame_buffer.frame_p_c_n[curr_index].U_comp_data; Ipp8u *cur_V_data = video->frame_buffer.frame_p_c_n[curr_index].V_comp_data; IppiSize roi = {16*(pSlice->mb_address_increment - 1), 16};#ifdef KEEP_HISTORY unsigned char *ref_history = video->frame_buffer.frame_p_c_n[video->frame_buffer.ind_his_ref].frame_history; unsigned char *curr_history = video->frame_buffer.frame_p_c_n[video->frame_buffer.ind_his_curr].frame_history; int offset_his = pSlice->mb_row_prev*sequenceHeader.mb_width + pSlice->mb_col_prev; int i; for (i = 0; i < pSlice->mb_address_increment - 1; i++) { if (ref_history[offset_his] != id_his_old) { ippiCopy16x16_8u_C1R(ref_Y_data + offset_l, pitch_l, cur_Y_data + offset_l, pitch_l); ippiCopy8x8_8u_C1R(ref_U_data + offset_c, pitch_c, cur_U_data + offset_c, pitch_c); ippiCopy8x8_8u_C1R(ref_V_data + offset_c, pitch_c, cur_V_data + offset_c, pitch_c); } curr_history[offset_his] = id_his_new; offset_l += 16; offset_c += 8; offset_his++; }#else ippiCopy_8u_C1R( ref_Y_data + offset_l, pitch_l, cur_Y_data + offset_l, pitch_l, roi); roi.height >>= 1; roi.width >>= 1; ippiCopy_8u_C1R( ref_U_data + offset_c, pitch_c, cur_U_data + offset_c, pitch_c, roi); ippiCopy_8u_C1R( ref_V_data + offset_c, pitch_c, cur_V_data + offset_c, pitch_c, roi);#endif } else { pMacro->offset_l = offset_l; pMacro->offset_c = offset_c; if (pMacro->macroblock_motion_forward && pMacro->macroblock_motion_backward) { mc_mp2_420b_frame_skip(zero_memory, threadID); } else { mc_mp2_420_frame_skip(threadID); } } }// skipped macroblocks DECODE_VLC(macroblock_type, video->bs, vlcMBType[PictureHeader.picture_coding_type - 1]); pMacro->macroblock_motion_forward = macroblock_type & 0x08; pMacro->macroblock_motion_backward= macroblock_type & 0x04; if(macroblock_type & 0x01) { if(!PictureHeader.frame_pred_frame_dct) GET_1BIT(video->bs,dct_type); if(macroblock_type & 0x10) { GET_TO9BITS(video->bs, 5, pSlice->quantizer_scale) if(pSlice->quantizer_scale < 1) return UMC_BAD_STREAM; pSlice->cur_q_scale = q_scale[PictureHeader.q_scale_type][pSlice->quantizer_scale]; } if(!PictureHeader.concealment_motion_vectors) { RESET_PMV(pMacro->PMV) } else { pMacro->prediction_type = IPPVC_MC_FRAME; pMacro->motion_vector_count = 1; mv_decode(0, 0, threadID); pMacro->PMV[4] = pMacro->PMV[0]; pMacro->PMV[5] = pMacro->PMV[1]; GET_1BIT(video->bs,code); pSlice->macroblock_motion_forward_prev = 1; pSlice->macroblock_motion_backward_prev = 0; } return ReconstructIntraMB(threadID, 6, dct_type); }//if(macroblock_intra) pSlice->dct_dc_y_past = pSlice->dct_dc_cb_past = pSlice->dct_dc_cr_past = PictureHeader.curr_reset_dc; pMacro->prediction_type = IPPVC_MC_FRAME; pMacro->motion_vector_count = 1; if(!PictureHeader.frame_pred_frame_dct) { code = 0; if (pMacro->macroblock_motion_forward || pMacro->macroblock_motion_backward) { GET_TO9BITS(video->bs, 2, code) } if(code == 1) { pMacro->prediction_type = IPPVC_MC_FIELD; pMacro->motion_vector_count = 2; } else if(code == 3) { pMacro->prediction_type = IPPVC_MC_DP; pMacro->motion_vector_count = 1; return Macroblock_420_DP(threadID, macroblock_type); } if(macroblock_type & 0x02) { GET_1BIT(video->bs,dct_type); } } if(macroblock_type & 0x10) { GET_TO9BITS(video->bs, 5, pSlice->quantizer_scale) if(pSlice->quantizer_scale < 1) return UMC_BAD_STREAM; pSlice->cur_q_scale = q_scale[PictureHeader.q_scale_type][pSlice->quantizer_scale]; } if(!pMacro->macroblock_motion_forward) { if (PictureHeader.picture_coding_type == P_FRAME) { RESET_PMV(pMacro->PMV) RESET_PMV(pMacro->vector) RESET_PMV(pMacro->vector_chroma) RESET_PMV(pMacro->vector_luma) } } else if(pMacro->prediction_type == IPPVC_MC_FRAME) { mv_decode(0, 0, threadID); pMacro->PMV[4] = pMacro->PMV[0]; pMacro->PMV[5] = pMacro->PMV[1]; } else { GET_1BIT(video->bs, pMacro->motion_vertical_field_select[0]); mv_decode(0, 0, threadID); GET_1BIT(video->bs, pMacro->motion_vertical_field_select[2]); mv_decode(1, 0, threadID); } if(pMacro->macroblock_motion_backward) { if(pMacro->prediction_type == IPPVC_MC_FRAME) { mv_decode(0, 1, threadID); pMacro->PMV[6] = pMacro->PMV[2]; pMacro->PMV[7] = pMacro->PMV[3]; } else { GET_1BIT(video->bs, pMacro->motion_vertical_field_select[1]); mv_decode(0, 1, threadID); GET_1BIT(video->bs, pMacro->motion_vertical_field_select[3]); mv_decode(1, 1, threadID); } } pSlice->macroblock_motion_forward_prev = pMacro->macroblock_motion_forward; pSlice->macroblock_motion_backward_prev = pMacro->macroblock_motion_backward; pMacro->offset_l = (pSlice->mb_row*video->frame_buffer.Y_comp_pitch + pSlice->mb_col) << 4; pMacro->offset_c = (pSlice->mb_row*video->frame_buffer.U_comp_pitch + pSlice->mb_col) << 3; int curr_index = video->frame_buffer.curr_index;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -