📄 base_video_render.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-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "base_video_render.h"
namespace UMC
{
#define MODULE "BaseVideoRender:"
#define FUNCTION "Unknown"
#define DBG_SET(msg) VIDEO_DRV_DBG_SET (MODULE, FUNCTION, msg)
BaseVideoRender::BaseVideoRender():
m_iBuffersNum(0),
m_iReadIndex(-1),
m_iLastFrameIndex(-1),
m_iWriteIndex(-1),
m_bPrevIp(false),
m_bShow(true),
m_bReorder(false),
m_bRenderingError(false)
{
memset(m_Buffers, 0, sizeof(m_Buffers));
memset(&m_dst_rect, 0, sizeof(m_dst_rect));
memset(&m_src_rect, 0, sizeof(m_src_rect));
m_SrcInfo.width = m_SrcInfo.height = 10;
m_bPrepareForReposition = false;
} // BaseVideoRender::BaseVideoRender():
BaseVideoRender::~BaseVideoRender()
{
Close();
} // BaseVideoRender::~BaseVideoRender()
// Initialize the render, return false if failed, call Close anyway
Status BaseVideoRender::Init(MediaReceiverParams *pInit)
{
Status umcRes = UMC_OK;
VideoRenderParams* pParams = DynamicCast<VideoRenderParams>(pInit);
if (NULL == pParams)
umcRes = UMC_ERR_NULL_PTR;
m_bPrepareForReposition = false;
m_bPrevIp = false;
m_bStop = false;
if (NONE == pParams->out_data_template.GetColorFormat())
m_SrcInfo = pParams->info;
else
{
m_SrcInfo.width = pParams->out_data_template.GetWidth();
m_SrcInfo.height = pParams->out_data_template.GetHeight();
}
m_bShow = true;
m_iWriteIndex = -1;
m_iReadIndex = -1;
m_iLastFrameIndex = -1;
m_bReorder = pParams->lFlags & FLAG_VREN_REORDER;
if (UMC_OK == umcRes)
{
umcRes = m_SuncMut.Init();
}
if (UMC_OK == umcRes)
{
umcRes = m_LockBufMut.Init();
}
VM_ASSERT(2 < MIN_FRAME_BUFFERS);
if (UMC_OK == umcRes)
umcRes = m_hDoneBufSema.Init(0);
if (UMC_OK == umcRes)
{
umcRes = m_hFreeBufSema.Init(m_iBuffersNum - 2);
m_hFreeBufSemaCount = m_iBuffersNum - 2;
}
if (UMC_OK == umcRes)
umcRes = ResizeDisplay(pParams->disp, pParams->range);
if (UMC_OK != umcRes)
Close();
return umcRes;
} // Status BaseVideoRender::Init(MediaReceiverParams *pInit)
Status BaseVideoRender::LockInputBuffer(MediaData *pInData)
{
#undef FUNCTION
#define FUNCTION "LockInputBuffer"
DBG_SET ("+");
Status umcRes = UMC_OK;
VideoData *pVideoData = DynamicCast<VideoData> (pInData);
if (NULL == pVideoData)
umcRes = UMC_ERR_NULL_PTR;
m_LockBufMut.Lock();
if (UMC_OK == umcRes)
{
if (m_bRenderingError)
{
DBG_SET(VM_STRING("critical error in RenderFrame"));
umcRes = UMC_ERR_FAILED;
}
}
if (UMC_OK == umcRes)
{
umcRes = m_hFreeBufSema.Wait(MAX_FRAME_BUFFERS * 40);
}
Ipp32s iPitch = 0;
Ipp8u *pbVideoMemory = NULL;
if (UMC_OK == umcRes)
{
m_SuncMut.Lock();
Ipp32s saved_FreeBufSemaCount = m_hFreeBufSemaCount;
Ipp32s saved_WriteIndex = m_iWriteIndex;
m_hFreeBufSemaCount--;
if (++m_iWriteIndex >= m_iBuffersNum)
m_iWriteIndex = 0;
iPitch = LockSurface(&pbVideoMemory);
if (0 == iPitch)
{
/* Unlocking buffer if render can't lock surface (example - SDL). */
m_hFreeBufSemaCount = saved_FreeBufSemaCount;
m_iWriteIndex = saved_WriteIndex;
m_hFreeBufSema.Signal();
umcRes = UMC_ERR_ALLOC;
}
m_SuncMut.Unlock();
}
if (UMC_OK == umcRes)
{
umcRes = pVideoData->SetSurface(pbVideoMemory, iPitch);
//pVideoData->SetPlanePointer(pbVideoMemory, 0);
//pVideoData->SetPlanePitch(iPitch, 0);
}
if (UMC_OK != umcRes)
{
m_LockBufMut.Unlock();
}
DBG_SET ("-");
return umcRes;
} // Status BaseVideoRender::LockInputBuffer(MediaData *pInData)
// Reserve a frame buffer for decoding the current frame
Ipp32s BaseVideoRender::ReserveBuffer(Ipp8u **ppucVidMem)
{
Ipp32s iRes = 0;
VideoData Data;
Data.Init(1,1,1,8); // only need pointer and pitch
if (UMC_OK == LockInputBuffer(&Data))
{
iRes = (Ipp32s)Data.GetPlanePitch(0);
if (NULL != ppucVidMem)
*ppucVidMem = (Ipp8u *)Data.GetPlanePointer(0);
}
return iRes;
} // Ipp32s BaseVideoRender::ReserveBuffer(Ipp8u **ppucVidMem)
Status BaseVideoRender::UnLockInputBuffer(MediaData* pInData, Status StreamStatus)
{
Status umcRes = (m_iWriteIndex >= 0) ? UMC_OK : UMC_ERR_NOT_INITIALIZED;
VideoData *pVideoData = DynamicCast<VideoData> (pInData);
if (NULL == pVideoData)
return UMC_ERR_NULL_PTR;
if (UMC_OK == umcRes)
{
if (m_bRenderingError)
{
DBG_SET(VM_STRING("critical error in RenderFrame"));
umcRes = UMC_ERR_FAILED;
}
}
if (UMC_OK == umcRes)
{
Ipp32s width = pVideoData->GetWidth();
Ipp32s height = pVideoData->GetHeight();
if(m_SrcInfo.width != width)
{
m_SrcInfo.width = width;
ResizeSource();
}
if(m_SrcInfo.height != height)
{
m_SrcInfo.height = height;
ResizeSource();
}
if (UMC_OK == umcRes)
{
m_SuncMut.Lock();
Ipp64f dfEndTime;
pVideoData->GetTime(m_Buffers[m_iWriteIndex].frame_time, dfEndTime);
m_Buffers[m_iWriteIndex].frame_type = pVideoData->GetFrameType();
UnlockSurface(0);
if (m_bReorder)
{
if (!m_bPrevIp)
{
if (pVideoData->GetFrameType() == B_PICTURE)
m_hDoneBufSema.Signal();
else
m_bPrevIp = true;
}
else
{
if (pVideoData->GetFrameType() == B_PICTURE)
{
Ipp32s prev_index = (!m_iWriteIndex) ?
(m_iBuffersNum - 1) : (m_iWriteIndex - 1);
sFrameBuffer tmp = m_Buffers[m_iWriteIndex];
m_Buffers[m_iWriteIndex] = m_Buffers[prev_index];
m_Buffers[prev_index] = tmp;
}
m_hDoneBufSema.Signal();
}
}
else
m_hDoneBufSema.Signal();
m_SuncMut.Unlock();
}
}
if (UMC_ERR_END_OF_STREAM == StreamStatus)
{
Stop();
}
if (UMC_OK == umcRes)
{
m_LockBufMut.Unlock();
}
return umcRes;
} // Status BaseVideoRender::UnLockInputBuffer(MediaData* pInData, Status StreamStatus)
// Buffer the decoded frame
Status BaseVideoRender::BufferReserved(Ipp64f frame_time, FrameType frame_type)
{
VideoData Data;
Data.SetFrameType(frame_type);
Data.SetTime(frame_time);
return UnLockInputBuffer(&Data);
} // Status BaseVideoRender::BufferReserved(Ipp64f frame_time, FrameType frame_type)
Status BaseVideoRender::Stop()
{
Status umcRes = UMC_OK;
VideoData InData;
if (m_bStop)
return umcRes;
m_SuncMut.Lock();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -