📄 umc_avs_dec_pic.cpp
字号:
// initialize picture structure
//
ResetPicture(&m_seqHeader,
(void **) pPlanes8u,
dimReq.width,
(isFramePic) ? AVS_FRAME : AVS_FIELD_PAIR);
// initialize field just in case of PAFF
m_Fields[0].ResetPicture(&m_seqHeader,
(void **) pPlanes8u,
dimReq.width,
AVS_UPPER_FIELD);
m_Fields[0].m_picHeader = m_picHeader;
m_Fields[1].ResetPicture(&m_seqHeader,
(void **) pPlanes8u,
dimReq.width,
AVS_LOWER_FIELD);
m_Fields[1].m_picHeader = m_picHeader;
// second field of I frame is always P frame
if (AVS_I_PICTURE == m_picHeader.PictureType)
{
m_Fields[1].m_picHeader.PictureType = AVS_P_PICTURE;
}
//
// assign MB info's and planes to slices
//
pSlice = m_Slices.GetHead();
pPrev = NULL;
pMemory = m_MemoryPieces.GetHead();
while (pSlice)
{
AVS_PICTURE_HEADER *pPicHeader = &m_picHeader;
Ipp32s fieldNum = 0;
Status umcRes;
// get appropriate picture header
if (false == isFramePic)
{
fieldNum = GetFieldNum(pMemory->GetBuffer(),
&m_seqHeader,
&m_picHeader);
pPicHeader = &(m_Fields[fieldNum].m_picHeader);
}
// initilalize slice
umcRes = pSlice->Init(pMemory->GetBuffer(),
pMemory->GetDataSize(),
&m_seqHeader,
pPicHeader);
if (UMC_OK != umcRes)
return UMC_ERR_INIT;
// assing macroblock plane pointer(s)
{
AVS_MB_INFO *pMbInfo = m_Fields[fieldNum].m_pMbInfo +
pSlice->m_SlcHeader.first_mb;
pSlice->m_decCtx.m_pMBInfo = pMbInfo;
pSlice->m_recCtx.m_pMBInfo = pMbInfo;
pSlice->m_debCtx.m_pMBInfo = pMbInfo;
}
// assign video planes to a slice
AssignVideoPlanes(pSlice);
// set the number of macroblocks in the slice
if ((pPrev) &&
(pPrev->m_SlcHeader.first_mb < pSlice->m_SlcHeader.first_mb))
{
pPrev->m_decCtx.MbLast = pSlice->m_SlcHeader.first_mb;
pPrev->m_recCtx.MbLast = pSlice->m_SlcHeader.first_mb;
pPrev->m_debCtx.MbLast = pSlice->m_SlcHeader.first_mb;
}
// save pointer to the previous slice
pPrev = pSlice;
// assign the owning picture
if (isFramePic)
{
pSlice->m_pPic = this;
pSlice = pSlice->GetNext();
}
else
{
pSlice->m_pPic = m_Fields + fieldNum;
m_Fields[fieldNum].m_Slices.AddToTail(*m_Slices.ExtractHead());
pSlice = m_Slices.GetHead();
}
// get next memory piece
pMemory = pMemory->GetNext();
}
return UMC_OK;
} // Status AVSFrame::Init(void)
bool AVSFrame::IsReady(void)
{
if (AVS_FRAME == m_picStructure)
{
if (m_Slices.GetHead())
return false;
}
else
{
if ((m_Fields[0].m_Slices.GetHead()) ||
(m_Fields[1].m_Slices.GetHead()))
return false;
}
return true;
} // bool AVSFrame::IsReady(void)
void AVSFrame::Reset(void)
{
m_iShown = 0;
} // void AVSFrame::Reset(void)
void AVSFrame::AssignVideoPlanes(AVSSlice *pSlice)
{
if (AVS_FRAME == m_picStructure)
{
AVSPicture::AssignVideoPlanes(pSlice);
}
else
{
if (0 == pSlice->m_SlcHeader.isSecondField)
{
m_Fields[0].AssignVideoPlanes(pSlice);
}
else
{
m_Fields[1].AssignVideoPlanes(pSlice);
}
}
} // void AVSFrame::AssignVideoPlanes(AVSSlice *pSlice)
void AVSFrame::SetReferences(AVSFrame **pRefs)
{
memset(m_pRef, 0, sizeof(m_pRef));
memset(m_Fields[0].m_pRef, 0, sizeof(m_Fields[0].m_pRef));
memset(m_Fields[1].m_pRef, 0, sizeof(m_Fields[1].m_pRef));
//
// The standard doesn't set block distances to max(1, real_block_distance),
// but we do that to avoid division on zero. Anyway zero distance is
// incorrect.
//
// this is a frame
if (AVS_FRAME == m_picStructure)
{
if (AVS_B_PICTURE == m_picHeader.PictureType)
{
Ipp32s distIdx = m_picHeader.picture_distance * 2;
Ipp32s blockDist;
m_pRef[AVS_FORWARD][0] = pRefs[1];
m_pRef[AVS_BACKWARD][0] = pRefs[0];
// calculate block distances
blockDist = distIdx -
pRefs[1]->m_picHeader.picture_distance * 2 +
512;
m_blockDist[AVS_FORWARD][0] = IPP_MAX(1, (blockDist) % 512);
blockDist = pRefs[0]->m_picHeader.picture_distance * 2 -
distIdx +
512;
m_blockDist[AVS_BACKWARD][0] = IPP_MAX(1, (blockDist) % 512);
}
else if (AVS_P_PICTURE == m_picHeader.PictureType)
{
Ipp32s distIdx = m_picHeader.picture_distance * 2;
Ipp32s blockDist;
m_pRef[AVS_FORWARD][0] = pRefs[0];
m_pRef[AVS_FORWARD][1] = pRefs[1];
// calculate distance indecies
m_distIdx[0] = pRefs[0]->m_picHeader.picture_distance * 2;
m_distIdx[1] = pRefs[1]->m_picHeader.picture_distance * 2;
// calculate block distances
blockDist = distIdx -
m_distIdx[0] +
512;
m_blockDist[AVS_FORWARD][0] = IPP_MAX(1, (blockDist) % 512);
blockDist = distIdx -
m_distIdx[1] +
512;
m_blockDist[AVS_FORWARD][1] = IPP_MAX(1, (blockDist) % 512);
}
}
// this is a couple of fields
else
{
if (AVS_B_PICTURE == m_picHeader.PictureType)
{
Ipp32s distIdx = m_picHeader.picture_distance * 2;
Ipp32s blockDist;
m_Fields[0].m_pRef[AVS_FORWARD][0] = pRefs[1]->GetPicture(AVS_LOWER_FIELD);
m_Fields[0].m_pRef[AVS_FORWARD][1] = pRefs[1]->GetPicture(AVS_UPPER_FIELD);
m_Fields[0].m_pRef[AVS_BACKWARD][0] = pRefs[0]->GetPicture(AVS_UPPER_FIELD);
m_Fields[0].m_pRef[AVS_BACKWARD][1] = pRefs[0]->GetPicture(AVS_LOWER_FIELD);
// calculate block distances
blockDist = distIdx -
pRefs[1]->m_picHeader.picture_distance * 2 +
512;
m_Fields[0].m_blockDist[AVS_FORWARD][0] = IPP_MAX(1, (blockDist - 1) % 512);
m_Fields[0].m_blockDist[AVS_FORWARD][1] = IPP_MAX(1, (blockDist) % 512);
blockDist = pRefs[0]->m_picHeader.picture_distance * 2 -
distIdx +
512;
m_Fields[0].m_blockDist[AVS_BACKWARD][0] = IPP_MAX(1, (blockDist) % 512);
m_Fields[0].m_blockDist[AVS_BACKWARD][1] = IPP_MAX(1, (blockDist + 1) % 512);
m_Fields[1].m_pRef[AVS_FORWARD][0] = m_Fields[0].m_pRef[AVS_FORWARD][0];
m_Fields[1].m_pRef[AVS_FORWARD][1] = m_Fields[0].m_pRef[AVS_FORWARD][0];
m_Fields[1].m_pRef[AVS_BACKWARD][0] = m_Fields[0].m_pRef[AVS_BACKWARD][0];
m_Fields[1].m_pRef[AVS_BACKWARD][1] = m_Fields[0].m_pRef[AVS_BACKWARD][0];
// calculate block distances
blockDist = distIdx -
pRefs[1]->m_picHeader.picture_distance * 2 +
512;
m_Fields[1].m_blockDist[AVS_FORWARD][0] = IPP_MAX(1, (blockDist) % 512);
m_Fields[1].m_blockDist[AVS_FORWARD][1] = IPP_MAX(1, (blockDist + 1) % 512);
blockDist = pRefs[0]->m_picHeader.picture_distance * 2 -
distIdx +
512;
m_Fields[1].m_blockDist[AVS_BACKWARD][0] = IPP_MAX(1, (blockDist - 1) % 512);
m_Fields[1].m_blockDist[AVS_BACKWARD][1] = IPP_MAX(1, (blockDist) % 512);
}
else if (AVS_P_PICTURE == m_picHeader.PictureType)
{
Ipp32s distIdx = m_picHeader.picture_distance * 2;
Ipp32s blockDist;
m_Fields[0].m_pRef[AVS_FORWARD][0] = pRefs[0]->GetPicture(AVS_LOWER_FIELD);
m_Fields[0].m_pRef[AVS_FORWARD][1] = pRefs[0]->GetPicture(AVS_UPPER_FIELD);
m_Fields[0].m_pRef[AVS_FORWARD][2] = pRefs[1]->GetPicture(AVS_LOWER_FIELD);
m_Fields[0].m_pRef[AVS_FORWARD][3] = pRefs[1]->GetPicture(AVS_UPPER_FIELD);
// calculate distance indices
m_Fields[0].m_distIdx[0] = pRefs[0]->m_picHeader.picture_distance * 2 + 1;
m_Fields[0].m_distIdx[1] = pRefs[0]->m_picHeader.picture_distance * 2;
m_Fields[0].m_distIdx[2] = pRefs[1]->m_picHeader.picture_distance * 2 + 1;
m_Fields[0].m_distIdx[3] = pRefs[1]->m_picHeader.picture_distance * 2;
// calculate block distances
blockDist = distIdx -
pRefs[0]->m_picHeader.picture_distance * 2 +
512;
m_Fields[0].m_blockDist[AVS_FORWARD][0] = IPP_MAX(1, (blockDist - 1) % 512);
m_Fields[0].m_blockDist[AVS_FORWARD][1] = IPP_MAX(1, (blockDist) % 512);
blockDist = distIdx -
pRefs[1]->m_picHeader.picture_distance * 2 +
512;
m_Fields[0].m_blockDist[AVS_FORWARD][2] = IPP_MAX(1, (blockDist - 1) % 512);
m_Fields[0].m_blockDist[AVS_FORWARD][3] = IPP_MAX(1, (blockDist) % 512);
m_Fields[1].m_pRef[AVS_FORWARD][0] = m_Fields + 0;
m_Fields[1].m_pRef[AVS_FORWARD][1] = pRefs[0]->GetPicture(AVS_LOWER_FIELD);
m_Fields[1].m_pRef[AVS_FORWARD][2] = pRefs[0]->GetPicture(AVS_UPPER_FIELD);
m_Fields[1].m_pRef[AVS_FORWARD][3] = pRefs[1]->GetPicture(AVS_LOWER_FIELD);
// calculate distance indices
m_Fields[1].m_distIdx[0] = m_picHeader.picture_distance * 2;
m_Fields[1].m_distIdx[1] = pRefs[0]->m_picHeader.picture_distance * 2 + 1;
m_Fields[1].m_distIdx[2] = pRefs[0]->m_picHeader.picture_distance * 2;
m_Fields[1].m_distIdx[3] = pRefs[1]->m_picHeader.picture_distance * 2 + 1;
// calculate block distances
blockDist = distIdx -
pRefs[0]->m_picHeader.picture_distance * 2 +
512;
m_Fields[1].m_blockDist[AVS_FORWARD][0] = (512 + 1) % 512;
m_Fields[1].m_blockDist[AVS_FORWARD][1] = IPP_MAX(1, (blockDist) % 512);
m_Fields[1].m_blockDist[AVS_FORWARD][2] = IPP_MAX(1, (blockDist + 1) % 512);
blockDist = distIdx -
pRefs[1]->m_picHeader.picture_distance * 2 +
512;
m_Fields[1].m_blockDist[AVS_FORWARD][3] = IPP_MAX(1, (blockDist) % 512);
}
else
{
m_Fields[1].m_pRef[AVS_FORWARD][0] = m_Fields + 0;
// calculate block distances
m_Fields[1].m_blockDist[AVS_FORWARD][0] = (512 + 1) % 512;
}
}
} // void AVSFrame::SetReferences(AVSFrame **pRefs)
void AVSFrame::RemoveSlices(AVSList<AVSSlice> *pList)
{
if (AVS_FRAME == m_picStructure)
{
pList->AddToTail(m_Slices);
pList->AddToTail(m_SlicesSpent);
}
else
{
pList->AddToTail(m_Fields[0].m_Slices);
pList->AddToTail(m_Fields[0].m_SlicesSpent);
pList->AddToTail(m_Fields[1].m_Slices);
pList->AddToTail(m_Fields[1].m_SlicesSpent);
}
} // void AVSFrame::RemoveSlice(AVSList<AVSSlice> *pList)
void AVSFrame::RemoveMemoryPieces(AVSList<AVSMemory> *pList)
{
pList->AddToTail(m_MemoryPieces);
} // void AVSFrame::RemoveMemoryPieces(AVSList<AVSMemory> *pList)
} // namespace UMC
#endif // #if defined(UMC_ENABLE_AVS_VIDEO_DECODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -