📄 umc_video_data.cpp
字号:
Status VideoData::Alloc()
{
size_t nSize;
// Release previous buffer
ReleaseImage();
// get size of buffer to allocate
nSize = GetMappingSize();
if (0 == nSize)
return UMC_ERR_INVALID_STREAM;
// allocate buffer
m_pbAllocated = new Ipp8u[nSize + m_iAlignment - 1];
if (NULL == m_pbAllocated)
return UMC_ERR_ALLOC;
// set pointer to image
return SetBufferPointer(m_pbAllocated, nSize);
} // Status VideoData::Alloc()
// Links to provided image memory
// Image must be described before
Status VideoData::SetBufferPointer(Ipp8u *pbBuffer, size_t nSize)
{
Ipp32s i;
size_t mapsize;
Ipp8u *ptr = align_pointer<Ipp8u *>(pbBuffer, m_iAlignment);
// check error(s)
if (NULL == m_pPlaneData) {
SetDataSize(0);
return UMC_ERR_FAILED;
}
mapsize = GetMappingSize();
if (nSize < mapsize) {
SetDataSize(0);
return UMC_ERR_NOT_ENOUGH_BUFFER;
}
// set new plane pointers
for(i=0; i<m_iPlanes; i++) {
m_pPlaneData[i].m_pPlane = ptr + m_pPlaneData[i].m_nOffset;
}
// call parent class methods
MediaData::SetBufferPointer(pbBuffer, nSize);
// set valid data size
SetDataSize(mapsize + (ptr - pbBuffer));
MoveDataPointer(ptr - pbBuffer);
return UMC_OK;
} // Status VideoData::SetBufferPointer(Ipp8u *pbBuffer, size_t nSize)
// Returns required image memory size according to alignment and current image description
size_t VideoData::GetMappingSize()
{
Ipp32s i;
size_t size = 0;
UMC_CHECK(m_pPlaneData, 0);
for (i = 0; i < m_iPlanes; i++) {
size += m_pPlaneData[i].m_nMemSize;
}
return size;
} // size_t VideoData::GetMappingSize(Ipp32s iAlignment)
// Set pointer for specified plane. Should be used for additional planes,
// or when image layout is different.
Status VideoData::SetPlanePointer(void *pDest, Ipp32s iPlaneNumber)
{
// check error(s)
if ((m_iPlanes <= iPlaneNumber) ||
(0 > iPlaneNumber) ||
(NULL == m_pPlaneData))
return UMC_ERR_FAILED;
m_pPlaneData[iPlaneNumber].m_pPlane = (Ipp8u *) pDest;
return UMC_OK;
} // Status VideoData::SetPlanePointer(void *pDest, Ipp32s iPlaneNumber)
// Set pitch for specified plane. Should be used for additional planes,
// or when image layout is different.
Status VideoData::SetPlanePitch(size_t nPitch, Ipp32s iPlaneNumber)
{
// check error(s)
if ((m_iPlanes <= iPlaneNumber) ||
(0 > iPlaneNumber) ||
(NULL == m_pPlaneData))
return UMC_ERR_FAILED;
m_pPlaneData[iPlaneNumber].m_nPitch = nPitch;
m_pPlaneData[iPlaneNumber].m_nMemSize = nPitch * m_pPlaneData[iPlaneNumber].m_ippSize.height;
return UMC_OK;
} // Status VideoData::SetPlanePitch(size_t nPitch, Ipp32s iPlaneNumber)
// Set bitdepth for specified plane, usually additional or when bitdepth differs
// for main planes
Status VideoData::SetPlaneBitDepth(Ipp32s iBitDepth, Ipp32s iPlaneNumber)
{
// check error(s)
if ((m_iPlanes <= iPlaneNumber) ||
(0 > iPlaneNumber) ||
(NULL == m_pPlaneData))
return UMC_ERR_FAILED;
m_pPlaneData[iPlaneNumber].m_iBitDepth = iBitDepth;
if(m_pPlaneData[iPlaneNumber].m_iSampleSize*8 < iBitDepth)
m_pPlaneData[iPlaneNumber].m_iSampleSize = (iBitDepth+7)>>3;
return UMC_OK;
} // Status VideoData::SetPlaneBitDepth(Ipp32s iBitDepth, Ipp32s iPlaneNumber)
// Set sample size for specified plane, usually additional or when bitdepth differs
// for main planes
Status VideoData::SetPlaneSampleSize(Ipp32s iSampleSize, Ipp32s iPlaneNumber)
{
// check error(s)
if ((m_iPlanes <= iPlaneNumber) ||
(0 > iPlaneNumber) ||
(NULL == m_pPlaneData))
return UMC_ERR_FAILED;
m_pPlaneData[iPlaneNumber].m_iSampleSize = iSampleSize;
if(iSampleSize*8 < m_pPlaneData[iPlaneNumber].m_iBitDepth)
m_pPlaneData[iPlaneNumber].m_iBitDepth = iSampleSize*8;
return UMC_OK;
} // Status VideoData::SetPlaneSampleSize(Ipp32s iSampleSize, Ipp32s iPlaneNumber)
// Links plane pointers to surface using provided pitch.
// All pitches and plane info are updated according to current
// color format.
// Supposes no gaps between planes.
Status VideoData::SetSurface(void* ptr, size_t nPitch)
{
Status ret;
size_t size = 0;
int i;
// check error(s)
UMC_CHECK(ptr, UMC_ERR_NULL_PTR);
UMC_CHECK(m_pPlaneData, UMC_ERR_NOT_INITIALIZED);
if(nPitch == 0) // use current
nPitch = m_pPlaneData[0].m_nPitch;
m_pPlaneData[0].m_nOffset = 0;
for (i = 0; i < m_iPlanes; i++) {
m_pPlaneData[i].m_nPitch = nPitch;
if (i > 0) {
m_pPlaneData[i].m_nPitch *= m_pPlaneData[i].m_iSamples*m_pPlaneData[0].m_iWidthDiv;
m_pPlaneData[i].m_nPitch /= m_pPlaneData[i].m_iWidthDiv*m_pPlaneData[0].m_iSamples;
m_pPlaneData[i].m_nOffset = m_pPlaneData[i - 1].m_nOffset + m_pPlaneData[i - 1].m_nMemSize;
}
m_pPlaneData[i].m_pPlane = (Ipp8u*)ptr + m_pPlaneData[i].m_nOffset;
m_pPlaneData[i].m_nMemSize = m_pPlaneData[i].m_nPitch * m_pPlaneData[i].m_ippSize.height;
size += m_pPlaneData[i].m_nMemSize;
}
ret = MediaData::SetBufferPointer((Ipp8u*)ptr, size);
ret = MediaData::SetDataSize(size);
return ret;
}
#define PITCH_PREC 8
// Calculate pitch from mapping size
size_t VideoData::GetPitchFromMappingSize(size_t mappingSize)
{
size_t size = 0;
int i;
// check error(s)
UMC_CHECK(m_pPlaneData, 0);
// calculate mapping size for pitch equal to (1 << PITCH_PREC)
size = m_pPlaneData[0].m_ippSize.height << PITCH_PREC;
for (i = 1; i < m_iPlanes; i++) {
size_t plane_size = m_pPlaneData[i].m_ippSize.height << PITCH_PREC;
plane_size *= m_pPlaneData[i].m_iSamples*m_pPlaneData[0].m_iWidthDiv;
plane_size /= m_pPlaneData[i].m_iWidthDiv*m_pPlaneData[0].m_iSamples;
size += plane_size;
}
UMC_CHECK(size, 0);
// calculate real pitch
return ((mappingSize << PITCH_PREC)/size);
}
Status VideoData::ConvertPictureStructure(PictureStructure newPicStructure)
{
PictureStructure curr = (PictureStructure)(m_picStructure & PS_FRAME);
int k;
vm_debug_trace2(VM_DEBUG_VERBOSE, VM_STRING("VideoData::ConvertPictureStructure %d->%d\n"), curr, newPicStructure);
if (curr == PS_FRAME && newPicStructure == PS_TOP_FIELD) {
m_ippSize.height >>= 1;
for (k = 0; k < m_iPlanes; k++) {
m_pPlaneData[k].m_ippSize.height >>= 1;
m_pPlaneData[k].m_nPitch <<= 1;
}
curr = PS_TOP_FIELD;
}
if (curr == PS_TOP_FIELD && newPicStructure == PS_BOTTOM_FIELD) {
for (k = 0; k < m_iPlanes; k++) {
m_pPlaneData[k].m_pPlane += (m_pPlaneData[k].m_nPitch >> 1);
}
curr = PS_BOTTOM_FIELD;
}
if (curr == PS_BOTTOM_FIELD && (newPicStructure == PS_TOP_FIELD || newPicStructure == PS_FRAME)) {
for (k = 0; k < m_iPlanes; k++) {
m_pPlaneData[k].m_pPlane -= (m_pPlaneData[k].m_nPitch >> 1);
}
curr = PS_TOP_FIELD;
}
if (curr == PS_TOP_FIELD && newPicStructure == PS_FRAME) {
m_ippSize.height <<= 1;
for (k = 0; k < m_iPlanes; k++) {
m_pPlaneData[k].m_ippSize.height <<= 1;
m_pPlaneData[k].m_nPitch >>= 1;
}
curr = PS_FRAME;
}
return SetPictureStructure(curr /*| (m_picStructure &~ PS_FRAME)*/);
}
// fills PlaneInfo structure
Status VideoData::GetPlaneInfo(PlaneInfo* pInfo, Ipp32s iPlaneNumber)
{
// check error(s)
if (NULL == pInfo)
return UMC_ERR_NULL_PTR;
if ((m_iPlanes <= iPlaneNumber) ||
(0 > iPlaneNumber) ||
(NULL == m_pPlaneData))
return UMC_ERR_FAILED;
*pInfo = m_pPlaneData[iPlaneNumber];
return UMC_OK;
} // Status VideoData::GetPlaneInfo(PlaneInfo* pInfo, Ipp32s iPlaneNumber)
// converts display aspect ratio to pixel AR
// or vise versa with exchanged width and height
Status DARtoPAR(Ipp32s width, Ipp32s height, Ipp32s dar_h, Ipp32s dar_v,
Ipp32s *par_h, Ipp32s *par_v)
{
// (width*par_h) / (height*par_v) == dar_h/dar_v =>
// par_h / par_v == dar_h * height / (dar_v * width)
Ipp32s simple_tab[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};
Ipp32s i, denom;
// suppose no overflow of 32s
Ipp32s h = dar_h * height;
Ipp32s v = dar_v * width;
// remove common multipliers
while( ((h|v)&1) == 0 ) {
h>>=1;
v>>=1;
}
for(i=0;i<sizeof(simple_tab)/sizeof(simple_tab[0]);i++) {
denom = simple_tab[i];
while(h%denom==0 && v%denom==0) {
v /= denom;
h /= denom;
}
if(v<=denom || h<=denom)
break;
}
*par_h = h;
*par_v = v;
// can don't reach minimum, no problem
if(i<sizeof(simple_tab)/sizeof(simple_tab[0]))
return UMC_WRN_INVALID_STREAM;
return UMC_OK;
}
void VideoData::operator=(VideoData &par)
{
PlaneInfo *PlaneData = m_pPlaneData;
if(m_iPlanes < par.m_iPlanes)
{
Close();
PlaneData = new PlaneInfo[par.m_iPlanes];
} else {
ReleaseImage();
}
memcpy(PlaneData, par.m_pPlaneData, par.m_iPlanes*sizeof(PlaneInfo));
memcpy(this, &par, sizeof(VideoData));
m_pPlaneData = PlaneData;
m_pbAllocated = NULL;
// from MediaData
m_bMemoryAllocated = false;
m_pts_start = par.m_pts_start;
m_pts_end = par.m_pts_end;
m_FrameType = par.m_FrameType;
}
} // end namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -