📄 umc_mpeg4_video_decoder.cpp
字号:
ppFrame1.mbPerCol = m_decInfo->VisualObject.vFrame->mbPerCol;
status = AllocateInitFrame(&ppFrame1);
if (status != UMC_OK)
return status;
}
if (ppFrame0.mid)
LockFrame(&ppFrame0);
if (ppFrame1.mid)
LockFrame(&ppFrame1);
PostProcess(&rendFrame);
}
//if (m_LastDecodedFrame.GetColorFormat() != YUV420) {
m_LastDecodedFrame.Init(m_decInfo->VisualObject.VideoObject.width, m_decInfo->VisualObject.VideoObject.height, YUV420);
//}
m_LastDecodedFrame.SetFrameType(ft);
m_LastDecodedFrame.SetTime(pts);
m_LastDecodedFrame.SetPlanePointer(rendFrame.pY, 0);
m_LastDecodedFrame.SetPlanePointer(rendFrame.pCb, 1);
m_LastDecodedFrame.SetPlanePointer(rendFrame.pCr, 2);
m_LastDecodedFrame.SetPlanePitch(rendFrame.stepY, 0);
m_LastDecodedFrame.SetPlanePitch(rendFrame.stepCb, 1);
m_LastDecodedFrame.SetPlanePitch(rendFrame.stepCr, 2);
if (!m_PostProcessing) {
if (m_allocatedPostProcessing)
m_PostProcessing = m_allocatedPostProcessing;
else
m_PostProcessing = m_allocatedPostProcessing = createVideoProcessing();
}
m_PostProcessing->GetFrame(&m_LastDecodedFrame, out);
if (ppDeblocking || ppDeringing) {
if (ppFrame0.mid)
status = m_pMemoryAllocator->Unlock(ppFrame0.mid);
if (ppFrame1.mid)
status = m_pMemoryAllocator->Unlock(ppFrame1.mid);
}
}
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);
}
// set interlaced info
if (!m_decInfo->VisualObject.VideoObject.interlaced)
m_Param.info.interlace_type = PROGRESSIVE;
else
m_Param.info.interlace_type = (m_decInfo->VisualObject.VideoObject.VideoObjectPlane.top_field_first) ? INTERLEAVED_TOP_FIELD_FIRST : INTERLEAVED_BOTTOM_FIELD_FIRST;
UnlockBuffers();
return status;
}
Status MPEG4VideoDecoder::Close(void)
{
m_IsInitBase = false;
if (m_IsInit) {
Status status = UMC_OK;
if (ppFrame0.mid) {
status = m_pMemoryAllocator->Free(ppFrame0.mid);
ppFrame0.mid = 0;
if (status != UMC_OK)
return status;
}
if (ppFrame1.mid) {
status = m_pMemoryAllocator->Free(ppFrame1.mid);
ppFrame1.mid = 0;
if (status != UMC_OK)
return status;
}
status = FreeBuffers();
if (status != UMC_OK)
return status;
// close default memory allocator if exist
status = BaseCodec::Close();
if (status != UMC_OK)
return status;
m_IsInit = false;
}
return UMC_OK;
}
MPEG4VideoDecoder::MPEG4VideoDecoder(void)
{
m_IsInit = m_IsInitBase = false;
m_decInfo = new mp4_Info;
m_IsReset = false;
}
MPEG4VideoDecoder::~MPEG4VideoDecoder(void)
{
Close();
delete m_decInfo;
}
Status MPEG4VideoDecoder::ResetSkipCount()
{
if (!m_IsInitBase)
return UMC_ERR_NOT_INITIALIZED;
m_is_skipped_b = m_skipped_fr = m_b_prev = 0;
return UMC_OK;
}
Status MPEG4VideoDecoder::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 MPEG4VideoDecoder::GetNumOfSkippedFrames(void)
{
return m_skipped_fr;
}
Status MPEG4VideoDecoder::Reset(void)
{
if (!m_IsInitBase)
return UMC_ERR_NOT_INITIALIZED;
if (m_IsInit) {
mp4_ResetVOL(m_decInfo);
m_IsReset = true;
m_dec_time_base = -1.0;
m_dec_time_prev = 0.0;
}
return UMC_OK;
}
Status MPEG4VideoDecoder::GetPerformance(Ipp64f *perf)
{
return UMC_ERR_NOT_IMPLEMENTED;
}
mp4_Frame* MPEG4VideoDecoder::GetCurrentFramePtr(void)
{
return m_decInfo->VisualObject.vFrame;
}
Status MPEG4VideoDecoder::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;
}
Status MPEG4VideoDecoder::SetDeblockingParams(bool procPlane0, bool procPlane1, bool procPlane2, Ipp32s THR1, Ipp32s THR2)
{
m_DeblockingProcPlane[0] = procPlane0;
m_DeblockingProcPlane[1] = procPlane1;
m_DeblockingProcPlane[2] = procPlane2;
m_DeblockingTHR1 = THR1;
m_DeblockingTHR2 = THR2;
return UMC_OK;
}
Status MPEG4VideoDecoder::SetDeringingParams(bool procPlane0, bool procPlane1, bool procPlane2)
{
m_DeringingProcPlane[0] = procPlane0;
m_DeringingProcPlane[1] = procPlane1;
m_DeringingProcPlane[2] = procPlane2;
return UMC_OK;
}
Status MPEG4VideoDecoder::PostProcess(mp4_Frame *inout)
{
int w, h, i, j, k, QP, width, height;
IppiSize size;
Ipp8u *pSrc[3], *pDst[3];
int srcPitch[3], dstPitch[3], threshold[6];
QP = m_decInfo->VisualObject.VideoObject.short_video_header ? m_decInfo->VisualObject.VideoObject.VideoObjectPlaneH263.vop_quant : m_decInfo->VisualObject.VideoObject.VideoObjectPlane.quant;
width = (m_decInfo->VisualObject.VideoObject.width + 7) & (~7);
height = (m_decInfo->VisualObject.VideoObject.height + 7) & (~7);
if (m_DeblockingProcPlane[0] || m_DeblockingProcPlane[1] || m_DeblockingProcPlane[2]) {
pSrc[0] = inout->pY;
srcPitch[0] = inout->stepY;
pDst[0] = ppFrame0.pY;
dstPitch[0] = ppFrame0.stepY;
pSrc[1] = inout->pCb;
srcPitch[1] = inout->stepCb;
pDst[1] = ppFrame0.pCb;
dstPitch[1] = ppFrame0.stepCb;
pSrc[2] = inout->pCr;
srcPitch[2] = inout->stepCr;
pDst[2] = ppFrame0.pCr;
dstPitch[2] = ppFrame0.stepCr;
for (k = 0; k < 3; k ++) {
if (m_DeblockingProcPlane[k]) {
size.height = 8;
if (k == 0) {
size.width = width;
h = height >> 3;
w = width >> 3;
} else {
size.width = width >> 1;
h = height >> 4;
w = width >> 4;
}
for (i = 0; i < h; i ++) {
ippiCopy_8u_C1R(pSrc[k], srcPitch[k], pDst[k], dstPitch[k], size);
if (i > 0) {
for (j = 0; j < w; j ++)
ippiFilterDeblocking8x8HorEdge_MPEG4_8u_C1IR(pDst[k] + 8 * j, dstPitch[k], QP, m_DeblockingTHR1, m_DeblockingTHR2);
for (j = 1; j < w; j ++)
ippiFilterDeblocking8x8VerEdge_MPEG4_8u_C1IR(pDst[k] - 8 * dstPitch[k] + 8 * j, dstPitch[k], QP, m_DeblockingTHR1, m_DeblockingTHR2);
}
if (i == h - 1) {
for (j = 1; j < w; j ++)
ippiFilterDeblocking8x8VerEdge_MPEG4_8u_C1IR(pDst[k] + 8 * j, dstPitch[k], QP, m_DeblockingTHR1, m_DeblockingTHR2);
}
pSrc[k] += srcPitch[k] * 8;
pDst[k] += dstPitch[k] * 8;
}
} else {
if (k == 0) {
size.width = width;
size.height = height;
} else {
size.width = width >> 1;
size.height = height >> 1;
}
ippiCopy_8u_C1R(pSrc[k], srcPitch[k], pDst[k], dstPitch[k], size);
}
}
*inout = ppFrame0;
}
if (m_DeringingProcPlane[0] || m_DeringingProcPlane[1] || m_DeringingProcPlane[2]) {
pSrc[0] = inout->pY;
srcPitch[0] = inout->stepY;
pDst[0] = ppFrame1.pY;
dstPitch[0] = ppFrame1.stepY;
if (!m_DeringingProcPlane[0]) {
size.width = width;
size.height = height;
ippiCopy_8u_C1R(pSrc[0], srcPitch[0], pDst[0], dstPitch[0], size);
}
pSrc[1] = inout->pCb;
srcPitch[1] = inout->stepCb;
pDst[1] = ppFrame1.pCb;
dstPitch[1] = ppFrame1.stepCb;
if (!m_DeringingProcPlane[1]) {
size.width = width >> 1;
size.height = height >> 1;
ippiCopy_8u_C1R(pSrc[1], srcPitch[1], pDst[1], dstPitch[1], size);
}
pSrc[2] = inout->pCr;
srcPitch[2] = inout->stepCr;
pDst[2] = ppFrame1.pCr;
dstPitch[2] = ppFrame1.stepCr;
if (!m_DeringingProcPlane[2]) {
size.width = width >> 1;
size.height = height >> 1;
ippiCopy_8u_C1R(pSrc[2], srcPitch[2], pDst[2], dstPitch[2], size);
}
h = inout->mbPerCol;
w = inout->mbPerRow;
for (i = 0; i < h; i ++) {
for (j = 0; j < w; j ++) {
ippiFilterDeringingThreshold_MPEG4_8u_P3R(pSrc[0]+ 16 * j, srcPitch[0], pSrc[1] + 8 * j, srcPitch[1], pSrc[2] + 8 * j, srcPitch[2], threshold);
// copy border macroblocks
if (i == 0 || i == h - 1 || j == 0 || j == w - 1) {
if (m_DeringingProcPlane[0])
ippiCopy16x16_8u_C1R(pSrc[0] + 16 * j, srcPitch[0], pDst[0] + 16 * j, dstPitch[0]);
if (m_DeringingProcPlane[1])
ippiCopy8x8_8u_C1R(pSrc[1] + 8 * j, srcPitch[1], pDst[1] + 8 * j, dstPitch[1]);
if (m_DeringingProcPlane[2])
ippiCopy8x8_8u_C1R(pSrc[2] + 8 * j, srcPitch[2], pDst[2] + 8 * j, dstPitch[2]);
}
if (m_DeringingProcPlane[0]) {
if (i != 0 && j != 0)
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[0] + 16 * j, srcPitch[0], pDst[0] + 16 * j, dstPitch[0], QP, threshold[0]);
if (i != 0 && j != w - 1)
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[0] + 16 * j + 8, srcPitch[0], pDst[0] + 16 * j + 8, dstPitch[0], QP, threshold[1]);
if (i != h - 1 && j != 0)
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[0] + 16 * j + 8 * srcPitch[0], srcPitch[0], pDst[0] + 16 * j + 8 * dstPitch[0], dstPitch[0], QP, threshold[2]);
if (i != h - 1 && j != w - 1)
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[0] + 16 * j + 8 * srcPitch[0] + 8, srcPitch[0], pDst[0] + 16 * j + 8 * dstPitch[0] + 8, dstPitch[0], QP, threshold[3]);
}
if (i != 0 && j != 0 && i != h - 1 && j != w - 1) {
if (m_DeringingProcPlane[1])
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[1] + 8 * j, srcPitch[1], pDst[1] + 8 * j, dstPitch[1], QP, threshold[4]);
if (m_DeringingProcPlane[2])
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[2] + 8 * j, srcPitch[2], pDst[2] + 8 * j, dstPitch[2], QP, threshold[5]);
}
}
pSrc[0] += srcPitch[0] * 16;
pDst[0] += dstPitch[0] * 16;
pSrc[1] += srcPitch[1] * 8;
pDst[1] += dstPitch[1] * 8;
pSrc[2] += srcPitch[2] * 8;
pDst[2] += dstPitch[2] * 8;
}
*inout = ppFrame1;
}
return UMC_OK;
}
} // end namespace UMC
#endif //defined (UMC_ENABLE_MPEG4_VIDEO_DECODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -