📄 umc_mpeg2_dec_pic.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_defs.h"#include "umc_mpeg2_dec_base.h"#include "umc_video_data.h"#include "umc_structures.h"#pragma warning(disable: 4244)using namespace UMC;#define ALIGN_VALUE 64// can decode all headers, except of slices// bitstream should point to next after header byteStatus MPEG2VideoDecoderBase::DecodeHeader(int startcode, int threadID){ IppVideoContext* video = &Video[threadID]; unsigned int code; switch(startcode) { case SEQUENCE_HEADER_CODE: return (DecodeSequenceHeader(threadID)); case SEQUENCE_END_CODE: return (UMC_OK); case GROUP_START_CODE: GET_BITS_LONG(video->bs, 27, code) sequenceHeader.broken_link = code & 1; sequenceHeader.closed_gop = code & 2; sequenceHeader.gop_picture = (code>>2) & 0x3f; sequenceHeader.gop_second = ((code>>8) & 0x3f) + ((code>>15) & 0x3f)*60 + ((code>>21) & 0x1f)*3600; sequenceHeader.stream_time_temporal_reference = -2; // new count return (UMC_OK); // ignore for a while case EXTENSION_START_CODE: SHOW_TO9BITS(video->bs, 4, code) //extensions switch(code) { case SEQUENCE_EXTENSION_ID: { GET_BITS32(video->bs, code) sequenceHeader.chroma_format = 1 << ((code >> 17) & ((1 << 2) - 1)); sequenceHeader.progressive_sequence = (code >> 19) & 1; sequenceHeader.extension_start_code_ID = SEQUENCE_EXTENSION_ID; GET_BITS(video->bs, 16, code) sequenceHeader.frame_rate_extension_d = code & 31; sequenceHeader.frame_rate_extension_n = (code >> 5) & 3; } break; case SEQUENCE_DISPLAY_EXTENSION_ID: sequence_display_extension(); break; case QUANT_MATRIX_EXTENSION_ID: quant_matrix_extension(); break; case COPYRIGHT_EXTENSION_ID: copyright_extension(); break; case PICTURE_DISPLAY_EXTENSION_ID: picture_display_extension(); break; case SEQUENCE_SCALABLE_EXTENSION_ID: sequence_scalable_extension(); break; case PICTURE_CODING_EXTENSION_ID: // can move after picture header (if mpeg2) //picture_coding_extension(); { int intra_dc_precision = 0; GET_BITS32(video->bs,code) VM_ASSERT((code>>28) == PICTURE_CODING_EXTENSION_ID); PictureHeader.repeat_first_field = (code >> 1) & 1; int alternate_scan = (code >> 2) & 1; PictureHeader.intra_vlc_format = (code >> 3) & 1; PictureHeader.q_scale_type = (code >> 4) & 1; PictureHeader.concealment_motion_vectors = (code >> 5) & 1; PictureHeader.frame_pred_frame_dct = (code >> 6) & 1; PictureHeader.top_field_first = (code >> 7) & 1; PictureHeader.picture_structure = (code >> 8) & 3; intra_dc_precision = (code >> 10) & 3; PictureHeader.f_code[3] = (code >> 12) & 15; PictureHeader.f_code[2] = (code >> 16) & 15; PictureHeader.f_code[1] = (code >> 20) & 15; PictureHeader.f_code[0] = (code >> 24) & 15; GET_1BIT(video->bs, PictureHeader.progressive_frame) GET_1BIT(video->bs, code) PictureHeader.r_size[0] = PictureHeader.f_code[0] - 1; PictureHeader.r_size[1] = PictureHeader.f_code[1] - 1; PictureHeader.r_size[2] = PictureHeader.f_code[2] - 1; PictureHeader.r_size[3] = PictureHeader.f_code[3] - 1; PictureHeader.curr_intra_dc_multi = intra_dc_multi[intra_dc_precision]; PictureHeader.curr_reset_dc = reset_dc[intra_dc_precision]; int i, f; for(i = 0; i < 4; i++) { f = 1 << PictureHeader.r_size[i]; PictureHeader.low_in_range[i] = -(f * 16); PictureHeader.high_in_range[i] = (f * 16) - 1; PictureHeader.range[i] = f * 32; } if(code) { GET_BITS_LONG(video->bs, 20, code) } if(PictureHeader.picture_structure == FRAME_PICTURE) PictureHeader.field_buffer_index = 0; // avoid field parity loss in resync ippiDecodeInterInit_MPEG2(NULL, alternate_scan | IPPVC_LEAVE_QUANT_UNCHANGED, decodeInterSpec); decodeIntraSpec->intraVLCFormat = PictureHeader.intra_vlc_format; decodeIntraSpec->intraShiftDC = PictureHeader.curr_intra_dc_multi; ippiDecodeIntraInit_MPEG2(NULL, alternate_scan | IPPVC_LEAVE_QUANT_UNCHANGED, decodeIntraSpec->intraVLCFormat, decodeIntraSpec->intraShiftDC, decodeIntraSpec); } break; case PICTURE_SPARTIAL_SCALABLE_EXTENSION_ID: picture_spartial_scalable_extension(); break; case PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID: picture_temporal_scalable_extension(); break; default: break; } return (UMC_OK); case USER_DATA_START_CODE: { int ATSC_identifier; SHOW_BITS_32(video->bs, ATSC_identifier) //Closed caption data if(m_pCCData) { ReadCCData(); } else { //other user info, skip it SHOW_BITS_LONG(video->bs,24,code) while(code != 0x000001) { GET_TO9BITS(video->bs, 8, code) SHOW_BITS_LONG(video->bs,24,code) } } } return (UMC_OK); case PICTURE_START_CODE: return (DecodePictureHeader()); default: return (UMC_BAD_STREAM); // unexpected }}Status MPEG2VideoDecoderBase::DecodeSequenceHeader(int threadID){ unsigned int load_non_intra_quantizer_matrix; unsigned int load_intra_quantizer_matrix; unsigned int constrained_parameters_flag; int i; unsigned int code; IppVideoContext* video = &Video[threadID]; Ipp8u iqm[64]; Ipp8u niqm[64]; if(GET_REMAINED_BYTES(video->bs) < 8) { // return header back UNGET_BITS_32(video->bs) return (UMC_NOT_ENOUGH_DATA); } GET_BITS32(video->bs, code) sequenceHeader.frame_rate_code = code & ((1 << 4) - 1); sequenceHeader.vertical_size = (code >> 8) & ((1 << 12) - 1); sequenceHeader.horizontal_size = (code >> 20) & ((1 << 12) - 1); code = (code >> 4) & ((1 << 4) - 1); if(code == 1) { sequenceHeader.aspect_ratio_w = 1; sequenceHeader.aspect_ratio_h = 1; } else if(code == 2) { sequenceHeader.aspect_ratio_w = 4; sequenceHeader.aspect_ratio_h = 3; } else if(code == 3) { sequenceHeader.aspect_ratio_w = 16; sequenceHeader.aspect_ratio_h = 9; } else if(code == 4) { sequenceHeader.aspect_ratio_w = 2.21; sequenceHeader.aspect_ratio_h = 1; } else { sequenceHeader.aspect_ratio_w = 1; sequenceHeader.aspect_ratio_h = 1; } m_ClipInfo.aspect_ratio_width = sequenceHeader.aspect_ratio_w; m_ClipInfo.aspect_ratio_height = sequenceHeader.aspect_ratio_h; m_ClipInfo.clip_info.width = sequenceHeader.horizontal_size; m_ClipInfo.clip_info.height = sequenceHeader.vertical_size; GET_BITS32(video->bs, code) constrained_parameters_flag = (code >> 2) & 1; load_intra_quantizer_matrix = (code >> 1) & 1; load_non_intra_quantizer_matrix = code & 1; // could be changed if(load_intra_quantizer_matrix) { GET_BITS(video->bs, 7, iqm[0]) iqm[0] |= (load_non_intra_quantizer_matrix << 7); for(i=1; i<64; i++) { GET_BITS(video->bs, 8, iqm[i]) } GET_1BIT(video->bs, load_non_intra_quantizer_matrix); } if(load_non_intra_quantizer_matrix) { for(i=0; i<64; i++) { GET_BITS(video->bs, 8, niqm[i]) } } VideoStreamType newtype = MPEG1_VIDEO; if(!constrained_parameters_flag) { FIND_START_CODE(video->bs,code) if(code == EXTENSION_START_CODE) { SKIP_BITS_32(video->bs); SHOW_TO9BITS(video->bs, 4, code) if(code == SEQUENCE_EXTENSION_ID) { newtype = MPEG2_VIDEO; DecodeHeader(EXTENSION_START_CODE, threadID); } } } if(sequenceHeader.stream_type == UNDEF_VIDEO) sequenceHeader.stream_type = newtype; else if(sequenceHeader.stream_type != newtype) return (UMC_BAD_STREAM); if(sequenceHeader.stream_type == MPEG1_VIDEO) { sequenceHeader.progressive_sequence = 1; } m_ClipInfo.stream_type = sequenceHeader.stream_type; FIND_START_CODE(video->bs, code); while(code == EXTENSION_START_CODE || code == USER_DATA_START_CODE) { SKIP_BITS_32(video->bs); DecodeHeader(code,threadID); FIND_START_CODE(video->bs, code); } // now compute params sequenceHeader.mb_width = (sequenceHeader.horizontal_size + 15) >> 4; sequenceHeader.mb_height= (sequenceHeader.vertical_size + 15) >> 4; if(!sequenceHeader.progressive_sequence) { sequenceHeader.mb_height = (sequenceHeader.mb_height + 1) & ~1; } m_ClipInfo.clip_info.width = sequenceHeader.horizontal_size; m_ClipInfo.clip_info.height = sequenceHeader.vertical_size; m_ClipInfo.aspect_ratio_width = sequenceHeader.aspect_ratio_w; m_ClipInfo.aspect_ratio_height = sequenceHeader.aspect_ratio_h; if(sequenceHeader.stream_type == MPEG1_VIDEO) { //m_lFlags &=~FLAG_VDEC_UVMERGED; m_Convert.ConversionInit.FormatSource = YUV420; sequenceHeader.chroma_format = CHROMA_420; } int flag_mpeg1 = (sequenceHeader.stream_type == MPEG1_VIDEO) ? IPPVC_MPEG1_STREAM : 0; ippiDecodeIntraInit_MPEG2(NULL, flag_mpeg1, PictureHeader.intra_vlc_format, PictureHeader.curr_intra_dc_multi, decodeIntraSpec); ippiDecodeInterInit_MPEG2(NULL, flag_mpeg1, decodeInterSpec); if(load_intra_quantizer_matrix) { ippiDecodeIntraInit_MPEG2(iqm, flag_mpeg1, PictureHeader.intra_vlc_format, PictureHeader.curr_intra_dc_multi, decodeIntraSpec); } if(load_non_intra_quantizer_matrix) { ippiDecodeInterInit_MPEG2(niqm, flag_mpeg1, decodeInterSpec); } switch(sequenceHeader.frame_rate_code) { case 0: sequenceHeader.delta_frame_time = 1000./30000.; break; case 1: sequenceHeader.delta_frame_time = 1001./24000.; break; case 2: sequenceHeader.delta_frame_time = 1000./24000.; break; case 3: sequenceHeader.delta_frame_time = 1000./25000.; break; case 4: sequenceHeader.delta_frame_time = 1001./30000.; break; case 5: sequenceHeader.delta_frame_time = 1000./30000.; break; case 6: sequenceHeader.delta_frame_time = 1000./50000.; break; case 7: sequenceHeader.delta_frame_time = 1001./60000.; break; case 8: sequenceHeader.delta_frame_time = 1000./60000.; break; default: sequenceHeader.delta_frame_time = 1000./30000.; //VM_ASSERT(0); break; } if(sequenceHeader.stream_type == MPEG1_VIDEO) return (UMC_OK); sequenceHeader.delta_frame_time *= (double)(sequenceHeader.frame_rate_extension_d + 1) / (sequenceHeader.frame_rate_extension_n + 1); return (UMC_OK);}void MPEG2VideoDecoderBase::sequence_display_extension(){ unsigned int code; IppVideoContext* video = &Video[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -