📄 umc_h263_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_h263_video_decoder.h"#include "umc_video_data.h"#include "h263.h"namespace UMC{Status H263VideoDecoder::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_is_skipped_b = m_skipped_fr = m_b_prev = 0; 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(); m_decInfo.buflen = pParam->m_pData->GetDataSize(); m_decInfo.bufptr = m_decInfo.buffer = reinterpret_cast<unsigned char *> (pParam->m_pData->GetDataPointer()); m_decInfo.bitoff = 0; 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)) 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; if (pParam->info.clip_info.width == 0 || pParam->info.clip_info.height == 0) { if (m_decInfo.VideoSequence.VideoPicture.width == 0 && m_decInfo.VideoSequence.VideoPicture.height== 0) return UMC_BAD_STREAM; else { pParam->info.clip_info.width = m_Param.info.clip_info.width = m_decInfo.VideoSequence.VideoPicture.width; pParam->info.clip_info.height = m_Param.info.clip_info.height = m_decInfo.VideoSequence.VideoPicture.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 H263VideoDecoder::InsideInit(VideoDecoderParams *pParam){ Status status; Close(); m_buffered_frame = m_Param.lFlags & FLAG_VDEC_REORDER; m_P_part_of_PB_pending = false; /* can be true only if !(m_Param.lFlags & FLAG_VDEC_REORDER) */ if (!h263_SeekStartCodePtr(&m_decInfo)) { vm_debug_trace(4,__VM_STRING("Error: Can't find picture start code\n")); return UMC_NOT_FIND_SYNCWORD; } if (h263_Parse_PictureHeader(&m_decInfo) != H263_STATUS_OK) return UMC_BAD_STREAM; if (h263_InitVSeq(&m_decInfo, -1, -1) != H263_STATUS_OK) { vm_debug_trace(4,__VM_STRING("Error: No memory to allocate internal buffers\n")); return UMC_ALLOC; } m_IsInit = true; return UMC_OK;}Status H263VideoDecoder::GetFrame(MediaData* in, MediaData* out){ Status status = UMC_OK; double pts; bool init_inside = false; if (in) { m_decInfo.bitoff = 0; m_decInfo.bufptr = m_decInfo.buffer = (Ipp8u *)in->GetDataPointer(); m_decInfo.buflen = in->GetDataSize(); } if (!m_IsInit) { if (in == NULL) return UMC_NULL_PTR; m_Param.m_pData = in; status = InsideInit(&m_Param); init_inside = true; 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; if (m_decInfo.VideoSequence.Ppics_to_show > 0) { m_decInfo.VideoSequence.vFrame = &m_decInfo.VideoSequence.rFrame; m_decInfo.VideoSequence.PicIndex++; m_decInfo.VideoSequence.Ppics_to_show = 0; } else if (m_decInfo.VideoSequence.Bpics_to_show > 0) { m_decInfo.VideoSequence.vFrame = &m_decInfo.VideoSequence.nFrame; m_decInfo.VideoSequence.PicIndex++; m_decInfo.VideoSequence.Bpics_to_show = 0; } else { m_decInfo.VideoSequence.vFrame = &m_decInfo.VideoSequence.cFrame; m_buffered_frame = false; } } else { if (m_decInfo.VideoSequence.Ppics_to_show < 1 && !m_P_part_of_PB_pending) { /* Seek the picture start code, and then begin the picture decoding */ if (!init_inside) { if (!h263_SeekStartCodePtr(&m_decInfo)) { vm_debug_trace(4,__VM_STRING("Error: Can't find picture start code\n")); status = UMC_NOT_FIND_SYNCWORD; break; } if (h263_Parse_PictureHeader(&m_decInfo) != H263_STATUS_OK) { status = UMC_BAD_STREAM; break; } } } if (!m_P_part_of_PB_pending) { if ((h263_DecodeVideoPicture(&m_decInfo)) != H263_STATUS_OK) { status = UMC_BAD_STREAM; } if (!(m_Param.lFlags & FLAG_VDEC_REORDER)) { m_decInfo.VideoSequence.Ppics_to_show = 0; m_decInfo.VideoSequence.Bpics_to_show = 0; m_P_part_of_PB_pending = (m_decInfo.VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_PB || m_decInfo.VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_iPB); } } else m_P_part_of_PB_pending = false; m_decInfo.VideoSequence.PicIndex++; if ((m_Param.lFlags & FLAG_VDEC_REORDER) && (m_decInfo.VideoSequence.vFrame == NULL)) { // buffer first frame in VDEC_REORDER mode status = UMC_NOT_ENOUGH_DATA; break; } if (!(m_Param.lFlags & FLAG_VDEC_REORDER)) { if (m_P_part_of_PB_pending || m_decInfo.VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_B) { m_decInfo.VideoSequence.vFrame = &m_decInfo.VideoSequence.nFrame; } else { m_decInfo.VideoSequence.vFrame = &m_decInfo.VideoSequence.cFrame; } } } if (out) { VideoData* pOutVideoData = DynamicCast<VideoData>(out); FrameType ft = (m_decInfo.VideoSequence.vFrame->type) == H263_PIC_TYPE_I ? I_PICTURE : (m_decInfo.VideoSequence.vFrame->type) == H263_PIC_TYPE_B ? B_PICTURE : P_PICTURE; pOutVideoData->SetFrameType(ft); // set source pointer(s) m_Convert.lpSource0 = m_decInfo.VideoSequence.vFrame->pY; m_Convert.lpSource2 = m_decInfo.VideoSequence.vFrame->pCb; m_Convert.lpSource1 = m_decInfo.VideoSequence.vFrame->pCr; m_Convert.PitchSource0 = m_decInfo.VideoSequence.vFrame->stepY; m_Convert.PitchSource2 = m_decInfo.VideoSequence.vFrame->stepCb; m_Convert.PitchSource1 = m_decInfo.VideoSequence.vFrame->stepCr; 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; } if (in) if (in->GetTime() >= 0.0 && m_dec_time_base < 0.0) m_dec_time_base = in->GetTime(); if (m_Param.lFlags & FLAG_VDEC_REORDER) { if (m_dec_time_prev >= 0.0) pts = m_dec_time_prev; else { if (m_Param.info.framerate > 0) pts = m_dec_time_fr; else { if (m_decInfo.VideoSequence.vFrame) pts = (double)m_decInfo.VideoSequence.vFrame->time / m_decInfo.VideoSequence.picture_time_increment_resolution; else pts = 0.0; } if (m_dec_time_base >= 0.0) pts += m_dec_time_base; } m_dec_time_fr += m_dec_time_frinc; if (in) m_dec_time_prev = in->GetTime(); } else { if (in->GetTime() >= 0.0) pts = in->GetTime(); else { pts = (double)m_decInfo.VideoSequence.vFrame->time / m_decInfo.VideoSequence.picture_time_increment_resolution; if (m_dec_time_base >= 0.0) pts += m_dec_time_base; } } if (out) out->SetTime(pts); if (in) { size_t stDecidedData; if ((size_t)m_decInfo.bufptr - (size_t)m_decInfo.buffer < 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 H263VideoDecoder::GetInfo(BaseCodecParams *lpInfo){ Status umcRes = UMC_OK; VideoDecoderParams *lpParams = DynamicCast<VideoDecoderParams> (lpInfo);// if (!m_IsInit)// return UMC_NOT_INITIALIZED; 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 H263VideoDecoder::Close(void){ if (m_IsInit) { h263_FreeVSeq(&m_decInfo); m_IsInit = false; return UMC_OK; } else return UMC_NOT_INITIALIZED;}H263VideoDecoder::H263VideoDecoder(void){ m_IsInit = false;}H263VideoDecoder::~H263VideoDecoder(void){ Close();}Status H263VideoDecoder::ResetSkipCount(){ return UMC_NOT_IMPLEMENTED;}Status H263VideoDecoder::SkipVideoFrame(int count){ if (!m_IsInit) return UMC_NOT_INITIALIZED; if (count < 0) { m_is_skipped_b = 0; return UMC_OK; } m_is_skipped_b += count; return UMC_OK;}vm_var32 H263VideoDecoder::GetSkipedFrame(void){ return m_skipped_fr;}Status H263VideoDecoder::Reset(void){ if (!m_IsInit) return UMC_NOT_INITIALIZED; else return UMC_OK;}Status H263VideoDecoder::GetPerformance(double *perf){ return UMC_NOT_IMPLEMENTED;}} // end namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -