📄 umc_h264_dec_decode_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_h264_dec.h"#include "umc_h264_deblocking_tools.h"#include "umc_h264_dec_conversion.h"#include "umc_video_data.h"#include "umc_media_data_ex.h"#include "umc_color_space_converter.h"#include "vm_debug.h"#include "vm_sys_info.h"namespace UMC{enum{ ALIGN_VALUE = 16};H264VideoDecoder::H264DecoderFrame::H264DecoderFrame() : m_pPreviousFrame(0) , m_pFutureFrame(0) , m_cumulativeTR(0.0) , m_wasOutputted(false) , m_isDisplayable(false) , m_lockedForDisplay(false)// , m_FrameNum((unsigned)-1) , m_bIsIDRPic(false) , m_pParsedFrameData(0) , m_paddedParsedFrameDataSize(sDimensions(0,0)) , m_pRefPicList(0) , m_num_slice_start(0) , m_wasDisplayed(false) , m_dFrameTime(-1.0){ m_pParsedFrameDataNew = NULL; m_isShortTermRef[0] = m_isShortTermRef[1] = false; m_isLongTermRef[0] = m_isLongTermRef[1] = false; m_FrameNumWrap = m_FrameNum = -1; m_LongTermFrameIdx = -1; m_RefPicListResetCount[0] = m_RefPicListResetCount[1] = 0; m_PicNum[0] = m_PicNum[1] = -1; m_LongTermPicNum[0] = m_PicNum[1] = -1;}voidH264VideoDecoder::H264DecoderFrame::deallocateParsedFrameData(){ if (m_pParsedFrameData) { // Free the old buffer. ippsFree(m_pParsedFrameData); m_pParsedFrameData = 0; m_pRefPicList = 0; } // new structure(s) hold pointer if (m_pParsedFrameDataNew) { ippsFree(m_pParsedFrameDataNew); m_pParsedFrameDataNew = NULL; } m_paddedParsedFrameDataSize = sDimensions(0,0);} // deallocateParsedFrameDataStatusH264VideoDecoder::H264DecoderFrame::allocateParsedFrameData(const sDimensions &size){ Status ps = UMC_OK; sDimensions desiredPaddedSize; desiredPaddedSize.width = (size.width + 15) & ~15; desiredPaddedSize.height = (size.height + 15) & ~15; // If our buffer and internal pointers are already set up for this // image size, then there's nothing more to do. if (m_paddedParsedFrameDataSize != desiredPaddedSize) { // // Determine how much space we need // Ipp32u MB_Frame_Width = desiredPaddedSize.width >> 4; Ipp32u MB_Frame_Height = desiredPaddedSize.height >> 4;// Ipp32u Sub_Block_Width = MB_Frame_Width << 2;// Ipp32u Sub_Block_Height = MB_Frame_Height << 2; Ipp32u uMaxNumSlices = MAX_SLICE_NUM <0?MB_Frame_Width * MB_Frame_Height:MIN(MAX_SLICE_NUM,MB_Frame_Width * MB_Frame_Height); Ipp32u uRefPicListSize = uMaxNumSlices * sizeof(H264DecoderRefPicList); Ipp32u totalSize = Ipp32u( + uRefPicListSize + 7 + YUV_ALIGNMENT); deallocateParsedFrameData(); int len = MAX(1, totalSize); m_pParsedFrameData = ippsMalloc_8u(len); if (!m_pParsedFrameData) return UMC_FAILED_TO_ALLOCATE_BUFFER; ippsZero_8u(m_pParsedFrameData, len); // Reassign our internal pointers { m_paddedParsedFrameDataSize = desiredPaddedSize; Ipp8u *pAlignedParsedData; Ipp32u offset = 0; pAlignedParsedData = _ALIGN(m_pParsedFrameData, YUV_ALIGNMENT); // align to 8-byte boundary if (offset & 0x7) offset = (offset + 7) & ~7; m_pRefPicList = (H264DecoderRefPicList*)(pAlignedParsedData + offset); offset += uRefPicListSize; VM_ASSERT(offset <= totalSize); } // allocate new MB structure(s) { size_t nMBCount = (desiredPaddedSize.width>>4) * (desiredPaddedSize.height>>4); // allocate buffer int len = (sizeof(H264DecoderMacroblockMVs) + sizeof(H264DecoderMacroblockMVs) + sizeof(H264DecoderMacroblockRefIdxs) + sizeof(H264DecoderMacroblockRefIdxs) + sizeof(H264DecoderMacroblockGlobalInfo)) * nMBCount + 16 * 5; // allocate buffer m_pParsedFrameDataNew = ippsMalloc_8u(len); if (NULL == m_pParsedFrameDataNew) return UMC_FAILED_TO_ALLOCATE_BUFFER; ippsZero_8u(m_pParsedFrameDataNew, len); // set pointer(s) m_mbinfo.MV[0] = align_pointer<H264DecoderMacroblockMVs *> (m_pParsedFrameDataNew, ALIGN_VALUE); m_mbinfo.MV[1] = align_pointer<H264DecoderMacroblockMVs *> (m_mbinfo.MV[0]+ nMBCount, ALIGN_VALUE); m_mbinfo.RefIdxs[0] = align_pointer<H264DecoderMacroblockRefIdxs *> (m_mbinfo.MV[1] + nMBCount, ALIGN_VALUE); m_mbinfo.RefIdxs[1] = align_pointer<H264DecoderMacroblockRefIdxs *> (m_mbinfo.RefIdxs[0] + nMBCount, ALIGN_VALUE); m_mbinfo.mbs = align_pointer<H264DecoderMacroblockGlobalInfo *> (m_mbinfo.RefIdxs[1] + nMBCount, ALIGN_VALUE); } } return ps;} // H264VideoDecoder::H264DecoderFrame::allocateParsedFrameData(const sDimensions &size)H264VideoDecoder::H264DecoderFrame::~H264DecoderFrame(){ // Just to be safe. m_pPreviousFrame = 0; m_pFutureFrame = 0; deallocateParsedFrameData();}StatusH264VideoDecoder::H264DecoderFrame::allocate(const sDimensions &lumaSize){ Status ps = UMC_OK; // Clear our state, since allocate is called when we are about // to decode into this frame buffer. m_wasOutputted = false; m_isDisplayable = false; m_cumulativeTR = 0.0; m_dimensions = lumaSize; // Don't reset m_activeReference or m_lockedForDisplay as these are handled // depending on frame type or by the calling application, respectively ps = allocateParsedFrameData(lumaSize); if (ps == UMC_OK) ps = H264DecYUVWorkSpace::allocate(lumaSize); return ps;}//////////////////////////////////////////////////////////////////////////////// H264Decoder constructor//////////////////////////////////////////////////////////////////////////////H264VideoDecoder::H264VideoDecoder () :m_pBitStream(0) , m_initialTR(0.0) , m_bIsDecodingStarted(false)#ifdef USE_SEI , m_FrameProcessingStage(0)#endif , m_pCurrentFrame(0) , m_pDisplayFrame(0) , m_pParsedData(0) , m_pParsedDataNew(0) , m_parsedDataLength(0) , m_pMBIntraTypes(0) , m_field_index(0) , m_broken_buffer(0) , m_broken_buffer_start_mb(0) , m_broken_buffer_start_slice(0) , m_pCoeffBlocksWrite(0) , m_pCoeffBlocksRead(0) , m_bSeqParamSetRead(false) , m_bPicParamSetRead(false) , m_CurrentSeqParamSet(-1) , m_CurrentPicParamSet(-1) , m_bDPBSizeChanged(false) , m_dpbSize(1) , m_bSeqParamSetChanged(true) , m_getframe_calls(0) , m_WaitForDR(true) , m_SkipFlag(0) ,m_SkipCycle(1) ,m_ModSkipCycle(1) ,m_VideoDecodingSpeed(0) ,m_PreviousPicSkipped(false){ int i; m_local_delta_frame_time = 1.0/30; m_local_frame_time = 0; m_pConverter = NULL; for (i=0; i<MAX_NUM_SEQ_PARAM_SETS; i++) { m_SeqParamSet[i].poffset_for_ref_frame = NULL; } for (i=0; i<MAX_NUM_PIC_PARAM_SETS; i++) { m_PicParamSet[i].pFMOMap = NULL; } ulResized = 0; m_uiSwpBuffSize = SWAP_BUFFER_SIZE; m_nAllocatedLimitedSliceInfo = 0; m_pLimitedSliceInfo = NULL; m_pThreadedDeblockingTools = NULL; // set conversion threading tools vm_event_set_invalid(&m_hStartConversion); vm_event_set_invalid(&m_hStopConversion); vm_thread_set_invalid(&m_hConversionThread);}//////////////////////////////////////////////////////////////////////////////// Start_Sequence: This method should be called if there are significant// changes in the input format in the compressed bit stream.// This method must be called between construction// of the H264Decoder object and the first time a decompress// is done.//////////////////////////////////////////////////////////////////////////////Status H264VideoDecoder::Init(BaseCodecParams *pInit){ Status ps = UMC_OK; Ipp32u i; sDimensions dimensions(0,0); VideoDecoderParams *init = DynamicCast<VideoDecoderParams> (pInit); // check error(s) if (NULL == init) return UMC_NULL_PTR; // release object before initialization Close(); // allocate deblocking tools if ((1 != init->uiLimitThreads) && (1 < vm_sys_info_get_cpu_num())) m_pThreadedDeblockingTools = new H264ThreadedDeblockingTools(); // initialize deblocking tools if (m_pThreadedDeblockingTools) { ps = m_pThreadedDeblockingTools->Initialize(this); // it is not critical if (UMC_OK != ps) { delete m_pThreadedDeblockingTools; m_pThreadedDeblockingTools = NULL; } } // initialize conversion threading tools InitializeConversionThreading();#ifdef USE_SEI m_FrameProcessingStage = NORMAL_FRAME_PROCESSING;#endif m_bDataNotSwapped = false; if (0 == (init->lFlags & FLAG_VDEC_4BYTE_ACCESS)) { ps = InitSwapBuffer(); if (ps != UMC_OK) return ps; m_bDataNotSwapped = true; } m_pConverter = init->lpConverter; if (0 != init->info.framerate && -1 != init->info.framerate) { m_local_delta_frame_time = 1 / init->info.framerate; } m_bSeqParamSetRead = false; m_bPicParamSetRead = false; m_ReallySkipped = 0; m_AskedSkipped = 0; m_NeedToSkip = 0; m_SkipRepeat = 0; m_PermanentTurnOffDeblocking = 0; m_getframe_calls = 0; m_bIsDecodingStarted= false; m_field_index = 0; m_WaitForDR = true; m_bHasSEI = false; for (i=0; i<MAX_NUM_SEQ_PARAM_SETS; i++) { m_SeqParamSet[i].poffset_for_ref_frame = NULL; m_SeqParamSet[i].seq_parameter_set_id = MAX_NUM_SEQ_PARAM_SETS; // illegal id } for (i=0; i<MAX_NUM_PIC_PARAM_SETS; i++) { m_PicParamSet[i].pFMOMap = NULL; m_PicParamSet[i].pic_parameter_set_id = MAX_NUM_PIC_PARAM_SETS; // illegal id } for (; ps == UMC_OK; ) // Not really a loop; use break instead of goto on error {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -