📄 umc_video_data.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 "umc_video_data.h"
#include "vm_debug.h"
namespace UMC
{
// Number of planes in format description table.
// Number of planes in image can be greater. In this case additional
// planes should be supported by the user with functions SetPlanePointer,
// SetPlanePitch.
enum
{
MAX_PLANE_NUMBER = 4
};
// Color format description structure
struct ColorFormatInfo
{
ColorFormat m_cFormat;
Ipp32s m_iPlanes; // Number of planes
Ipp32s m_iMinBitDepth; // Minimum bitdepth
Ipp32s m_iMinAlign; // Minimal required alignment in bytes
struct {
Ipp32s m_iWidthDiv; // Horizontal downsampling factor
Ipp32s m_iHeightDiv; // Vertical downsampling factor
Ipp32s m_iChannels; // Number of merged channels in the plane
Ipp32s m_iAlignMult; // Alignment value multiplier
} m_PlaneFormatInfo[MAX_PLANE_NUMBER];
};
// Color format description table
static
const
ColorFormatInfo FormatInfo[] =
{
{YV12, 3, 8, 1, {{1, 1, 1, 2}, {2, 2, 1, 1}, {2, 2, 1, 1}}},
{NV12, 2, 8, 2, {{1, 1, 1, 1}, {1, 2, 1, 1}, }},
{YUY2, 1, 8, 2, {{2, 1, 4, 1}, }},
{UYVY, 1, 8, 2, {{2, 1, 4, 1}, }},
{YUV411, 3, 8, 1, {{1, 1, 1, 1}, {4, 1, 1, 1}, {4, 1, 1, 1}}},
{YUV420, 3, 8, 1, {{1, 1, 1, 1}, {2, 2, 1, 1}, {2, 2, 1, 1}}},
{YUV422, 3, 8, 1, {{1, 1, 1, 1}, {2, 1, 1, 1}, {2, 1, 1, 1}}},
{YUV444, 3, 8, 1, {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}},
{YUV_VC1, 3, 8, 1, {{1, 1, 1, 1}, {2, 2, 1, 1}, {2, 2, 1, 1}}},
{Y411, 1, 8, 2, {{4, 1, 6, 1}, }},
{Y41P, 1, 8, 2, {{8, 1, 12, 1}, }},
{RGB32, 1, 8, 1, {{1, 1, 4, 1}, }},
{RGB24, 1, 8, 4, {{1, 1, 3, 1}, }},
{RGB565, 1, 16, 2, {{1, 1, 1, 1}, }},
{RGB555, 1, 16, 2, {{1, 1, 1, 1}, }},
{RGB444, 1, 16, 2, {{1, 1, 1, 1}, }},
{GRAY, 1, 8, 1, {{1, 1, 1, 1}, }},
{GRAYA, 2, 8, 1, {{1, 1, 1, 1}, {1, 1, 1, 1}}},
{YUV420A, 4, 8, 1, {{1, 1, 1, 1}, {2, 2, 1, 1}, {2, 2, 1, 1}, {1, 1, 1, 1}}},
{YUV422A, 4, 8, 1, {{1, 1, 1, 1}, {2, 1, 1, 1}, {2, 1, 1, 1}, {1, 1, 1, 1}}},
{YUV444A, 4, 8, 1, {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}},
{YVU9, 3, 8, 1, {{1, 1, 1, 1}, {4, 4, 1, 1}, {4, 4, 1, 1}}}
};
// Number of entries in the FormatInfo table
static
const
Ipp32s iNumberOfFormats = sizeof(FormatInfo) / sizeof(FormatInfo[0]);
// returns pointer to color format description table for cFormat
// or NULL if cFormat is not described (unknown color format).
static
const
ColorFormatInfo *GetColorFormatInfo(ColorFormat cFormat)
{
const ColorFormatInfo *pReturn = NULL;
Ipp32s i;
// find required format
for (i = 0; i < iNumberOfFormats; i += 1)
{
if (FormatInfo[i].m_cFormat == cFormat)
{
pReturn = FormatInfo + i;
break;
}
}
return pReturn;
} // ColorFormatInfo *GetColorFormatInfo(ColorFormat cFormat)
// Initialization to undefined image type
VideoData::VideoData(void)
{
m_iAlignment = 1;
m_pPlaneData = NULL;
m_iPlanes = 0;
m_ippSize.width = 0;
m_ippSize.height = 0;
m_ColorFormat = NONE;
m_picStructure = PS_FRAME;
// set square pixel
m_iHorzAspect =
m_iVertAspect = 1;
m_pbAllocated = NULL;
} // VideoData::VideoData(void)
VideoData::~VideoData(void)
{
Close();
} // VideoData::~VideoData(void)
// Release all possessed memory
Status VideoData::Close(void)
{
if (m_pPlaneData)
delete [] m_pPlaneData;
m_pPlaneData = NULL;
m_iPlanes = 0;
return ReleaseImage();
} // Status VideoData::Close(void)
// Release image memory if it was owned
Status VideoData::ReleaseImage(void)
{
Ipp32s i;
for (i = 0; i < m_iPlanes; i++)
m_pPlaneData[i].m_pPlane = NULL;
if (m_pbAllocated)
delete [] m_pbAllocated;
m_pbAllocated = NULL;
return MediaData::Close();
} // Status VideoData::ReleaseImage(void)
// Initializes image dimensions and bitdepth.
// Has to be followed by SetColorFormat call.
// Planes' information is initialized to invalid values
Status VideoData::Init(Ipp32s iWidth,
Ipp32s iHeight,
Ipp32s iPlanes,
Ipp32s iBitDepth)
{
Ipp32s i;
// check error(s)
if ((0 >= iWidth) ||
(0 >= iHeight) ||
(0 >= iPlanes) ||
(8 > iBitDepth))
return UMC_ERR_INVALID_STREAM;
// release object before initialization
Close();
// allocate plane info
m_pPlaneData = new PlaneInfo[iPlanes];
if (NULL == m_pPlaneData)
return UMC_ERR_ALLOC;
// fill plane info
for (i = 0; i < iPlanes; i++)
{
m_pPlaneData[i].m_iSamples = 1;
m_pPlaneData[i].m_iSampleSize = (iBitDepth+7)>>3;
m_pPlaneData[i].m_iBitDepth = iBitDepth;
m_pPlaneData[i].m_pPlane = NULL;
m_pPlaneData[i].m_nMemSize = 0;
// we can't set pitch without align value
m_pPlaneData[i].m_nPitch = 0;
m_pPlaneData[i].m_nOffset = 0;
// can't assign dimension to unknown planes
m_pPlaneData[i].m_ippSize.width = 0;
m_pPlaneData[i].m_ippSize.height = 0;
}
m_iPlanes = iPlanes;
m_ippSize.width = iWidth;
m_ippSize.height = iHeight;
return UMC_OK;
} // Status VideoData::Init(Ipp32s iWidth,
// Completely sets image information, without allocation or linking to
// image memory.
Status VideoData::Init(Ipp32s iWidth,
Ipp32s iHeight,
ColorFormat cFormat,
Ipp32s iBitDepth)
{
Status umcRes;
const ColorFormatInfo* pFormat;
pFormat = GetColorFormatInfo(cFormat);
if(NULL == pFormat)
return UMC_ERR_INVALID_STREAM;
// allocate planes
if(iBitDepth == 0)
iBitDepth = pFormat->m_iMinBitDepth;
umcRes = Init(iWidth, iHeight, pFormat->m_iPlanes, iBitDepth);
if (UMC_OK != umcRes)
return umcRes;
// set color format and
// correct width & height for planes
umcRes = SetColorFormat(cFormat);
if (UMC_OK != umcRes)
return umcRes;
return UMC_OK;
} // Status VideoData::Init(Ipp32s iWidth,
// Sets or change Color format information for image, only when it has
// specified size, number of planes and bitdepth. Number of planes in cFormat must
// be not greater than specified in image.
Status VideoData::SetColorFormat(ColorFormat cFormat)
{
Ipp32s i;
const ColorFormatInfo *pFormat;
// check error(s)
pFormat = GetColorFormatInfo(cFormat);
if (NULL == pFormat)
return UMC_ERR_INVALID_STREAM;
if (m_iPlanes < pFormat->m_iPlanes)
return UMC_ERR_INVALID_STREAM;
m_ColorFormat = cFormat;
m_pPlaneData[0].m_nOffset = 0;
// set correct width & height to planes
for (i = 0; i < m_iPlanes; i += 1)
{
Ipp32s align, bpp;
if(i>0) {
m_pPlaneData[i].m_nOffset =
m_pPlaneData[i-1].m_nOffset + m_pPlaneData[i-1].m_nMemSize;
}
if (i < pFormat->m_iPlanes)
{
m_pPlaneData[i].m_iWidthDiv = pFormat->m_PlaneFormatInfo[i].m_iWidthDiv;
m_pPlaneData[i].m_iHeightDiv = pFormat->m_PlaneFormatInfo[i].m_iHeightDiv;
m_pPlaneData[i].m_iSamples = pFormat->m_PlaneFormatInfo[i].m_iChannels;
} else {
m_pPlaneData[i].m_iWidthDiv = 1;
m_pPlaneData[i].m_iHeightDiv = 1;
m_pPlaneData[i].m_iSamples = 1;
}
if (m_pPlaneData[i].m_iWidthDiv != 1) {
int sz = m_pPlaneData[i].m_iWidthDiv;
m_pPlaneData[i].m_ippSize.width = (m_ippSize.width + sz - 1) / sz;
} else {
m_pPlaneData[i].m_ippSize.width = m_ippSize.width;
}
if (m_pPlaneData[i].m_iHeightDiv != 1) {
int sz = m_pPlaneData[i].m_iHeightDiv;
m_pPlaneData[i].m_ippSize.height = (m_ippSize.height + sz - 1) / sz;
} else {
m_pPlaneData[i].m_ippSize.height = m_ippSize.height;
}
bpp = m_pPlaneData[i].m_iSampleSize * m_pPlaneData[i].m_iSamples;
align = IPP_MAX(m_iAlignment, bpp);
if (i < pFormat->m_iPlanes) {
// sometimes dimension of image may be not aligned to native size
align = IPP_MAX(align, pFormat->m_iMinAlign);
align *= pFormat->m_PlaneFormatInfo[i].m_iAlignMult;
}
m_pPlaneData[i].m_nPitch =
align_value<size_t>(m_pPlaneData[i].m_ippSize.width * bpp, align);
m_pPlaneData[i].m_nMemSize = m_pPlaneData[i].m_nPitch * m_pPlaneData[i].m_ippSize.height;
}
// special case, can't be completely covered by format table
//if(cFormat == YV12) { // V than U
// size_t tmp = m_pPlaneData[1].m_nOffset;
// m_pPlaneData[1].m_nOffset = m_pPlaneData[2].m_nOffset;
// m_pPlaneData[2].m_nOffset = tmp;
//}
// for complexer cases, such as IMC2 or IMC4, need more manual changes here
return UMC_OK;
} // Status VideoData::SetColorFormat(ColorFormat cFormat)
// Set common Alignment
Status VideoData::SetAlignment(Ipp32s iAlignment)
{
// check alignment
Ipp32s i;
if(iAlignment <= 0)
return UMC_ERR_INVALID_STREAM;
for (i = 1; i < (1 << 16); i <<= 1) {
if (i & iAlignment) {
m_iAlignment = i;
break; // stop at last nonzero bit
}
}
if (i != iAlignment)
return UMC_WRN_INVALID_STREAM;
return UMC_OK;
}
// Allocates memory according to existing information in VideoData and given alignment
// If image memory was already allocated it is released.
// return UMC_OK on success, UMC_ERR_INVALID_STREAM if image is improperly described
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -