📄 umc_h264_segment_decoder_deblocking.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)
#include "umc_h264_segment_decoder.h"
#include "umc_h264_dec_deblocking.h"
#include "umc_h264_frame_info.h"
namespace UMC
{
// initialize const array
H264SegmentDecoder::ChromaDeblockingFunction H264SegmentDecoder::DeblockChroma[4];
H264SegmentDecoder::ChromaDeblockingFunctionMBAFF H264SegmentDecoder::DeblockChromaVerticalMBAFF[4];
H264SegmentDecoder::ChromaDeblockingFunctionMBAFF H264SegmentDecoder::DeblockChromaHorizontalMBAFF[4];
void H264SegmentDecoder::DeblockInitialize()
{
// fill static table (sometimes it isn't initialized)
DeblockChroma[0] = &H264SegmentDecoder::DeblockChroma400;
DeblockChroma[1] = &H264SegmentDecoder::DeblockChroma420;
DeblockChroma[2] = &H264SegmentDecoder::DeblockChroma422;
DeblockChroma[3] = &H264SegmentDecoder::DeblockChroma444;
DeblockChromaVerticalMBAFF[0] = &H264SegmentDecoder::DeblockChromaVerticalMBAFF400;
DeblockChromaVerticalMBAFF[1] = &H264SegmentDecoder::DeblockChromaVerticalMBAFF420;
DeblockChromaVerticalMBAFF[2] = &H264SegmentDecoder::DeblockChromaVerticalMBAFF422;
DeblockChromaVerticalMBAFF[3] = &H264SegmentDecoder::DeblockChromaVerticalMBAFF444;
DeblockChromaHorizontalMBAFF[0] = &H264SegmentDecoder::DeblockChromaHorizontalMBAFF400;
DeblockChromaHorizontalMBAFF[1] = &H264SegmentDecoder::DeblockChromaHorizontalMBAFF420;
DeblockChromaHorizontalMBAFF[2] = &H264SegmentDecoder::DeblockChromaHorizontalMBAFF422;
DeblockChromaHorizontalMBAFF[3] = &H264SegmentDecoder::DeblockChromaHorizontalMBAFF444;
IppDeblocking[0] = &(FilterDeblockingLuma_VerEdge);
IppDeblocking[1] = &(FilterDeblockingLuma_HorEdge);
IppDeblocking[2] = &(FilterDeblockingChroma_VerEdge);
IppDeblocking[3] = &(FilterDeblockingChroma_HorEdge);
IppDeblocking[4] = &(FilterDeblockingChroma422_VerEdge);
IppDeblocking[5] = &(FilterDeblockingChroma422_HorEdge);
IppDeblocking[6] = &(FilterDeblockingChroma444_VerEdge);
IppDeblocking[7] = &(FilterDeblockingChroma444_HorEdge);
IppDeblocking16u[0] = &(FilterDeblockingLuma_VerEdge);
IppDeblocking16u[1] = &(FilterDeblockingLuma_HorEdge);
IppDeblocking16u[2] = &(FilterDeblockingChroma_VerEdge);
IppDeblocking16u[3] = &(FilterDeblockingChroma_HorEdge);
IppDeblocking16u[4] = &(FilterDeblockingChroma422_VerEdge);
IppDeblocking16u[5] = &(FilterDeblockingChroma422_HorEdge);
IppDeblocking16u[6] = &(FilterDeblockingChroma444_VerEdge);
IppDeblocking16u[7] = &(FilterDeblockingChroma444_HorEdge);
}
void H264SegmentDecoder::DeblockFrame(Ipp32s iFirstMB, Ipp32s iNumMBs)
{
Ipp32s i;
m_bFrameDeblocking = true;
for (i = iFirstMB; i < iFirstMB + iNumMBs; i++)
DeblockMacroblockMSlice(i);
} // void H264SegmentDecoder::DeblockFrame(Ipp32s uFirstMB, Ipp32s uNumMBs)
void H264SegmentDecoder::DeblockSegment(Ipp32s iFirstMB, Ipp32s iNumMBs)
{
Ipp32s i;
// no filtering edges of this slice
if (DEBLOCK_FILTER_OFF == m_pSliceHeader->disable_deblocking_filter_idc)
return;
// set frame deblocking flag
m_bFrameDeblocking = false;
// MBAFF case
if (m_pSliceHeader->MbaffFrameFlag)
{
// select optimized deblocking function
switch (m_pSliceHeader->slice_type)
{
case INTRASLICE:
for (i = iFirstMB; i < iFirstMB + iNumMBs; i++)
DeblockMacroblockISliceMBAFF(i);
break;
case PREDSLICE:
for (i = iFirstMB; i < iFirstMB + iNumMBs; i++)
DeblockMacroblockPSliceMBAFF(i);
break;
case BPREDSLICE:
for (i = iFirstMB; i < iFirstMB + iNumMBs; i++)
DeblockMacroblockBSliceMBAFF(i);
break;
default:
VM_ASSERT(false);
break;
}
}
// non-MBAFF case
else
{
// select optimized deblocking function
switch (m_pSliceHeader->slice_type)
{
case INTRASLICE:
for (i = iFirstMB; i < iFirstMB + iNumMBs; i++)
DeblockMacroblockISlice(i);
break;
case PREDSLICE:
for (i = iFirstMB; i < iFirstMB + iNumMBs; i++)
DeblockMacroblockPSlice(i);
break;
case BPREDSLICE:
for (i = iFirstMB; i < iFirstMB + iNumMBs; i++)
DeblockMacroblockBSlice(i);
break;
default:
VM_ASSERT(false);
break;
}
}
} // void H264SegmentDecoder::DeblockSegment(Ipp32s iFirstMB, Ipp32s iNumMBs)
void H264SegmentDecoder::DeblockMacroblockMSlice(Ipp32s MBAddr)
{
H264Slice* pSlice = m_pCurrentFrame->GetAU(m_field_index)->GetSliceByNumber(m_gmbinfo->mbs[MBAddr].slice_id);
// when deblocking isn't required
if ((NULL == pSlice) ||
(DEBLOCK_FILTER_OFF == pSlice->GetSliceHeader()->disable_deblocking_filter_idc))
return;
// select optimized deblocking function
switch (pSlice->GetSliceHeader()->slice_type)
{
case INTRASLICE:
DeblockMacroblockISlice(MBAddr);
break;
case PREDSLICE:
DeblockMacroblockPSlice(MBAddr);
break;
case BPREDSLICE:
DeblockMacroblockBSlice(MBAddr);
break;
default:
// illegal case. it should never hapen.
VM_ASSERT(false);
break;
}
} // void H264SegmentDecoder::DeblockMacroblockMSlice(Ipp32s MBAddr)
void H264SegmentDecoder::DeblockMacroblockISlice(Ipp32s MBAddr)
{
__align(16)
DeblockingParameters params;
// prepare deblocking parameters
params.nMBAddr = MBAddr;
ResetDeblockingVariables(¶ms);
PrepareDeblockingParametersISlice(¶ms);
{
Ipp32u color_format = m_pCurrentFrame->m_chroma_format;
(this->*DeblockChroma[color_format])(VERTICAL_DEBLOCKING, ¶ms);
(this->*DeblockChroma[color_format])(HORIZONTAL_DEBLOCKING, ¶ms);
}
// perform deblocking
DeblockLuma(VERTICAL_DEBLOCKING, ¶ms);
DeblockLuma(HORIZONTAL_DEBLOCKING, ¶ms);
} // void H264SegmentDecoder::DeblockMacroblockISlice(Ipp32s MBAddr)
void H264SegmentDecoder::DeblockMacroblockPSlice(Ipp32s MBAddr)
{
__align(16)
DeblockingParameters params;
// prepare deblocking parameters
params.nMBAddr = MBAddr;
ResetDeblockingVariables(¶ms);
PrepareDeblockingParametersPSlice(¶ms);
{
Ipp32u color_format = m_pCurrentFrame->m_chroma_format;
(this->*DeblockChroma[color_format])(VERTICAL_DEBLOCKING, ¶ms);
(this->*DeblockChroma[color_format])(HORIZONTAL_DEBLOCKING, ¶ms);
}
// perform deblocking
DeblockLuma(VERTICAL_DEBLOCKING, ¶ms);
DeblockLuma(HORIZONTAL_DEBLOCKING, ¶ms);
} // void H264SegmentDecoder::DeblockMacroblockPSlice(Ipp32u MBAddr)
void H264SegmentDecoder::DeblockMacroblockBSlice(Ipp32s MBAddr)
{
__align(16)
DeblockingParameters params;
// prepare deblocking parameters
params.nMBAddr = MBAddr;
ResetDeblockingVariables(¶ms);
PrepareDeblockingParametersBSlice(¶ms);
{
Ipp32u color_format = m_pCurrentFrame->m_chroma_format;
(this->*DeblockChroma[color_format])(VERTICAL_DEBLOCKING, ¶ms);
(this->*DeblockChroma[color_format])(HORIZONTAL_DEBLOCKING, ¶ms);
}
// perform deblocking
DeblockLuma(VERTICAL_DEBLOCKING, ¶ms);
DeblockLuma(HORIZONTAL_DEBLOCKING, ¶ms);
} // void H264SegmentDecoder::DeblockMacroblockBSlice(Ipp32s MBAddr)
void H264SegmentDecoder::DeblockLuma(Ipp32u dir, DeblockingParameters *pParams)
{
PlanePtrYCommon pY = pParams->pLuma;
Ipp32s pic_pitch = pParams->pitch_luma;
Ipp32s MBAddr = pParams->nMBAddr;
Ipp8u Clipping[16];
Ipp8u Alpha[2];
Ipp8u Beta[2];
Ipp32s AlphaC0Offset = pParams->nAlphaC0Offset;
Ipp32s BetaOffset = pParams->nBetaOffset;
Ipp32s pmq_QP = m_mbinfo.mbs[MBAddr].QP;
//
// luma deblocking
//
if (pParams->DeblockingFlag[dir])
{
Ipp8u *pClipTab;
Ipp32s QP;
Ipp32s index;
Ipp8u *pStrength = pParams->Strength[dir];
//
// correct strengths for high profile
//
if (GetMB8x8TSFlag(m_gmbinfo->mbs[MBAddr]))
{
SetEdgeStrength(pStrength + 4, 0);
SetEdgeStrength(pStrength + 12, 0);
}
if (pParams->ExternalEdgeFlag[dir])
{
Ipp32s pmp_QP;
// get neighbour block QP
pmp_QP = m_mbinfo.mbs[pParams->nNeighbour[dir]].QP;
// luma variables
QP = (pmp_QP + pmq_QP + 1) >> 1 ;
// external edge variables
index = IClip(0, 51, QP + BetaOffset);
Beta[0] = (Ipp8u) (BETA_TABLE[index]);
index = IClip(0, 51, QP + AlphaC0Offset);
Alpha[0] = (Ipp8u) (ALPHA_TABLE[index]);
pClipTab = CLIP_TAB[index];
// create clipping values
Clipping[0] = (Ipp8u) (pClipTab[pStrength[0]]);
Clipping[1] = (Ipp8u) (pClipTab[pStrength[1]]);
Clipping[2] = (Ipp8u) (pClipTab[pStrength[2]]);
Clipping[3] = (Ipp8u) (pClipTab[pStrength[3]]);
}
// internal edge variables
QP = pmq_QP;
index = IClip(0, 51, QP + BetaOffset);
Beta[1] = (Ipp8u) (BETA_TABLE[index]);
index = IClip(0, 51, QP + AlphaC0Offset);
Alpha[1] = (Ipp8u) (ALPHA_TABLE[index]);
pClipTab = CLIP_TAB[index];
// create clipping values
{
Ipp32s edge;
for (edge = 1;edge < 4;edge += 1)
{
if (*((Ipp32u *) (pStrength + edge * 4)))
{
// create clipping values
Clipping[edge * 4 + 0] = (Ipp8u) (pClipTab[pStrength[edge * 4 + 0]]);
Clipping[edge * 4 + 1] = (Ipp8u) (pClipTab[pStrength[edge * 4 + 1]]);
Clipping[edge * 4 + 2] = (Ipp8u) (pClipTab[pStrength[edge * 4 + 2]]);
Clipping[edge * 4 + 3] = (Ipp8u) (pClipTab[pStrength[edge * 4 + 3]]);
}
}
}
if (pParams->bitDepthLuma > 8)
{
IppDeblocking16u[dir]((Ipp16u*)pY,
pic_pitch,
Alpha,
Beta,
Clipping,
pStrength,
pParams->bitDepthLuma);
}
else
{
IppDeblocking[dir](pY,
pic_pitch,
Alpha,
Beta,
Clipping,
pStrength,
pParams->bitDepthLuma);
}
}
} // void H264SegmentDecoder::DeblockLuma(Ipp32u dir, DeblockingParameters *pParams)
void H264SegmentDecoder::DeblockChroma400(Ipp32u, DeblockingParameters *)
{
// there is nothing to deblock
} // void H264SegmentDecoder::DeblockChroma400(Ipp32u, DeblockingParameters *)
void H264SegmentDecoder::DeblockChroma420(Ipp32u dir, DeblockingParameters *pParams)
{
if (pParams->DeblockingFlag[dir])
{
Ipp32s pic_pitch = pParams->pitch_chroma;
Ipp32s MBAddr = pParams->nMBAddr;
Ipp8u Clipping[16];
Ipp8u Alpha[2];
Ipp8u Beta[2];
Ipp32s AlphaC0Offset = pParams->nAlphaC0Offset;
Ipp32s BetaOffset = pParams->nBetaOffset;
Ipp32s pmq_QP = m_mbinfo.mbs[MBAddr].QP;
Ipp8u *pClipTab;
Ipp32s QP;
Ipp32s index;
Ipp8u *pStrength = pParams->Strength[dir];
Ipp32s nPlane;
Ipp32s chroma_qp_offset = ~(m_pPicParamSet->chroma_qp_index_offset[0]);
for (nPlane = 0; nPlane < 2; nPlane += 1)
{
if (chroma_qp_offset != m_pPicParamSet->chroma_qp_index_offset[nPlane])
{
chroma_qp_offset = m_pPicParamSet->chroma_qp_index_offset[nPlane];
if (pParams->ExternalEdgeFlag[dir])
{
Ipp32s pmp_QP;
// get left block QP
pmp_QP = m_mbinfo.mbs[pParams->nNeighbour[dir]].QP;
// external edge variables
QP = (QP_SCALE_CR[IClip(0, 51, pmp_QP + chroma_qp_offset)] +
QP_SCALE_CR[IClip(0, 51, pmq_QP + chroma_qp_offset)] + 1) >> 1;
index = IClip(0, 51, QP + BetaOffset);
Beta[0] = (Ipp8u) (BETA_TABLE[index]);
index = IClip(0, 51, QP + AlphaC0Offset);
Alpha[0] = (Ipp8u) (ALPHA_TABLE[index]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -