📄 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-2007 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::AllocateInitFrame(h263_Frame* pFrame)
{
Status status;
Ipp32s w, h;
Ipp8u *p;
w = (pFrame->mbPerRow + 2 * H263_NUM_EXT_MB) << 4;
h = (pFrame->mbPerCol + 2 * H263_NUM_EXT_MB) << 4;
status = m_pMemoryAllocator->Alloc(&pFrame->mid, w * h + (w * h >> 1), UMC_ALLOC_PERSISTENT);
if (status != UMC_OK)
return status;
p = (Ipp8u*)m_pMemoryAllocator->Lock(pFrame->mid);
ippsSet_8u(0, p, w * h);
ippsSet_8u(128, p + w * h, w * h >> 1);
status = m_pMemoryAllocator->Unlock(pFrame->mid);
if (status != UMC_OK)
return status;
pFrame->stepY = w;
pFrame->stepCb = w >> 1;
pFrame->stepCr = w >> 1;
return UMC_OK;
}
void H263VideoDecoder::LockFrame(h263_Frame* pFrame)
{
Ipp32s w, h;
w = (pFrame->mbPerRow + 2 * H263_NUM_EXT_MB) << 4;
h = (pFrame->mbPerCol + 2 * H263_NUM_EXT_MB) << 4;
pFrame->apY = (Ipp8u*)m_pMemoryAllocator->Lock(pFrame->mid);
pFrame->pY = pFrame->apY + w * 16 + 16;
pFrame->apCb = pFrame->apY + w * h;
w >>= 1;
h >>= 1;
pFrame->pCb = pFrame->apCb + w * 8 + 8;
pFrame->apCr = pFrame->apCb + w * h;
pFrame->pCr = pFrame->apCr + w * 8 + 8;
}
Status H263VideoDecoder::AllocateBuffers()
{
Status status = UMC_OK;
// allocate only frame memory, may be extended for whole buffers
// current frame
status = AllocateInitFrame(&m_decInfo->VideoSequence.cFrame);
if (status != UMC_OK)
return status;
// ref in past frame
status = AllocateInitFrame(&m_decInfo->VideoSequence.rFrame);
if (status != UMC_OK)
return status;
/* not referenced frame (B-part of PB-frame or B-frame) */
status = AllocateInitFrame(&m_decInfo->VideoSequence.nFrame);
if (status != UMC_OK)
return status;
/* not referenced frame (B-part of PB-frame or B-frame) */
status = AllocateInitFrame(&m_decInfo->VideoSequence.bFrame);
if (status != UMC_OK)
return status;
return status;
}
Status H263VideoDecoder::FreeBuffers()
{
Status status = UMC_OK;
Ipp32s i;
if (m_decInfo->VideoSequence.cFrame.mid) {
status = m_pMemoryAllocator->Free(m_decInfo->VideoSequence.cFrame.mid);
if (status != UMC_OK)
return status;
}
if (m_decInfo->VideoSequence.rFrame.mid) {
status = m_pMemoryAllocator->Free(m_decInfo->VideoSequence.rFrame.mid);
if (status != UMC_OK)
return status;
}
if (m_decInfo->VideoSequence.nFrame.mid) {
status = m_pMemoryAllocator->Free(m_decInfo->VideoSequence.nFrame.mid);
if (status != UMC_OK)
return status;
}
if (m_decInfo->VideoSequence.bFrame.mid) {
status = m_pMemoryAllocator->Free(m_decInfo->VideoSequence.bFrame.mid);
if (status != UMC_OK)
return status;
}
for (i = 0; i < H263_MAX_ENH_LAYERS; i++) {
h263_EnhancedLayer *layer = m_decInfo->VideoSequence.enhLayers[i];
if (layer) {
if (layer->c_Frame.mid) {
status = m_pMemoryAllocator->Free(layer->c_Frame.mid);
if (status != UMC_OK)
return status;
}
if (layer->r_Frame.mid) {
status = m_pMemoryAllocator->Free(layer->r_Frame.mid);
if (status != UMC_OK)
return status;
}
if (layer->n_Frame.mid) {
status = m_pMemoryAllocator->Free(layer->n_Frame.mid);
if (status != UMC_OK)
return status;
}
if (layer->a_Frame.mid) {
status = m_pMemoryAllocator->Free(layer->a_Frame.mid);
if (status != UMC_OK)
return status;
}
ippsFree(layer);
m_decInfo->VideoSequence.enhLayers[i] = NULL;
}
}
return status;
}
void H263VideoDecoder::LockBuffers()
{
LockFrame(&m_decInfo->VideoSequence.cFrame);
LockFrame(&m_decInfo->VideoSequence.rFrame);
LockFrame(&m_decInfo->VideoSequence.nFrame);
LockFrame(&m_decInfo->VideoSequence.bFrame);
if (m_decInfo->VideoSequence.aFrame.mid)
LockFrame(&m_decInfo->VideoSequence.aFrame);
}
Status H263VideoDecoder::UnlockBuffers()
{
Status status = UMC_OK;
status = m_pMemoryAllocator->Unlock(m_decInfo->VideoSequence.cFrame.mid);
if (status != UMC_OK)
return status;
status = m_pMemoryAllocator->Unlock(m_decInfo->VideoSequence.rFrame.mid);
if (status != UMC_OK)
return status;
status = m_pMemoryAllocator->Unlock(m_decInfo->VideoSequence.nFrame.mid);
if (status != UMC_OK)
return status;
status = m_pMemoryAllocator->Unlock(m_decInfo->VideoSequence.bFrame.mid);
if (status != UMC_OK)
return status;
if (m_decInfo->VideoSequence.aFrame.mid) {
status = m_pMemoryAllocator->Unlock(m_decInfo->VideoSequence.aFrame.mid);
if (status != UMC_OK)
return status;
}
return status;
}
void H263VideoDecoder::LockEnhancedLayerBuffers(Ipp32s enh_layer_num, Ipp32s ref_layer_num, Ipp32s lockedMask)
{
h263_EnhancedLayer *layer = m_decInfo->VideoSequence.enhLayers[enh_layer_num - 2];
if (!(lockedMask & 4))
LockFrame(&layer->c_Frame);
if (!(lockedMask & 1))
LockFrame(&layer->r_Frame);
if (!(lockedMask & 2))
LockFrame(&layer->n_Frame);
if (!(lockedMask & 8))
LockFrame(&layer->a_Frame);
if (ref_layer_num > 1) {
layer = m_decInfo->VideoSequence.enhLayers[ref_layer_num - 2];
LockFrame(&layer->c_Frame);
LockFrame(&layer->r_Frame);
LockFrame(&layer->n_Frame);
LockFrame(&layer->a_Frame);
}
}
Status H263VideoDecoder::UnlockEnhancedLayerBuffers(Ipp32s enh_layer_num, Ipp32s ref_layer_num)
{
Status status = UMC_OK;
h263_EnhancedLayer *layer = m_decInfo->VideoSequence.enhLayers[enh_layer_num - 2];
if (layer->c_Frame.mid) {
status = m_pMemoryAllocator->Unlock(layer->c_Frame.mid);
if (status != UMC_OK)
return status;
}
if (layer->r_Frame.mid) {
status = m_pMemoryAllocator->Unlock(layer->r_Frame.mid);
if (status != UMC_OK)
return status;
}
if (layer->n_Frame.mid) {
status = m_pMemoryAllocator->Unlock(layer->n_Frame.mid);
if (status != UMC_OK)
return status;
}
if (layer->a_Frame.mid) {
status = m_pMemoryAllocator->Unlock(layer->a_Frame.mid);
if (status != UMC_OK)
return status;
}
if (ref_layer_num > 1) {
layer = m_decInfo->VideoSequence.enhLayers[ref_layer_num - 2];
if (layer->c_Frame.mid) {
status = m_pMemoryAllocator->Unlock(layer->c_Frame.mid);
if (status != UMC_OK)
return status;
}
if (layer->r_Frame.mid) {
status = m_pMemoryAllocator->Unlock(layer->r_Frame.mid);
if (status != UMC_OK)
return status;
}
if (layer->n_Frame.mid) {
status = m_pMemoryAllocator->Unlock(layer->n_Frame.mid);
if (status != UMC_OK)
return status;
}
if (layer->a_Frame.mid) {
status = m_pMemoryAllocator->Unlock(layer->a_Frame.mid);
if (status != UMC_OK)
return status;
}
}
return status;
}
Status H263VideoDecoder::ReAlLockFrame(h263_Frame* pFrame)
{
Ipp32s w, h;
Status status = UMC_OK;
Ipp32s mbPerRow, mbPerCol;
mbPerRow = m_decInfo->VideoSequence.VideoPicture.MacroBlockPerRow;
mbPerCol = m_decInfo->VideoSequence.VideoPicture.MacroBlockPerCol;
if (pFrame->mid) {
status = m_pMemoryAllocator->Unlock(pFrame->mid);
if (status != UMC_OK)
return status;
status = m_pMemoryAllocator->Free(pFrame->mid);
if (status != UMC_OK)
return status;
}
w = (mbPerRow + 2 * H263_NUM_EXT_MB) << 4;
h = (mbPerCol + 2 * H263_NUM_EXT_MB) << 4;
pFrame->mbPerRow = mbPerRow;
pFrame->mbPerCol = mbPerCol;
pFrame->width = m_decInfo->VideoSequence.VideoPicture.width;
pFrame->height = m_decInfo->VideoSequence.VideoPicture.height;
pFrame->stepY = w;
pFrame->stepCb = w >> 1;
pFrame->stepCr = w >> 1;
status = m_pMemoryAllocator->Alloc(&pFrame->mid, w * h + (w * h >> 1), UMC_ALLOC_PERSISTENT);
if (status != UMC_OK)
return status;
pFrame->apY = (Ipp8u*)m_pMemoryAllocator->Lock(pFrame->mid);
ippsSet_8u(0, pFrame->apY, w * h);
pFrame->pY = pFrame->apY + w * 16 + 16;
pFrame->apCb = pFrame->apY + w * h;
ippsSet_8u(128, pFrame->apCb, w * h >> 1);
w >>= 1;
h >>= 1;
pFrame->pCb = pFrame->apCb + w * 8 + 8;
pFrame->apCr = pFrame->apCb + w * h;
pFrame->pCr = pFrame->apCr + w * 8 + 8;
return status;
}
Status H263VideoDecoder::ReAlLockBuffers(Ipp32s resizeMask)
{
Status status = UMC_OK;
// mbinfo realloc
if (resizeMask & 0x100) {
if (m_decInfo->VideoSequence.MBinfo)
ippsFree(m_decInfo->VideoSequence.MBinfo);
m_decInfo->VideoSequence.num_of_MBs = m_decInfo->VideoSequence.VideoPicture.MacroBlockPerCol * m_decInfo->VideoSequence.VideoPicture.MacroBlockPerRow;
m_decInfo->VideoSequence.MBinfo = (h263_MacroBlock*)ippsMalloc_8u(m_decInfo->VideoSequence.num_of_MBs * sizeof(h263_MacroBlock));
if (!m_decInfo->VideoSequence.MBinfo)
return UMC_ERR_ALLOC;
}
if (resizeMask & 1) {
status = ReAlLockFrame(&m_decInfo->VideoSequence.rFrame);
if (status != UMC_OK)
return status;
}
if (resizeMask & 2) {
status = ReAlLockFrame(&m_decInfo->VideoSequence.nFrame);
if (status != UMC_OK)
return status;
}
if (resizeMask & 4) {
status = ReAlLockFrame(&m_decInfo->VideoSequence.bFrame);
if (status != UMC_OK)
return status;
}
if (resizeMask & 8) {
status = ReAlLockFrame(&m_decInfo->VideoSequence.aFrame);
if (status != UMC_OK)
return status;
}
if (resizeMask & 0xF0) {
Ipp32s layer_ind = m_decInfo->VideoSequence.VideoPicture.enh_layer_num - 2;
h263_EnhancedLayer *enh_layer = m_decInfo->VideoSequence.enhLayers[layer_ind];
if (enh_layer == NULL) {
enh_layer = (h263_EnhancedLayer *)ippsMalloc_8u(sizeof(h263_EnhancedLayer));
if (enh_layer == NULL)
return UMC_ERR_ALLOC;
m_decInfo->VideoSequence.enhLayers[layer_ind] = enh_layer;
ippsZero_8u((Ipp8u *)enh_layer, sizeof(h263_EnhancedLayer));
}
if (resizeMask & 0x10) {
status = ReAlLockFrame(&enh_layer->r_Frame);
if (status != UMC_OK)
return status;
}
if (resizeMask & 0x20) {
status = ReAlLockFrame(&enh_layer->n_Frame);
if (status != UMC_OK)
return status;
}
if (resizeMask & 0x40) {
status = ReAlLockFrame(&enh_layer->c_Frame);
if (status != UMC_OK)
return status;
}
if (resizeMask & 0x80) {
status = ReAlLockFrame(&enh_layer->a_Frame);
if (status != UMC_OK)
return status;
}
}
return status;
}
Status H263VideoDecoder::Init(BaseCodecParams *lpInit)
{
Status status = UMC_OK;
VideoDecoderParams *pParam = DynamicCast<VideoDecoderParams> (lpInit);
Close();
if (NULL == pParam)
return UMC_ERR_NULL_PTR;
// create default memory allocator
status = BaseCodec::Init(lpInit);
if (status != UMC_OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -