📄 umc_h264_dec_slice_decoder_decode_pic.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_defs.h"
#if defined (UMC_ENABLE_H264_VIDEO_DECODER)
/* DEBUG: this file is requred to changing name
to umc_h264_dec_slice_decode_pic */
#include "umc_h264_slice_decoding.h"
#include "umc_h264_dec.h"
#include "vm_debug.h"
#include "umc_h264_frame_list.h"
namespace UMC
{
struct H264RefListInfo
{
Ipp32s m_iNumShortEntriesInList;
Ipp32s m_iNumLongEntriesInList;
Ipp32s m_iNumFramesInL0List;
Ipp32s m_iNumFramesInL1List;
Ipp32s m_iNumFramesInLTList;
};
static
H264DecoderFrame *FindLastValidReference(H264DecoderFrame **pList, Ipp32s iLength)
{
Ipp32s i;
H264DecoderFrame *pLast = NULL;
for (i = 0; i < iLength; i += 1)
{
if (pList[i])
pLast = pList[i];
}
return pLast;
} // H264DecoderFrame *FindLastValidReference(H264DecoderFrame **pList,
FactorArrayAFF H264Slice::m_StaticFactorArrayAFF;
Status H264Slice::UpdateReferenceList(H264DBPList *pDecoderFrameList)
{
Status ps = UMC_OK;
RefPicListReorderInfo *pReorderInfo_L0 = &ReorderInfoL0;
RefPicListReorderInfo *pReorderInfo_L1 = &ReorderInfoL1;
H264SeqParamSet *sps = GetSeqParam();
Ipp32u uMaxFrameNum;
Ipp32u uMaxPicNum;
H264DecoderFrame *pFrm;
H264DecoderFrame *pHead = pDecoderFrameList->head();
//Ipp32u i;
H264DecoderFrame **pRefPicList0;
H264DecoderFrame **pRefPicList1;
ReferenceFlags *pFields0;
ReferenceFlags *pFields1;
Ipp32u NumShortTermRefs, NumLongTermRefs;
H264RefListInfo rli;
H264DecoderFrame *(pLastInList[2]) = {NULL, NULL};
if (m_SliceHeader.is_auxiliary)
{
pHead = GetAuxiliaryFrame(pHead);
}
VM_ASSERT(m_pCurrentFrame);
pRefPicList0 = m_pCurrentFrame->GetRefPicList(m_iNumber, 0)->m_RefPicList;
pRefPicList1 = m_pCurrentFrame->GetRefPicList(m_iNumber, 1)->m_RefPicList;
pFields0 = m_pCurrentFrame->GetRefPicList(m_iNumber, 0)->m_Flags;
pFields1 = m_pCurrentFrame->GetRefPicList(m_iNumber, 1)->m_Flags;
// Spec reference: 8.2.4, "Decoding process for reference picture lists
// construction"
// get pointers to the picture and sequence parameter sets currently in use
uMaxFrameNum = (1<<sps->log2_max_frame_num);
uMaxPicNum = (m_SliceHeader.field_pic_flag == 0) ? uMaxFrameNum : uMaxFrameNum<<1;
for (pFrm = pHead; pFrm; pFrm = pFrm->future())
{
// update FrameNumWrap and picNum if frame number wrap occurred,
// for short-term frames
// TBD: modify for fields
pFrm->UpdateFrameNumWrap((Ipp32s)m_SliceHeader.frame_num,
uMaxFrameNum,
m_pCurrentFrame->m_PictureStructureForDec +
m_SliceHeader.bottom_field_flag);
// For long-term references, update LongTermPicNum. Note this
// could be done when LongTermFrameIdx is set, but this would
// only work for frames, not fields.
// TBD: modify for fields
pFrm->UpdateLongTermPicNum(m_pCurrentFrame->m_PictureStructureForDec +
m_SliceHeader.bottom_field_flag);
}
pRefPicList0[0] = 0;
pRefPicList1[0] = 0;
if ((m_SliceHeader.slice_type != INTRASLICE) && (m_SliceHeader.slice_type != S_INTRASLICE))
{
for (Ipp32s number = 0; number <= MAX_NUM_REF_FRAMES + 1; number++)
{
pRefPicList0[number] = 0;
pRefPicList1[number] = 0;
pFields0[number].field = 0;
pFields0[number].isShortReference = 0;
pFields1[number].field = 0;
pFields1[number].isShortReference = 0;
}
// Detect and report no available reference frames
pDecoderFrameList->countActiveRefs(NumShortTermRefs, NumLongTermRefs);
if ((NumShortTermRefs + NumLongTermRefs) == 0)
{
VM_ASSERT(0);
ps = UMC_ERR_INVALID_STREAM;
}
if (ps == UMC_OK)
{
/*static int kkkk = 0;
kkkk++;*/
// Initialize the reference picture lists
// Note the slice header get function always fills num_ref_idx_lx_active
// fields with a valid value; either the override from the slice
// header in the bitstream or the values from the pic param set when
// there is no override.
if ((m_SliceHeader.slice_type == PREDSLICE) ||
(m_SliceHeader.slice_type == S_PREDSLICE))
{
InitPSliceRefPicList(m_SliceHeader.field_pic_flag != 0,
m_SliceHeader.num_ref_idx_l0_active,
pRefPicList0,
pDecoderFrameList);
pLastInList[0] = FindLastValidReference(pRefPicList0,
m_SliceHeader.num_ref_idx_l0_active);
}
else
{
//pRefPicList1 = m_pCurrentFrame->GetRefPicList(m_iNumber, 1)->m_RefPicList;
InitBSliceRefPicLists(m_SliceHeader.field_pic_flag != 0, m_SliceHeader.num_ref_idx_l0_active,
m_SliceHeader.num_ref_idx_l1_active,
pRefPicList0, pRefPicList1,
pDecoderFrameList,
rli);
pLastInList[0] = FindLastValidReference(pRefPicList0,
m_SliceHeader.num_ref_idx_l0_active);
pLastInList[1] = FindLastValidReference(pRefPicList1,
m_SliceHeader.num_ref_idx_l1_active);
}
// Reorder the reference picture lists
Ipp8u num_ST_Ref0 = 0, num_ST_Ref1, num_LT_Ref = 0;
if (m_pCurrentFrame->m_PictureStructureForDec < FRM_STRUCTURE)
{
rli.m_iNumFramesInL0List = AdjustRefPicListForFields(pRefPicList0, pFields0, rli);
num_ST_Ref0 = (Ipp8u) rli.m_iNumShortEntriesInList;
num_LT_Ref = (Ipp8u) rli.m_iNumLongEntriesInList;
}
if (BPREDSLICE == m_SliceHeader.slice_type)
{
if (m_pCurrentFrame->m_PictureStructureForDec < FRM_STRUCTURE)
{
rli.m_iNumFramesInL1List = AdjustRefPicListForFields(pRefPicList1, pFields1, rli);
num_ST_Ref1 = (Ipp8u) rli.m_iNumShortEntriesInList;
}
if ((rli.m_iNumFramesInL0List == rli.m_iNumFramesInL1List) &&
(rli.m_iNumFramesInL0List > 1))
{
bool isNeedSwap = true;
for (Ipp32s i = 0; i < rli.m_iNumFramesInL0List; i++)
{
if (pRefPicList1[i] != pRefPicList0[i] ||
pFields1[i].field != pFields0[i].field)
{
isNeedSwap = false;
break;
}
}
if (isNeedSwap)
{
swapValues(pRefPicList1[0], pRefPicList1[1]);
swapValues(pFields1[0], pFields1[1]);
}
}
}
pRefPicList0[m_SliceHeader.num_ref_idx_l0_active] = 0;
/*{
FILE * fl = fopen("d:/ipp.ref", "a+");
fprintf(fl, "init - l0 - %d\n", kkkk);
for (Ipp32s k1 = 0; k1 < m_SliceHeader.num_ref_idx_l0_active; k1++)
{
if (!pRefPicList0[k1])
break;
fprintf(fl, "i - %d, field - %d, poc %d \n", k1, pFields0[k1].field, pRefPicList0[k1]->PicOrderCnt(pRefPicList0[k1]->GetNumberByParity(pFields0[k1].field)));
}
fprintf(fl, "l1 - %d\n", kkkk);
for (Ipp32s k1 = 0; k1 < m_SliceHeader.num_ref_idx_l1_active; k1++)
{
if (!pRefPicList1[k1])
break;
fprintf(fl, "i - %d, field - %d, poc %d \n", k1, pFields1[k1].field, pRefPicList1[k1]->PicOrderCnt(pRefPicList1[k1]->GetNumberByParity(pFields1[k1].field)));
}
fclose(fl);
}*/
if (pReorderInfo_L0->num_entries > 0)
ReOrderRefPicList(m_SliceHeader.field_pic_flag != 0, pRefPicList0, pFields0, pReorderInfo_L0, uMaxPicNum, m_SliceHeader.num_ref_idx_l0_active, pDecoderFrameList);
if (BPREDSLICE == m_SliceHeader.slice_type)
{
pRefPicList1[m_SliceHeader.num_ref_idx_l1_active] = 0;
if (pReorderInfo_L1->num_entries > 0)
ReOrderRefPicList(m_SliceHeader.field_pic_flag != 0, pRefPicList1, pFields1, pReorderInfo_L1, uMaxPicNum, m_SliceHeader.num_ref_idx_l1_active, pDecoderFrameList);
}
/*{kkkk++;
FILE * fl = fopen("d:/ipp.ref", "a+");
fprintf(fl, "reorder - l0 - %d\n", kkkk);
for (Ipp32s k1 = 0; k1 < m_SliceHeader.num_ref_idx_l0_active; k1++)
{
fprintf(fl, "i - %d, field - %d, poc %d \n", k1, pFields0[k1].field, pRefPicList0[k1]->PicOrderCnt(pRefPicList0[k1]->GetNumberByParity(pFields0[k1].field)));
}
fprintf(fl, "l1 - %d\n", kkkk);
for (Ipp32s k1 = 0; k1 < m_SliceHeader.num_ref_idx_l1_active; k1++)
{
fprintf(fl, "i - %d, field - %d, poc %d \n", k1, pFields1[k1].field, pRefPicList1[k1]->PicOrderCnt(pRefPicList1[k1]->GetNumberByParity(pFields1[k1].field)));
}
fclose(fl);
}*/
// set absent references
{
Ipp32s i;
Ipp32s iCurField = 1;
for (i = 0; i < m_SliceHeader.num_ref_idx_l0_active; i += 1)
{
if (NULL == pRefPicList0[i])
{
pRefPicList0[i] = pLastInList[0];
pFields0[i].field = (Ipp8s) (iCurField ^= 1);
pFields0[i].isShortReference = 1;
m_pCurrentFrame->SetError(1);
}
else
{
m_pCurrentFrame->SetError(pRefPicList0[i]->IsFrameExist() ? 0 : 1);
pFields0[i].isShortReference =
pRefPicList0[i]->isShortTermRef(pRefPicList0[i]->GetNumberByParity(pFields0[i].field));
}
}
if (BPREDSLICE == m_SliceHeader.slice_type)
{
iCurField = 1;
for (i = 0; i < m_SliceHeader.num_ref_idx_l1_active; i += 1)
{
if (NULL == pRefPicList1[i])
{
pRefPicList1[i] = pLastInList[1];
pFields1[i].field = (Ipp8s) (iCurField ^= 1);
pFields1[i].isShortReference = 1;
m_pCurrentFrame->SetError(1);
}
else
{
m_pCurrentFrame->SetError(pRefPicList1[i]->IsFrameExist() ? 0 : 1);
pFields1[i].isShortReference =
pRefPicList1[i]->isShortTermRef(pRefPicList1[i]->GetNumberByParity(pFields1[i].field));
}
}
}
}
// If B slice, init scaling factors array
if ((BPREDSLICE == m_SliceHeader.slice_type) && (pRefPicList1[0] != NULL))
InitDistScaleFactor(
m_SliceHeader.num_ref_idx_l0_active,
m_SliceHeader.num_ref_idx_l1_active,
pRefPicList0, pRefPicList1, pFields0, pFields1);
}
}
return ps;
} // Status H264Slice::UpdateRefPicList(H264DecoderFrameList *pDecoderFrameList)
void H264Slice::InitPSliceRefPicList(bool bIsFieldSlice,
Ipp32s /*NumL0RefActive*/,
H264DecoderFrame **pRefPicList,
H264DecoderFrameList *pDecoderFrameList)
{
Ipp32s j, k;
Ipp32s NumFramesInList;
H264DecoderFrame *pHead = pDecoderFrameList->head();
H264DecoderFrame *pFrm;
Ipp32s picNum;
bool bError = false;
VM_ASSERT(pRefPicList);
if (m_SliceHeader.is_auxiliary)
{
pHead = GetAuxiliaryFrame(pHead);
}
NumFramesInList = 0;
if (!bIsFieldSlice)
{
// Frame. Ref pic list ordering: Short term largest pic num to
// smallest, followed by long term, largest long term pic num to
// smallest. Note that ref pic list has one extra slot to assist
// with re-ordering.
for (pFrm = pHead; pFrm; pFrm = pFrm->future())
{
if (pFrm->isShortTermRef()==3)
{
// add to ordered list
picNum = pFrm->PicNum(0);
// find insertion point
j=0;
while (j<NumFramesInList &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -