📄 umc_vc1_enc_planes.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) 2007 Intel Corporation. All Rights Reserved.
//
//
// VC-1 (VC1) encoder, work with planes
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_VC1_VIDEO_ENCODER)
#include "ippvc.h"
#include "ippi.h"
#include "umc_vc1_enc_def.h"
#include "umc_vc1_enc_common.h"
#include "umc_vc1_enc_debug.h"
#include "umc_vc1_enc_planes.h"
namespace UMC_VC1_ENCODER
{
UMC::Status Frame::Init(Ipp32u w, Ipp32u h, Ipp32u paddingSize)
{
Ipp32u wMB = (w+15)>>4;
Ipp32u hMB = (h+15)>>4;
Close();
m_widthYPlane = w;
m_widthUVPlane = w>>1;
m_heightYPlane = h;
m_heightUVPlane = h>>1;
m_paddingSize = paddingSize;
m_stepY = wMB*VC1_ENC_LUMA_SIZE + 2*m_paddingSize;
m_stepUV= wMB*VC1_ENC_CHROMA_SIZE + m_paddingSize;
//Y
if(m_pMemoryAllocator->Alloc(&m_YFrameMemID,
m_stepY * (hMB*VC1_ENC_LUMA_SIZE + 2*m_paddingSize) +32,
UMC::UMC_ALLOC_PERSISTENT, 16) != UMC::UMC_OK )
return UMC::UMC_ERR_ALLOC;
m_pYFrame = (Ipp8u*)m_pMemoryAllocator->Lock(m_YFrameMemID);
//U
if(m_pMemoryAllocator->Alloc(&m_UFrameMemID,
m_stepUV * (hMB*VC1_ENC_CHROMA_SIZE+ m_paddingSize)+32,
UMC::UMC_ALLOC_PERSISTENT, 16) != UMC::UMC_OK )
return UMC::UMC_ERR_ALLOC;
m_pUFrame = (Ipp8u*)m_pMemoryAllocator->Lock(m_UFrameMemID);
//V
if(m_pMemoryAllocator->Alloc(&m_VFrameMemID,
m_stepUV * (hMB*VC1_ENC_CHROMA_SIZE+ m_paddingSize)+32,
UMC::UMC_ALLOC_PERSISTENT, 16) != UMC::UMC_OK )
return UMC::UMC_ERR_ALLOC;
m_pVFrame = (Ipp8u*)m_pMemoryAllocator->Lock(m_VFrameMemID);
m_pYPlane = UMC::align_pointer<Ipp8u*>( m_pYFrame + m_stepY*m_paddingSize + m_paddingSize);
m_pUPlane = UMC::align_pointer<Ipp8u*>( m_pUFrame + m_stepUV*(m_paddingSize>>1) + (m_paddingSize>>1));
m_pVPlane = UMC::align_pointer<Ipp8u*>( m_pVFrame + m_stepUV*(m_paddingSize>>1) + (m_paddingSize>>1));
return UMC::UMC_OK;
}
void Frame::Close()
{
if(m_pMemoryAllocator)
{
m_pMemoryAllocator->Unlock(m_YFrameMemID);
m_pMemoryAllocator->Unlock(m_UFrameMemID);
m_pMemoryAllocator->Unlock(m_VFrameMemID);
if(m_bOwnAllocator == true)
{
m_pMemoryAllocator->Free(m_YFrameMemID);
m_pMemoryAllocator->Free(m_UFrameMemID);
m_pMemoryAllocator->Free(m_VFrameMemID);
}
}
m_YFrameMemID = (UMC::MemID)-1;
m_UFrameMemID = (UMC::MemID)-1;
m_VFrameMemID = (UMC::MemID)-1;
m_pYFrame = 0;
m_pUFrame = 0;
m_pVFrame = 0;
m_stepY = 0;
m_stepUV = 0;
m_pYPlane = 0;
m_pUPlane = 0;
m_pVPlane = 0;
m_widthYPlane = 0;
m_widthUVPlane = 0;
m_heightYPlane = 0;
m_heightUVPlane = 0;
m_paddingSize = 0;
m_bTaken = false;
}
UMC::Status Frame::PadFrameProgressive()
{
Ipp32u rightY = (((m_widthYPlane + 15)>>4)<<4) - m_widthYPlane + m_paddingSize;
Ipp32u bottomY = (((m_heightYPlane + 15)>>4)<<4) - m_heightYPlane + m_paddingSize;
Ipp32u upperY = m_paddingSize;
Ipp32u leftY = m_paddingSize;
Ipp32u rightUV = rightY >>1;
Ipp32u bottomUV = bottomY>>1;
Ipp32u upperUV = upperY >>1;
Ipp32u leftUV = leftY >>1;
Ipp8u *pY = 0, *pU = 0, *pV = 0;
Ipp32u i;
// upper
pY = m_pYPlane;
pU = m_pUPlane;
pV = m_pVPlane;
for (i=0; i<upperY;i++ )
{
memcpy(pY - m_stepY, pY , m_widthYPlane);
pY -= m_stepY;
}
for (i=0; i<upperUV;i++ )
{
memcpy(pU - m_stepUV, pU , m_widthUVPlane);
memcpy(pV - m_stepUV, pV , m_widthUVPlane);
pU -= m_stepUV;
pV -= m_stepUV;
}
// bottom
pY = m_pYPlane + (m_heightYPlane - 1)*m_stepY;
pU = m_pUPlane + (m_heightUVPlane - 1)*m_stepUV;
pV = m_pVPlane + (m_heightUVPlane - 1)*m_stepUV;
for (i=0; i<bottomY;i++ )
{
memcpy(pY + m_stepY, pY , m_widthYPlane);
pY += m_stepY;
}
for (i=0; i<bottomUV;i++ )
{
memcpy(pU + m_stepUV, pU , m_widthUVPlane);
memcpy(pV + m_stepUV, pV , m_widthUVPlane);
pU += m_stepUV;
pV += m_stepUV;
}
// left
pY = m_pYPlane - m_stepY *upperY;
pU = m_pUPlane - m_stepUV*upperUV;
pV = m_pVPlane - m_stepUV*upperUV;
for (i=0; i<m_heightYPlane+upperY+bottomY; i++)
{
memset(pY-leftY,pY[0],leftY);
pY += m_stepY;
}
for (i=0; i<m_heightUVPlane+upperUV+bottomUV; i++)
{
memset(pU-leftUV,pU[0],leftUV);
memset(pV-leftUV,pV[0],leftUV);
pU += m_stepUV;
pV += m_stepUV;
}
//right
pY = m_pYPlane - m_stepY*upperY + m_widthYPlane - 1;
pU = m_pUPlane - m_stepUV*upperUV+ m_widthUVPlane - 1;
pV = m_pVPlane - m_stepUV*upperUV+ m_widthUVPlane - 1;
for (i=0; i<m_heightYPlane+upperY+bottomY; i++)
{
memset(pY+1,pY[0],rightY);
pY += m_stepY;
}
for (i=0; i<m_heightUVPlane+upperUV+bottomUV; i++)
{
memset(pU+1,pU[0],rightUV);
memset(pV+1,pV[0],rightUV);
pU += m_stepUV;
pV += m_stepUV;
}
return UMC::UMC_OK;
}
UMC::Status Frame::PadPlaneProgressive()
{
Ipp32u rightY = (((m_widthYPlane + 15)>>4)<<4) - m_widthYPlane ;
Ipp32u bottomY = (((m_heightYPlane + 15)>>4)<<4) - m_heightYPlane;
Ipp32u rightUV = rightY >>1;
Ipp32u bottomUV = bottomY>>1;
Ipp8u *pY = 0, *pU = 0, *pV = 0;
Ipp32u i;
// bottom
pY = m_pYPlane + (m_heightYPlane - 1)*m_stepY;
pU = m_pUPlane + (m_heightUVPlane - 1)*m_stepUV;
pV = m_pVPlane + (m_heightUVPlane - 1)*m_stepUV;
for (i=0; i<bottomY;i++ )
{
memcpy(pY + m_stepY, pY , m_widthYPlane);
pY += m_stepY;
}
for (i=0; i<bottomUV;i++ )
{
memcpy(pU + m_stepUV, pU , m_widthUVPlane);
memcpy(pV + m_stepUV, pV , m_widthUVPlane);
pU += m_stepUV;
pV += m_stepUV;
}
//right
pY = m_pYPlane + m_widthYPlane - 1;
pU = m_pUPlane + m_widthUVPlane - 1;
pV = m_pVPlane + m_widthUVPlane - 1;
for (i=0; i<m_heightYPlane+bottomY; i++)
{
memset(pY+1,pY[0],rightY);
pY += m_stepY;
}
for (i=0; i<m_heightUVPlane+bottomUV; i++)
{
memset(pU+1,pU[0],rightUV);
memset(pV+1,pV[0],rightUV);
pU += m_stepUV;
pV += m_stepUV;
}
return UMC::UMC_OK;
}
UMC::Status Frame::CopyPlane ( Ipp8u* pYPlane, Ipp32u stepY,
Ipp8u* pUPlane, Ipp32u stepU,
Ipp8u* pVPlane, Ipp32u stepV,
ePType pictureType)
{
IppiSize sizeLuma = {m_widthYPlane, m_heightYPlane};
IppiSize sizeChroma = {m_widthUVPlane,m_heightUVPlane};
IPP_STAT_START_TIME(m_IppStat->IppStartTime);
ippiCopy_8u_C1R(pYPlane,stepY, m_pYPlane,m_stepY, sizeLuma);
ippiCopy_8u_C1R(pUPlane,stepU,m_pUPlane,m_stepUV, sizeChroma);
ippiCopy_8u_C1R(pVPlane,stepV,m_pVPlane,m_stepUV, sizeChroma);
IPP_STAT_END_TIME(m_IppStat->IppStartTime, m_IppStat->IppEndTime, m_IppStat->IppTotalTime);
m_bTaken = true;
m_pictureType = pictureType;
return UMC::UMC_OK;
}
void Frame::SetMemoryAllocator(UMC::MemoryAllocator *pMemoryAllocator, bool bOwnAllocator)
{
m_pMemoryAllocator = pMemoryAllocator;
m_bOwnAllocator = bOwnAllocator;
};
//////////////////////////////////////////////////////////////////////////////////////
UMC::Status BufferedFrames::Init (Ipp32u w, Ipp32u h, Ipp32u paddingSize, Ipp32u n)
{
Ipp32u i;
UMC::Status err = UMC::UMC_OK;
Close();
m_pFrames = new Frame[n];
if (!m_pFrames)
return UMC::UMC_ERR_ALLOC;
m_bufferSize = n;
for (i = 0; i < n ; i++)
{
err = m_pFrames[i].Init (w,h,paddingSize);
if (err != UMC::UMC_OK)
return err;
}
return err;
}
void BufferedFrames::Close ()
{
if (m_pFrames)
{
delete [] m_pFrames;
m_pFrames = 0;
}
m_bufferSize = 0;
m_nBuffered = 0;
m_currFrameIndex = 0;
m_bClosed = false;
}
UMC::Status BufferedFrames::SaveFrame ( Ipp8u* pYPlane, Ipp32u stepY,
Ipp8u* pUPlane, Ipp32u stepU,
Ipp8u* pVPlane, Ipp32u stepV )
{
if (m_currFrameIndex)
{
// frames from prev. seq. - ERROR;
return UMC::UMC_ERR_FAILED;
}
if (m_nBuffered < m_bufferSize )
{
m_pFrames[m_nBuffered].CopyPlane(pYPlane,stepY,pUPlane,stepU,pVPlane,stepV);
m_bClosed = false;
m_nBuffered++;
return UMC::UMC_OK;
}
else
{
return UMC::UMC_ERR_NOT_ENOUGH_BUFFER;
}
};
UMC::Status BufferedFrames::GetFrame (Frame** currFrame)
{
*currFrame = 0;
if (!m_bClosed)
{
//sequence isn't closed - ERROR;
return UMC::UMC_ERR_FAILED;
}
if (m_nBuffered)
{
*currFrame = &(m_pFrames[m_currFrameIndex]);
m_nBuffered --;
m_currFrameIndex = (m_nBuffered) ? (m_currFrameIndex++) : 0;
return UMC::UMC_OK;
}
else
{
return UMC::UMC_ERR_NOT_ENOUGH_DATA;
}
}
UMC::Status BufferedFrames::GetReferenceFrame (Frame** currFrame)
{
Ipp32u index = 0;
*currFrame = 0;
if (m_bClosed)
{
//sequence is closed - ERROR;
return UMC::UMC_ERR_FAILED;
}
if (m_nBuffered)
{
index = m_currFrameIndex + m_nBuffered - 1;
*currFrame = &(m_pFrames[m_currFrameIndex]);
m_bClosed = true;
m_nBuffered -- ;
m_currFrameIndex = (m_nBuffered) ? m_currFrameIndex : 0;
return UMC::UMC_OK;
}
else
{
return UMC::UMC_ERR_NOT_ENOUGH_DATA;
}
}
UMC::Status BufferedFrames::ReferenceFrame()
{
if (m_currFrameIndex)
{
return UMC::UMC_ERR_FAILED;
}
if (m_nBuffered)
{
m_bClosed = true;
}
return UMC::UMC_OK;
}
}
#endif // defined (UMC_ENABLE_VC1_VIDEO_ENCODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -