📄 umc_h263_video_decoder.cpp
字号:
return status;
m_dec_time_fr = 0.0;
m_dec_time_base = -1.0;
m_dec_time_prev = 0.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(h263_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();
if (m_decInfo->buflen > 0) {
m_decInfo->bufptr = m_decInfo->buffer = reinterpret_cast<Ipp8u *> (pParam->m_pData->GetDataPointer());
// m_decInfo->bitoff = 0;
status = InsideInit(&m_Param);
}
}
if (UMC_OK == status) {
m_PostProcessing = pParam->pPostProcessing;
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_ERR_INIT;
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->info.framerate <= 0) {
Ipp32s frameInterval;
if (m_decInfo->VideoSequence.VideoPicture.clock_divisor)
frameInterval = m_decInfo->VideoSequence.VideoPicture.clock_divisor * (1000 + m_decInfo->VideoSequence.VideoPicture.clock_conversion_code);
else
frameInterval = H263_DEFAULT_FRAME_INTERVAL;
pParam->info.framerate = m_Param.info.framerate = (Ipp64f)m_decInfo->VideoSequence.picture_time_increment_resolution / (Ipp64f)frameInterval;
}
}
m_ClipInfo = m_Param.info;
m_IsInitBase = true;
return status;
}
Status H263VideoDecoder::InsideInit(VideoDecoderParams *pParam)
{
Status status = UMC_OK;
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) */
m_decInfo->number_threads = m_Param.numThreads;
if (!h263_SeekStartCodePtr(m_decInfo)) {
vm_debug_trace(VM_DEBUG_INFO,__VM_STRING("Error: Can't find picture start code\n"));
return UMC_ERR_SYNC;
}
if (h263_Parse_PictureHeader(m_decInfo) != H263_STATUS_OK)
return UMC_ERR_INVALID_STREAM;
if (h263_InitVSeq(m_decInfo, -1, -1) != H263_STATUS_OK) {
vm_debug_trace(VM_DEBUG_INFO,__VM_STRING("Error: No memory to allocate internal buffers\n"));
return UMC_ERR_ALLOC;
}
pParam->info.clip_info.width = m_decInfo->VideoSequence.VideoPicture.width;
pParam->info.clip_info.height = m_decInfo->VideoSequence.VideoPicture.height;
status = AllocateBuffers();
if (status != UMC_OK)
return status;
m_decInfo->bufptr = m_decInfo->buffer;
m_decInfo->bitoff = 0;
m_IsInit = true;
return status;
}
Status H263VideoDecoder::GetFrame(MediaData* in, MediaData* out)
{
Status status = UMC_OK;
Ipp64f pts;
Ipp32s resizeMask;
#ifdef _OMP_KARABAS
m_decInfo->mTreadPriority = vm_get_current_thread_priority();
#endif // _OMP_KARABAS
if (!m_IsInitBase)
return UMC_ERR_NOT_INITIALIZED;
if (out == NULL)
return UMC_ERR_NULL_PTR;
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_ERR_NULL_PTR;
m_Param.m_pData = in;
status = InsideInit(&m_Param);
if (status != UMC_OK) {
in->MoveDataPointer(in->GetDataSize() - m_decInfo->buflen);
return UMC_ERR_INIT;
}
}
LockBuffers();
for (;;) {
if (in == NULL) {
// show last frame (it can be only if (m_Param.lFlags & FLAG_VDEC_REORDER))
if (!m_buffered_frame) {
UnlockBuffers();
return UMC_ERR_NOT_ENOUGH_DATA;
}
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 (!h263_SeekStartCodePtr(m_decInfo)) {
vm_debug_trace(VM_DEBUG_INFO,__VM_STRING("Error: Can't find picture start code\n"));
status = UMC_ERR_SYNC;
break;
}
if (h263_Parse_PictureHeader(m_decInfo) != H263_STATUS_OK) {
status = UMC_WRN_INVALID_STREAM;
break;
}
if (m_decInfo->VideoSequence.VideoPicture.picture_coding_type == H263_PIC_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_ERR_NOT_ENOUGH_DATA;
break;
} else
m_b_prev = 0;
}
/*
if (m_decInfo->VideoSequence.VideoPicture.enh_layer_num > 1) {
status = UMC_ERR_NOT_ENOUGH_DATA;
break;
}
*/
resizeMask = h263_Check_Resize(m_decInfo);
if (resizeMask < 0) {
status = UMC_WRN_INVALID_STREAM;
break;
}
if (resizeMask) {
status = ReAlLockBuffers(resizeMask);
if (status != UMC_OK)
break;
}
if (m_decInfo->VideoSequence.VideoPicture.enh_layer_num > 1)
LockEnhancedLayerBuffers(m_decInfo->VideoSequence.VideoPicture.enh_layer_num, m_decInfo->VideoSequence.VideoPicture.ref_layer_num, (resizeMask >> 4));
}
if (!m_P_part_of_PB_pending) {
if ((h263_DecodeVideoPicture(m_decInfo)) != H263_STATUS_OK) {
status = UMC_WRN_INVALID_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;
// TODO: add enh layer output optional processing and skipping ???
if (m_decInfo->VideoSequence.VideoPicture.enh_layer_num > 1) {
m_decInfo->VideoSequence.enhLayers[m_decInfo->VideoSequence.VideoPicture.enh_layer_num - 2]->picIndex++;
UnlockEnhancedLayerBuffers(m_decInfo->VideoSequence.VideoPicture.enh_layer_num, m_decInfo->VideoSequence.VideoPicture.ref_layer_num);
status = UMC_ERR_NOT_ENOUGH_DATA;
break;
}
/*
if (m_decInfo->VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_EP || m_decInfo->VideoSequence.VideoPicture.picture_coding_type == H263_PIC_TYPE_EI) {
m_decInfo->VideoSequence.vFrame = m_decInfo->VideoSequence.enhLayers[m_decInfo->VideoSequence.VideoPicture.enh_layer_num - 2]->v_Frame;
}
*/
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_ERR_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;
}
}
}
break;
}
if (in)
if (in->GetTime() >= 0.0 && m_dec_time_base < 0.0)
m_dec_time_base = in->GetTime();
if (m_dec_time_frinc > 0.0) {
if (m_Param.lFlags & FLAG_VDEC_REORDER)
pts = m_dec_time_prev;
if (in) {
if (in->GetTime() >= 0.0) {
// take right PTS for I-, P- frames
m_dec_time_prev = in->GetTime();
} else {
// when PB... are in one AVI chunk, first PTS from in->GetTime() is right and second is -1.0
m_dec_time_prev += m_dec_time_frinc;
}
}
if (!(m_Param.lFlags & FLAG_VDEC_REORDER))
pts = m_dec_time_prev;
} else {
if (in && in->GetTime() >= 0.0)
pts = in->GetTime();
else {
// internal pts
if (m_decInfo->VideoSequence.vFrame)
pts = (Ipp64f)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;
}
}
if ((UMC_OK == status || UMC_WRN_INVALID_STREAM == status) && m_decInfo->VideoSequence.vFrame != NULL) {
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;
if (m_LastDecodedFrame.GetColorFormat() != YUV420) {
m_LastDecodedFrame.Init(m_decInfo->VideoSequence.vFrame->width,
m_decInfo->VideoSequence.vFrame->height,
YUV420);
}
m_LastDecodedFrame.SetFrameType(ft);
m_LastDecodedFrame.SetTime(pts);
m_LastDecodedFrame.SetPlanePointer(m_decInfo->VideoSequence.vFrame->pY, 0);
m_LastDecodedFrame.SetPlanePointer(m_decInfo->VideoSequence.vFrame->pCb, 1);
m_LastDecodedFrame.SetPlanePointer(m_decInfo->VideoSequence.vFrame->pCr, 2);
m_LastDecodedFrame.SetPlanePitch(m_decInfo->VideoSequence.vFrame->stepY, 0);
m_LastDecodedFrame.SetPlanePitch(m_decInfo->VideoSequence.vFrame->stepCb, 1);
m_LastDecodedFrame.SetPlanePitch(m_decInfo->VideoSequence.vFrame->stepCr, 2);
if (!m_PostProcessing) {
m_PostProcessing = m_allocatedPostProcessing = createVideoProcessing();
}
status = m_PostProcessing->GetFrame(&m_LastDecodedFrame, out);
}
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<Ipp32u>(stDecidedData));
// can't calculate time for the next frame
in->SetTime(-1.0);
}
UnlockBuffers();
return status;
}
Status H263VideoDecoder::Close(void)
{
m_IsInitBase = false;
if (m_IsInit) {
FreeBuffers();
// close default memory allocator
BaseCodec::Close();
h263_FreeVSeq(m_decInfo);
m_IsInit = false;
}
return UMC_OK;
}
H263VideoDecoder::H263VideoDecoder(void)
{
m_IsInit = m_IsInitBase = false;
m_decInfo = new h263_Info;
}
H263VideoDecoder::~H263VideoDecoder(void)
{
Close();
delete m_decInfo;
}
Status H263VideoDecoder::GetInfo(BaseCodecParams* info)
{
VideoDecoderParams *pParams;
if (!m_IsInitBase)
return UMC_ERR_NOT_INITIALIZED;
if (info == NULL)
return UMC_ERR_NULL_PTR;
pParams = DynamicCast<VideoDecoderParams> (info);
if (NULL != pParams) {
*pParams = m_Param;
} else {
if (!m_IsInit)
return UMC_ERR_NOT_INITIALIZED;
// info->profile = m_Param.profile;
// info->level = m_Param.level;
}
return UMC_OK;
}
/*
h263_Frame* H263VideoDecoder::GetCurrentFramePtr(void)
{
return m_decInfo->VideoSequence.vFrame;
}
*/
Status H263VideoDecoder::ResetSkipCount()
{
if (!m_IsInitBase)
return UMC_ERR_NOT_INITIALIZED;
m_is_skipped_b = m_skipped_fr = m_b_prev = 0;
return UMC_OK;
}
Status H263VideoDecoder::SkipVideoFrame(Ipp32s count)
{
if (!m_IsInitBase)
return UMC_ERR_NOT_INITIALIZED;
if (count < 0) {
m_is_skipped_b = 0;
return UMC_OK;
}
m_is_skipped_b += count;
return UMC_OK;
}
Ipp32u H263VideoDecoder::GetNumOfSkippedFrames(void)
{
return m_skipped_fr;
}
Status H263VideoDecoder::Reset(void)
{
if (!m_IsInitBase) {
return UMC_ERR_NOT_INITIALIZED;
} else if (m_IsInit) {
m_decInfo->VideoSequence.PicIndex = 0;
m_decInfo->VideoSequence.Bpics_to_show = m_decInfo->VideoSequence.Ppics_to_show = 0;
m_decInfo->VideoSequence.prevP_pic_time = m_decInfo->VideoSequence.ref_pic_time = 0;
m_decInfo->VideoSequence.prevP_temporal_reference = 0;
m_P_part_of_PB_pending = false;
m_dec_time_base = -1.0;
m_dec_time_prev = 0.0;
m_decInfo->VideoSequence.vFrame = NULL;
}
return UMC_OK;
}
Status H263VideoDecoder::GetPerformance(Ipp64f *perf)
{
return UMC_ERR_NOT_IMPLEMENTED;
}
} // end namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -