📄 umc_h261_video_decoder.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) 2005 Intel Corporation. All Rights Reserved.////*/#include <string.h>#include "vm_debug.h"#include "umc_h261_video_decoder.h"#include "umc_video_data.h"#include "h261decoder.h"namespace UMC{Status H261VideoDecoder::Init(BaseCodecParams *lpInit){ Status status = UMC_OK; VideoDecoderParams *pParam = DynamicCast<VideoDecoderParams> (lpInit); if (NULL == pParam) return UMC_NULL_PTR; m_dec_time_fr = 0.0; m_dec_time_base = m_dec_time_prev = -1.0; m_dec_time_frinc = (pParam->info.framerate > 0) ? 1.0 / pParam->info.framerate : 0.0; m_buffered_frame = false; m_Param = *pParam; m_IsInit = false; memset(&m_decInfo, 0, sizeof(m_decInfo)); if (NULL != pParam->m_pData) { if (pParam->m_pData->GetTime() >= 0.0) m_dec_time_base = pParam->m_pData->GetTime(); status = InsideInit(&m_Param); if (UMC_OK == status) { if ((m_Param.lFlags & FLAG_VDEC_REORDER) && ((m_decInfo.buflen - ((size_t)m_decInfo.bufptr - (size_t)m_decInfo.buffer)) > 4)) { m_buffered_frame = true; status = GetFrame(pParam->m_pData, NULL); } if (UMC_NOT_ENOUGH_DATA == status) status = UMC_OK; } pParam->m_pData->MoveDataPointer(static_cast<vm_var32>((size_t)m_decInfo.bufptr - (size_t)m_decInfo.buffer)); } if (UMC_OK == status) { m_pConverter = pParam->lpConverter; // set VOP size if it is unknown in splitter if (pParam->info.clip_info.width == 0 || pParam->info.clip_info.height == 0) { if (m_decInfo.picture_width == 0 && m_decInfo.picture_height == 0) return UMC_BAD_STREAM; else { pParam->info.clip_info.width = m_Param.info.clip_info.width = m_decInfo.picture_width; pParam->info.clip_info.height = m_Param.info.clip_info.height = m_decInfo.picture_height; } } if (pParam->lpConvertInit) { m_Convert.ConversionInit = *(pParam->lpConvertInit); m_Convert.ConversionInit.FormatSource = YV12; m_Convert.ConversionInit.FormatDest = (*pParam).cformat; m_Convert.ConversionInit.SizeSource.width = pParam->info.clip_info.width; m_Convert.ConversionInit.SizeSource.height = pParam->info.clip_info.height; if (NULL != m_pConverter && (status = m_pConverter->Init(m_Convert.ConversionInit)) != UMC_OK) return status; } } return status;}Status H261VideoDecoder::InsideInit(VideoDecoderParams *pParam){ Close(); m_decInfo.buflen = pParam->m_pData->GetDataSize(); m_decInfo.buffer = reinterpret_cast<unsigned char *> (pParam->m_pData->GetDataPointer()); if (initDecoder(&m_decInfo) == 0) { vm_debug_trace(4,__VM_STRING("Error: No memory to allocate internal buffers\n")); return UMC_ALLOC; } if (pParam->info.clip_info.width != 0 && pParam->info.clip_info.height != 0) { if (pParam->info.clip_info.width != m_decInfo.picture_width || pParam->info.clip_info.height != m_decInfo.picture_height) return UMC_BAD_STREAM; } m_IsInit = true; return UMC_OK;}Status H261VideoDecoder::GetFrame(MediaData* in, MediaData* out){ Status status = UMC_OK; double pts; if (in) { m_decInfo.bufptr = m_decInfo.buffer = (Ipp8u*)in->GetDataPointer(); m_decInfo.buflen = in->GetDataSize(); // find bit-offset of start code (it can be not byte-aligned) for (m_decInfo.bitoff = 0; m_decInfo.bitoff < 8; m_decInfo.bitoff ++) { int sc = (m_decInfo.bufptr[0] << (m_decInfo.bitoff + 24)) + (m_decInfo.bufptr[1] << (m_decInfo.bitoff + 16)) + (m_decInfo.bufptr[2] << (m_decInfo.bitoff + 8)) + (m_decInfo.bufptr[3] << (m_decInfo.bitoff)); if ((sc & 0xfffff000) == 0x00010000) break; } if (m_decInfo.bitoff >= 8) return UMC_BAD_STREAM; } if (!m_IsInit) { if (in == NULL) return UMC_NULL_PTR; m_Param.m_pData = in; status = InsideInit(&m_Param); if (status != UMC_OK) { in->MoveDataPointer(in->GetDataSize() - m_decInfo.buflen); return UMC_FAILED_TO_INITIALIZE; } } for (;;) { if (in == NULL) { // show last frame (it can be only if (m_Param.lFlags & FLAG_VDEC_REORDER)) if (!m_buffered_frame) return UMC_END_OF_STREAM; m_buffered_frame = false; _SWAP(m_decInfo.curPic[0], m_decInfo.refPic[0]); _SWAP(m_decInfo.curPic[1], m_decInfo.refPic[1]); _SWAP(m_decInfo.curPic[2], m_decInfo.refPic[2]); } else { if (getPictureHeader(&m_decInfo) != 0) { status = UMC_BAD_STREAM; break; } if (getPicture(&m_decInfo) != 0) { status = UMC_BAD_STREAM; } } if (out) { VideoData* pOutVideoData = DynamicCast<VideoData>(out); // set frame type pOutVideoData->SetFrameType(m_decInfo.picType == 0 ? I_PICTURE : P_PICTURE); // set pointers m_Convert.lpSource0 = m_decInfo.refPic[0]; m_Convert.lpSource2 = m_decInfo.refPic[1]; m_Convert.lpSource1 = m_decInfo.refPic[2]; m_Convert.PitchSource0 = m_decInfo.picture_width; m_Convert.PitchSource2 = m_decInfo.picture_width >> 1; m_Convert.PitchSource1 = m_decInfo.picture_width >> 1; m_Convert.lpDest0 = (Ipp8u*)pOutVideoData->m_lpDest[0]; m_Convert.lpDest1 = (Ipp8u*)pOutVideoData->m_lpDest[1]; m_Convert.lpDest2 = (Ipp8u*)pOutVideoData->m_lpDest[2]; m_Convert.PitchDest0 = pOutVideoData->m_lPitch[0]; m_Convert.PitchDest1 = pOutVideoData->m_lPitch[1]; m_Convert.PitchDest2 = pOutVideoData->m_lPitch[2]; if (NULL != m_pConverter) status = m_pConverter->ConvertFrame(&m_Convert); } break; }; pts = -1.0; if (in) { if (in->GetTime() >= 0.0 && m_dec_time_base < 0.0) m_dec_time_base = in->GetTime(); pts = in->GetTime(); } if (pts < 0) { pts = (double)m_decInfo.time * (1001.0 / 30000.0); if (m_dec_time_base >= 0.0) pts += m_dec_time_base; } if (m_buffered_frame) { double tmp = pts; pts = m_dec_time_prev; m_dec_time_prev = tmp; } if (out) out->SetTime(pts); if (in) { size_t stDecidedData; if ((size_t)m_decInfo.bufptr - (size_t)m_decInfo.buffer < (size_t)m_decInfo.buflen) stDecidedData = m_decInfo.buflen - ((size_t)m_decInfo.bufptr - (size_t)m_decInfo.buffer); else stDecidedData = 0; in->MoveDataPointer(in->GetDataSize() - static_cast<vm_var32>(stDecidedData)); // can't calculate time for the next frame in->SetTime(-1.0); } return status;}Status H261VideoDecoder::GetInfo(BaseCodecParams *lpInfo){ Status umcRes = UMC_OK; VideoDecoderParams *lpParams = DynamicCast<VideoDecoderParams> (lpInfo); if (NULL == lpParams) umcRes = UMC_NULL_PTR; if (UMC_OK == umcRes) umcRes = VideoDecoder::GetInfo(lpInfo); if (UMC_OK == umcRes) { lpParams->info.clip_info.width = m_Convert.ConversionInit.SizeDest.width; lpParams->info.clip_info.height =m_Convert.ConversionInit.SizeDest.height; } return umcRes;}Status H261VideoDecoder::Close(void){ if (m_IsInit) { freeDecoder(&m_decInfo); m_IsInit = false; return UMC_OK; } else return UMC_NOT_INITIALIZED;}H261VideoDecoder::H261VideoDecoder(void){ m_IsInit = false;}H261VideoDecoder::~H261VideoDecoder(void){ Close();}Status H261VideoDecoder::ResetSkipCount(){ return UMC_NOT_IMPLEMENTED;}Status H261VideoDecoder::SkipVideoFrame(int count){ return UMC_NOT_IMPLEMENTED;}vm_var32 H261VideoDecoder::GetSkipedFrame(void){ return 0;}Status H261VideoDecoder::Reset(void){ if (m_IsInit) return UMC_OK; else return UMC_ALLOC;}Status H261VideoDecoder::GetPerformance(double *perf){ return UMC_NOT_IMPLEMENTED;}} // end namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -