📄 umc_mpeg4_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) 2003-2005 Intel Corporation. All Rights Reserved.////*/#include <string.h>#include "vm_debug.h"#include "umc_mpeg4_video_decoder.h"#include "umc_video_data.h"#include "mp4.h"namespace UMC{Status MPEG4VideoDecoder::Init(BaseCodecParams *lpInit){ Status status = UMC_OK; VideoDecoderParams *pParam = DynamicCast<VideoDecoderParams> (lpInit); if (NULL == m_decInfo) return UMC_ALLOC; 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(mp4_Info)); 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 || UMC_NOT_FIND_SYNCWORD == 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->VisualObject.VideoObject.width == 0 && m_decInfo->VisualObject.VideoObject.height== 0) return UMC_BAD_STREAM; else { pParam->info.clip_info.width = m_Param.info.clip_info.width = m_decInfo->VisualObject.VideoObject.width; pParam->info.clip_info.height = m_Param.info.clip_info.height = m_decInfo->VisualObject.VideoObject.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 MPEG4VideoDecoder::InsideInit(VideoDecoderParams *pParam){ Status status; Ipp32u code, h_vo_found = 0, h_vos_found = 0; Close(); m_buffered_frame = m_Param.lFlags & FLAG_VDEC_REORDER; if (pParam->info.stream_subtype == MPEG4_VIDEO_DIVX5) { m_decInfo->ftype = 2; m_decInfo->ftype_f = 1; } else if (pParam->info.stream_subtype == MPEG4_VIDEO_QTIME) { m_decInfo->ftype = 1; m_decInfo->ftype_f = 0; } else { // UNDEF_VIDEO_SUBTYPE m_decInfo->ftype = 0; m_decInfo->ftype_f = 0; } for (;;) { if (!mp4_SeekStartCodeOrShortPtr(m_decInfo)) { vm_debug_trace(4,__VM_STRING("Error: Can't find Visual Object or Video Object start codes or short_video_start_marker\n")); return UMC_NOT_FIND_SYNCWORD; } // check short_video_start_marker if ((mp4_ShowBits(m_decInfo, 24) & (0xFFFFFC)) == 0x80) { code = MP4_VIDEO_OBJECT_MIN_SC; } else { code = mp4_GetBits(m_decInfo, 8); if (!h_vos_found && code == MP4_VISUAL_OBJECT_SEQUENCE_SC) { h_vos_found = 1; } if (!h_vo_found && code == MP4_VISUAL_OBJECT_SC) { h_vo_found = 1; if ((mp4_Parse_VisualObject(m_decInfo)) != MP4_STATUS_OK) return UMC_BAD_STREAM; } } if ((int)code >= MP4_VIDEO_OBJECT_MIN_SC && code <= MP4_VIDEO_OBJECT_MAX_SC) { if ((mp4_Parse_VideoObject(m_decInfo)) != MP4_STATUS_OK) return UMC_BAD_STREAM; break; } } if (mp4_InitVOL(m_decInfo) != MP4_STATUS_OK) { vm_debug_trace(4,__VM_STRING("Error: No memory to allocate internal buffers\n")); return UMC_ALLOC; } // set aspect ratio info switch (m_decInfo->VisualObject.VideoObject.aspect_ratio_info) { case MP4_ASPECT_RATIO_FORBIDDEN: case MP4_ASPECT_RATIO_1_1: pParam->info.aspect_ratio_width = 1; pParam->info.aspect_ratio_height = 1; break; case MP4_ASPECT_RATIO_12_11: pParam->info.aspect_ratio_width = 12; pParam->info.aspect_ratio_height = 11; break; case MP4_ASPECT_RATIO_10_11: pParam->info.aspect_ratio_width = 10; pParam->info.aspect_ratio_height = 11; break; case MP4_ASPECT_RATIO_16_11: pParam->info.aspect_ratio_width = 16; pParam->info.aspect_ratio_height = 11; break; case MP4_ASPECT_RATIO_40_33: pParam->info.aspect_ratio_width = 40; pParam->info.aspect_ratio_height = 33; break; default: pParam->info.aspect_ratio_width = m_decInfo->VisualObject.VideoObject.aspect_ratio_info_par_width; pParam->info.aspect_ratio_height = m_decInfo->VisualObject.VideoObject.aspect_ratio_info_par_height; } m_IsInit = true; return UMC_OK;}Status MPEG4VideoDecoder::GetFrame(MediaData* in, MediaData* out){ Status status = UMC_OK; double pts; 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); 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; m_decInfo->VisualObject.vFrame = m_decInfo->VisualObject.VideoObject.prevPlaneIsB ? &m_decInfo->VisualObject.nFrame : &m_decInfo->VisualObject.cFrame; } else { // Seeking the VOP start_code, and then begin the vop decoding if (m_decInfo->VisualObject.VideoObject.short_video_header) { if (!mp4_SeekShortVideoStartMarker(m_decInfo)) { vm_debug_trace(4,__VM_STRING("Error: Failed seeking short_video_start_marker\n")); status = UMC_NOT_FIND_SYNCWORD; break; } } else { if (!mp4_SeekStartCodeValue(m_decInfo, MP4_VIDEO_OBJECT_PLANE_SC)) { vm_debug_trace(4,__VM_STRING("Error: Failed seeking VOP Start Code\n")); status = UMC_NOT_FIND_SYNCWORD; break; } } // parse VOP header if ((mp4_Parse_VideoObjectPlane(m_decInfo)) != MP4_STATUS_OK) { status = UMC_BAD_STREAM; break; } if (m_decInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B) { if (0 < m_is_skipped_b && !m_b_prev) { m_is_skipped_b --; m_skipped_fr ++; m_b_prev = 1; m_decInfo->bufptr = m_decInfo->buffer+ m_decInfo->buflen; status = UMC_NOT_ENOUGH_DATA; break; } else m_b_prev = 0; } // decode VOP if ((mp4_DecodeVideoObjectPlane(m_decInfo)) != MP4_STATUS_OK) { status = UMC_BAD_STREAM; } if (m_decInfo->VisualObject.VideoObject.VideoObjectPlane.coded || (m_decInfo->VisualObject.rFrame.time != m_decInfo->VisualObject.cFrame.time && m_decInfo->VisualObject.nFrame.time != m_decInfo->VisualObject.cFrame.time)) { m_decInfo->VisualObject.VideoObject.VOPindex ++; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -