📄 umc_h264_dec_decode_pic.cpp
字号:
for (Ipp32u i = 0; i < DEC_NUM_ALLOC_REF_FRAMES; i++) { H264DecoderFrame *pFrame = new H264DecoderFrame(); if (!pFrame) { ps = UMC_FAILED_TO_ALLOCATE_BUFFER; break; } //m_freeReferenceFrames.append(pFrame); m_H264DecoderFramesList.append(pFrame); } if (ps != UMC_OK) break; Status ps = UMC_OK; m_pBitStream = new H264Bitstream(); if (!m_pBitStream) ps = UMC_FAILED_TO_ALLOCATE_BUFFER; if (ps != UMC_OK) { delete m_pBitStream; m_pBitStream = NULL; break; } break; } m_lFlags = init->lFlags;/////////////////////////////////// for (;;) // Not really a loop. Use "break" instead of "goto" on error. { if (ps != UMC_OK) break; m_pDisplayFrame = 0; m_pCurrentFrame = 0; // Any previously displayed or decoded frame // will no longer be valid. // Reallocate all of our buffers to the exact size needed. // To reduce memory fragmentation, delete all the memory before // reallocating any. But, for performance reasons, try not to // delete anything that's already the correct size. Remember, // Start_Sequence might get called during a seek operation, so // performance is a concern. { ps = AllocateParsedData(dimensions, true); if (ps != UMC_OK) break; //pCurr = m_freeReferenceFrames.head(); /* H264DecoderFrame *pCurr = m_H264DecoderFramesList.head(); for (; pCurr; pCurr = pCurr->future()) { ps = pCurr->allocate(dimensions); if (ps != UMC_OK) break; }*/ if (ps != UMC_OK) break; //if (isBFrameBufferProbablyNeeded) //{ // ps = m_BFrame.allocate(dimensions); // if (ps != UMC_OK) // break; //} } break; } if(init->lpConvertInit) { switch(init->lpConvertInit->lFlags) { case FLAG_CCNV_NONE: case FLAG_CCNV_CONVERT: ulResized = 1; break; case FLAG_CCNV_RESIZE_2S: ulResized = 2; break; case FLAG_CCNV_RESIZE_4S: ulResized = 4; break; case FLAG_CCNV_RESIZE_8S: ulResized = 8; break; default: ulResized = 0; break; } // initialize convertion param(s) m_Convert.ConversionInit = *(init->lpConvertInit); m_Convert.ConversionInit.FormatSource = YUV420; // if second picture desired if (NULL != init->lpConvertInitPreview) { m_bTwoPictures = true; m_ConvertPreview.ConversionInit = *(init->lpConvertInitPreview); m_ConvertPreview.ConversionInit.FormatSource = YUV420; } else m_bTwoPictures = false; if(init->m_pData) { ps = GetFrame((MediaData *) init->m_pData, NULL);//ps; // we always use ColorSpaceConverter // create color convertion object// if (NULL == m_pConverter)// m_pConverter = new ColorSpaceConverter();// if (NULL == m_pConverter)// return UMC_NOT_INITIALIZED; //InitColorConverter(pDisplayFrame); } } else if(init->m_pData) { ps = GetFrame((MediaData *) init->m_pData, NULL);//ps; } if((UMC_NOT_ENOUGH_DATA == ps)) // && !(m_lFlags & FLAG_VDEC_REORDER)) ps = UMC_OK;// Ipp32s num=4;// ChangeVideoDecodingSpeed(num); return ps;}Status H264VideoDecoder::Close(){ // deallocate deblocking tools if (m_pThreadedDeblockingTools) delete m_pThreadedDeblockingTools; m_pThreadedDeblockingTools = NULL; // release conversion thrading tools ReleaseConversionThreading(); if(m_pBitStream) delete m_pBitStream; m_pBitStream = NULL; if (m_bDataNotSwapped) FreeSwapBuffer();// if (m_pConverter)// delete m_pConverter; m_pConverter = NULL; DeallocateParsedData(); // destroy limited slice info array if (m_pLimitedSliceInfo) ippsFree(m_pLimitedSliceInfo); m_nAllocatedLimitedSliceInfo = 0; m_pLimitedSliceInfo = NULL; // destroy threaded deblocking tools if (m_pThreadedDeblockingTools) delete m_pThreadedDeblockingTools; m_pThreadedDeblockingTools = NULL; Ipp32u i; for (i=0; i<MAX_NUM_SEQ_PARAM_SETS; i++) { if (m_SeqParamSet[i].poffset_for_ref_frame) { ippsFree(m_SeqParamSet[i].poffset_for_ref_frame); m_SeqParamSet[i].poffset_for_ref_frame = NULL; } } for (i=0; i<MAX_NUM_PIC_PARAM_SETS; i++) { if (m_PicParamSet[i].pFMOMap) { ippsFree(m_PicParamSet[i].pFMOMap); m_PicParamSet[i].pFMOMap = NULL; } }// m_freeReferenceFrames.destroy();// m_referenceFrames.destroy(); return UMC_OK;}//////////////////////////////////////////////////////////////////////////////// H264Decoder Destructor//////////////////////////////////////////////////////////////////////////////H264VideoDecoder::~H264VideoDecoder(void){ Close();}//////////////////////////////////////////////////////////////////////////////// UpdateRefPicList//// Management of active reference picture lists to be used for decoding the// slice whose header has just been read.////////////////////////////////////////////////////////////////////////////////Status H264VideoDecoder::UpdateRefPicList( H264SliceHeader SHdr, RefPicListReorderInfo *pReorderInfo_L0, RefPicListReorderInfo *pReorderInfo_L1, Ipp32u uSliceNum){ Status ps = UMC_OK; H264SeqParamSet *sps; H264PicParamSet *pps; Ipp32u uMaxFrameNum; Ipp32u uMaxPicNum; H264DecoderFrame *pFrm; H264DecoderFrame *pHead = m_H264DecoderFramesList.head(); //Ipp32u i; H264DecoderFrame **pRefPicList0; H264DecoderFrame **pRefPicList1; Ipp8s *pFields0; Ipp8s *pFields1; Ipp32u NumShortTermRefs, NumLongTermRefs; VM_ASSERT(m_pCurrentFrame); pRefPicList0 = m_pCurrentFrame->GetRefPicList(uSliceNum, 0)->m_RefPicList; pRefPicList1 = m_pCurrentFrame->GetRefPicList(uSliceNum, 1)->m_RefPicList; pFields0 = m_pCurrentFrame->GetRefPicList(uSliceNum, 0)->m_Prediction; pFields1 = m_pCurrentFrame->GetRefPicList(uSliceNum, 1)->m_Prediction; // Spec reference: 8.2.4, "Decoding process for reference picture lists // construction" // get pointers to the picture and sequence parameter sets currently in use pps = &m_PicParamSet[SHdr.pic_parameter_set_id]; sps = &m_SeqParamSet[pps->seq_parameter_set_id]; uMaxFrameNum = (1<<sps->log2_max_frame_num); uMaxPicNum = (SHdr.field_pic_flag == 0) ? uMaxFrameNum : uMaxFrameNum<<1;/* if(m_field_index && m_pCurrentFrame->m_PictureStructureForRef<FRM_STRUCTURE) { if (m_NALRefIDC[0]) { m_pCurrentFrame->SetisShortTermRef(0); } // If B slice, init scaling factors array }*/ for (pFrm = pHead; pFrm; pFrm = pFrm->future()) { // update FrameNumWrap and PicNum if frame number wrap occurred, // for short-term frames // TBD: modify for fields pFrm->UpdateFrameNumWrap((Ipp32s)SHdr.frame_num, uMaxFrameNum, m_pCurrentFrame->m_PictureStructureForRef+ m_pCurrentFrame->m_bottom_field_flag[m_field_index]); // For long-term references, update LongTermPicNum. Note this // could be done when LongTermFrameIdx is set, but this would // only work for frames, not fields. // TBD: modify for fields pFrm->UpdateLongTermPicNum(m_pCurrentFrame->m_PictureStructureForRef+m_pCurrentFrame->m_bottom_field_flag[m_field_index]); } if ((SHdr.slice_type != INTRASLICE) && (SHdr.slice_type != S_INTRASLICE)) { // Detect and report no available reference frames m_H264DecoderFramesList.countActiveRefs(NumShortTermRefs, NumLongTermRefs); if ((NumShortTermRefs + NumLongTermRefs) == 0) { VM_ASSERT(0); ps = UMC_BAD_STREAM; } if (ps == UMC_OK) { // Initialize the reference picture lists // Note the slice header get function always fills num_ref_idx_lx_active // fields with a valid value; either the override from the slice // header in the bitstream or the values from the pic param set when // there is no override. if ((SHdr.slice_type == PREDSLICE) || (SHdr.slice_type == S_PREDSLICE)) InitPSliceRefPicList(SHdr.field_pic_flag != 0, SHdr.num_ref_idx_l0_active, pRefPicList0); else { //pRefPicList1 = m_pCurrentFrame->GetRefPicList(uSliceNum, 1)->m_RefPicList; InitBSliceRefPicLists(SHdr.field_pic_flag != 0, SHdr.num_ref_idx_l0_active, SHdr.num_ref_idx_l1_active, pRefPicList0, pRefPicList1); } // Reorder the reference picture lists Ipp8u num_ST_Ref0 = 0, num_ST_Ref1, num_LT_Ref = 0; if (m_pCurrentFrame->m_PictureStructureForRef<FRM_STRUCTURE) { AdjustRefPicListForFields(pRefPicList0,pFields0); num_ST_Ref0 = m_NumShortEntriesInList; num_LT_Ref = m_NumLongEntriesInList; } if (BPREDSLICE == SHdr.slice_type) { if (m_pCurrentFrame->m_PictureStructureForRef<FRM_STRUCTURE) { AdjustRefPicListForFields(pRefPicList1,pFields1); num_ST_Ref1 = m_NumShortEntriesInList; if ((m_NumFramesInL0List == 0 || m_NumFramesInL1List == 0) && ((num_ST_Ref0+num_ST_Ref1+num_LT_Ref) > 1))//handling special case for fields { pRefPicList1[0] = pRefPicList0[1]; pRefPicList1[1] = pRefPicList0[0]; pFields1[0] = pFields0[1]; pFields1[1] = pFields0[0]; } } } if (pReorderInfo_L0->num_entries > 0) ReOrderRefPicList(SHdr.field_pic_flag != 0,pRefPicList0, pFields0,pReorderInfo_L0, uMaxPicNum, SHdr.num_ref_idx_l0_active); if (BPREDSLICE == SHdr.slice_type) { if (pReorderInfo_L1->num_entries > 0) ReOrderRefPicList(SHdr.field_pic_flag != 0,pRefPicList1, pFields1,pReorderInfo_L1, uMaxPicNum, SHdr.num_ref_idx_l1_active); } // If B slice, init scaling factors array if ((BPREDSLICE == SHdr.slice_type) && (pRefPicList1[0] != NULL)) InitDistScaleFactor(SHdr.num_ref_idx_l0_active, pRefPicList0, pRefPicList1, pFields0,pFields1); } } return ps;} // UpdateRefPicList//////////////////////////////////////////////////////////////////////////////// InitPSliceRefPicList//////////////////////////////////////////////////////////////////////////////void H264VideoDecoder::InitPSliceRefPicList(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -