📄 umc_h264_dec_conversion.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_dec_conversion.h"#include "umc_video_data.h"#include "vm_thread.h"#include "vm_event.h"namespace UMC{void H264VideoDecoder::InitializeConversionThreading(void){ vm_status res; bool bErr = false; // set quit flag m_bQuit = false; // create objects res = vm_event_init(&m_hStartConversion, 0, 0); if (VM_OK != res) bErr = true; res = vm_event_init(&m_hStopConversion, 0, 0); if (VM_OK != res) bErr = true; { int res; res = vm_thread_create(&m_hConversionThread, ConvertFrameAsyncSecondThread, this); if (0 == res) bErr = true; } // deinitialize when error occurs. Its not critical. if (bErr) ReleaseConversionThreading();} // void H264VideoDecoder::InitializeConversionThreading(void)void H264VideoDecoder::ReleaseConversionThreading(void){ if (vm_thread_is_valid(&m_hConversionThread)) { m_bQuit = true; vm_event_signal(&m_hStartConversion); vm_thread_wait(&m_hConversionThread); vm_thread_close(&m_hConversionThread); } // close handles if (vm_event_is_valid(&m_hStartConversion)) vm_event_destroy(&m_hStartConversion); if (vm_event_is_valid(&m_hStopConversion)) vm_event_destroy(&m_hStopConversion); // reset handles vm_thread_set_invalid(&m_hConversionThread); vm_event_set_invalid(&m_hStartConversion); vm_event_set_invalid(&m_hStopConversion); m_bQuit = false;} // void H264VideoDecoder::ReleaseConversionThreading(void)void H264VideoDecoder::InitColorConverter(H264DecoderFrame *source, Ipp8u force_field){ // set correct size in color converter Ipp32s crop_left = source->m_crop_left; Ipp32s crop_right = source->m_crop_right; Ipp32s crop_top = source->m_crop_top; Ipp32s crop_bottom = source->m_crop_bottom; Ipp32s width = source->lumaSize().width; Ipp32s height= source->lumaSize().height; width-=2*(crop_left+crop_right);//-+crop_flag; height-=2*(crop_top+crop_bottom);//+crop_flag; if ((0 == m_Convert.ConversionInit.SizeSource.width) || ((Ipp32u) (m_Convert.ConversionInit.SizeSource.width) != source->lumaSize().width)) { m_Convert.ConversionInit.SizeSource.width = source->lumaSize().width; } if ((0 == m_Convert.ConversionInit.SizeSource.height) || ((Ipp32u) (m_Convert.ConversionInit.SizeSource.height) != (source->lumaSize().height >> force_field))) { m_Convert.ConversionInit.SizeSource.height = source->lumaSize().height>>force_field; } m_Convert.ConversionInit.SrcCropRect.left = (short) (2 * crop_left); m_Convert.ConversionInit.SrcCropRect.top = (short) (2 * crop_top); m_Convert.ConversionInit.SrcCropRect.right = (short) (2*crop_left+width); m_Convert.ConversionInit.SrcCropRect.bottom = (short) ((2*crop_top+height) >> force_field); if(ulResized) { m_Convert.ConversionInit.SizeDest.width = width / ulResized; m_Convert.ConversionInit.SizeDest.height = height / ulResized; m_Convert.ConversionInit.SrcCropRect.left = (short) (m_Convert.ConversionInit.SrcCropRect.left / ulResized); m_Convert.ConversionInit.SrcCropRect.top = (short) (m_Convert.ConversionInit.SrcCropRect.top / ulResized); m_Convert.ConversionInit.SrcCropRect.right = (short) (m_Convert.ConversionInit.SrcCropRect.right / ulResized); m_Convert.ConversionInit.SrcCropRect.bottom = (short) (m_Convert.ConversionInit.SrcCropRect.bottom / ulResized); } if (NULL != m_pConverter) m_pConverter->Init(m_Convert.ConversionInit); if (m_bTwoPictures) { m_ConvertPreview.ConversionInit.SizeSource.width = source->lumaSize().width; m_ConvertPreview.ConversionInit.SizeSource.height = source->lumaSize().height>>force_field; if (NULL != m_pConverter) m_pConverter->Init(m_ConvertPreview.ConversionInit); }} // void H264VideoDecoder::InitColorConverter(H264DecoderFrame *source, Ipp8u force_field)H264VideoDecoder::H264DecoderFrame *H264VideoDecoder::GetFrameToDisplay(Ipp32u nStage){ if (BEFORE_DECODING == nStage) { H264DecoderFrame *pTmp; // there are no frames to show if ((1 >= m_dpbSize) || (m_H264DecoderFramesList.countNumDisplayable() < (m_dpbSize - 1))) return NULL; // sometimes current frame may be shown after decoding pTmp = m_H264DecoderFramesList.findOldestDisplayable(); if ((m_pCurrentFrame->RefPicListResetCount(0, 3) > pTmp->RefPicListResetCount(0, 3)) || ((m_pCurrentFrame->PicOrderCnt(0, 3) < pTmp->PicOrderCnt(0, 3)) && (m_pCurrentFrame->RefPicListResetCount(0, 3) == pTmp->RefPicListResetCount(0, 3)))) return NULL; return pTmp; } else { // show oldest frame if ((m_H264DecoderFramesList.countNumDisplayable() >= m_dpbSize) || (ABSENT_DECODING == nStage)) return m_H264DecoderFramesList.findOldestDisplayable(); // there are no frames to show else return NULL; }} // H264DecoderFrame *GetFrameToDisplay(bool bAfterDecodingCall)Status H264VideoDecoder::OutputFrame(MediaData *dst, Ipp32u nStage){ Status ps = UMC_OK;#ifdef USE_SEI if (PREPARE_DECODING == nStage) { Ipp8u save_field = 0; if(COMBINE_FIELDS == m_FrameProcessingStage) { save_field = (m_pDisplayFrame->m_PictureStructureFromSEI == 6) || (m_pDisplayFrame->m_PictureStructureFromSEI == 4); if (dst) OutputHalfFrame(m_pDisplayFrame,dst,save_field); m_pDisplayFrame->m_RepeatCount--;//may not be neede but decrease anyway } } else if ((AFTER_DECODING == nStage) || (ABSENT_DECODING == nStage)) { // do frame conversion Ipp32s NumDisplayable = m_H264DecoderFramesList.countNumDisplayable(); if ((NULL == m_pDisplayFrame) || (REPEAT_LAST_FRAME != m_FrameProcessingStage)) { H264DecoderFrame *TempDisplay; if (NumDisplayable >= m_dpbSize || (ABSENT_DECODING == nStage)) TempDisplay = m_H264DecoderFramesList.findOldestDisplayable(); else TempDisplay = NULL; if ((ABSENT_DECODING != nStage) || (TempDisplay != NULL) || (m_FrameProcessingStage != COMBINE_FIELDS)) { m_pDisplayFrame = TempDisplay; } } if (m_pDisplayFrame && dst != NULL) { const Ipp8u RepCountToProcStage[]= { NORMAL_FRAME_PROCESSING, NORMAL_FRAME_PROCESSING, COMBINE_FIELDS, REPEAT_LAST_FRAME, REPEAT_LAST_FRAME, REPEAT_LAST_FRAME, }; if (m_FrameProcessingStage==COMBINE_FIELDS) { ps = OutputHalfFrame(m_pDisplayFrame,dst,!save_field); m_pDisplayFrame->m_RepeatCount--; } else { if (m_pDisplayFrame->m_PictureStructureFromSEI==4 || m_pDisplayFrame->m_PictureStructureFromSEI==6) ps = OutputReverseFrame(m_pDisplayFrame,dst); else ps = ConvertFrame(dst); m_pDisplayFrame->m_RepeatCount-=2; } if (m_pDisplayFrame->m_RepeatCount<=1) m_pDisplayFrame->setWasOutputted();//set wasOutputed even if one field left m_FrameProcessingStage = RepCountToProcStage[m_pDisplayFrame->m_RepeatCount+1]; } else ps = UMC_END_OF_STREAM; }#else // !USE_SEI // we suppose to m_pDisplayFrame will be the same // before and after current frame decoding switch (nStage) { case PREPARE_DECODING: m_pDisplayFrame = NULL; break; case BEFORE_DECODING: m_pDisplayFrame = GetFrameToDisplay(nStage); // run conversion asynchronously if (vm_thread_is_valid(&m_hConversionThread)) ConvertFrameAsync(dst, nStage); break; case AFTER_DECODING: case ABSENT_DECODING: { if (m_pDisplayFrame) { H264DecoderFrame *pTmp = GetFrameToDisplay(nStage); VM_ASSERT((m_pDisplayFrame == pTmp) || (NULL == m_pDisplayFrame) || (NULL == pTmp)); if (dst) { // sometimes we have converted unnecessary frame if (vm_thread_is_valid(&m_hConversionThread)) ps = ConvertFrameAsync(dst, nStage); m_pDisplayFrame = pTmp; if ((0 == vm_thread_is_valid(&m_hConversionThread)) && (m_pDisplayFrame)) ps = ConvertFrame(dst); } } else { m_pDisplayFrame = GetFrameToDisplay(nStage); if (m_pDisplayFrame && dst) ps = ConvertFrame(dst); } if (m_pDisplayFrame && dst) { m_pDisplayFrame->setWasOutputted(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -