📄 umc_h264_deblock.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) 2004 - 2005 Intel Corporation. All Rights Reserved.//#include "umc_h264_video_encoder.h"#include "umc_h264_deblock.h"#include "umc_h264_tables.h" // needed for ClampTbl#include "umc_h264_decdefs.h"#include "ippvc.h"using namespace UMC_H264_ENCODER;namespace UMC{//----------------------------------------------------------------------------// Constructor//----------------------------------------------------------------------------DeblockingFilter::DeblockingFilter(){ // Allocate 8-byte aligned buffer for 24 clip values. Alignment // required for the SIMD filter implementations. m_pBlockClipValAllocated = (Ipp8u *)H264_Allocate(24+7, false); if (m_pBlockClipValAllocated == NULL) { } m_pBlockClipVal = H264_ALIGN(m_pBlockClipValAllocated, 8);} // Constructor//----------------------------------------------------------------------------// Destructor//----------------------------------------------------------------------------DeblockingFilter::~DeblockingFilter(){ if (m_pBlockClipValAllocated) { H264_Free(m_pBlockClipValAllocated); m_pBlockClipValAllocated = NULL; }} // Destructor//////////////////////////////////////////////////////////////////////////////// Start_Frame//// Initializes frame pointers.//////////////////////////////////////////////////////////////////////////////void DeblockingFilter::Start_Frame( T_EncodeMBData *pMBInfoBase, // for macroblock 0 const SliceData *pSliceDataBase, // for slice 0 Ipp32u uWidth, Ipp32u uHeight, Ipp32u uPitch, Ipp8u *pYPlane, // start of frame luma data Ipp8u *pVPlane, Ipp8u *pUPlane){ m_pMBInfoBase = pMBInfoBase; m_pFilterSliceData = pSliceDataBase; m_uWidth = uWidth; m_uHeight = uHeight; m_uPitch = uPitch; m_uNumMBPerRow = (uWidth >> 4); m_uTotalNumMB = m_uNumMBPerRow * (uHeight >> 4); m_pYPlane = pYPlane; m_pVPlane = pVPlane; m_pUPlane = pUPlane;} // Start_Frame// Clipping levels for deblock filter, dependent upon QP and filter strengthstatic const Ipp8u DeblockClipTable [QP_MAX+1][3] ={ {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0} // QP=0-7 ,{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0} // 8-15 ,{0,0,0},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,1,1},{0,1,1},{1,1,1} // 16-23 ,{1,1,1},{1,1,1},{1,1,1},{1,1,2},{1,1,2},{1,1,2},{1,1,2},{1,2,3} // 24-31 ,{1,2,3},{2,2,3},{2,2,4},{2,3,4},{2,3,4},{3,3,5},{3,4,6},{3,4,6} // 32-39 ,{4,5,7},{4,5,8},{4,6,9},{5,7,10},{6,8,11},{6,8,13},{7,10,14},{8,11,16} // 40-47 ,{9,12,18},{10,13,20},{11,15,23},{13,17,25} // 48-51};// Filtering thresholds, dependent upon QP, alpha-beta pairsstatic const struct { Ipp8u alpha; Ipp8u beta;} DeblockAlphaBetaTable [QP_MAX+1] ={ {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0} // QP=0-7 ,{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0} // 8-15 ,{4,2},{4,2},{5,2},{6,3},{7,3},{8,3},{9,3},{10,4} // 16-23 ,{12,4},{13,4},{15,6},{17,6},{20,7},{22,7},{25,8},{28,8} // 24-31 ,{32,9},{36,9},{40,10},{45,10},{50,11},{56,11},{63,12},{71,12} // 32-39 ,{80,13},{90,13},{101,14},{113,14},{127,15},{144,15},{162,16},{182,16} // 40-47 ,{203,17},{226,17},{255,18},{255,18} // 48-51};// Max level at which alpha and beta are zero, thus filter is OFF#define MAX_NOFILTER_INDEX 15//----------------------------------------------------------------------------// Perform deblocking filtering on given YUV12 plane segments. This is an inplace// filter.//----------------------------------------------------------------------------////////////////////////////////////////////////////////////////////////////////// All 4x4 block edges are optionally filtered using a strong or weak filter.// This filters one 16x16 macroblock (MB) area at a time as most// of the input information is MB-based. The filtering of the vertical and// horizontal edges of a 4x4 block must be performed in the following order:// 1. V (vertical)// 2. H (horizontal)// Note that the strong or weak filter decision is per edge (not per block). For// each edge there is also a filter/no filter decision.// A simplifying filter definition rule is that only MB edges are strong-filtered.//// For each V or H edge there are three properties to be determined for the// filter:// a. boolean, whether or not to filter the edge// b. boolean, weak or strong filter (if edge is filtered)// c. filter clip level//// This implementation uses packed bit variables for booleans (a) and (b), with// one variable for each, and for each of V and H. The contents are readily// initialized from the bit-packed input variable cbp and computed mvd. Note that// these new boolean variables are *edge* booleans (not 4x4 *block* booleans);// The input cbp is block-based. Bit order of the edge booleans is// left to right, top to bottom, starting with top left at bit 0.// mvd is computed for the macroblock, is a bit-packed edge variable with a// bit set for any edge which has motion vector differences greater than a// threshold between the blocks on either side of the edge.//// Edge boolean determination// --------------------------// a. whether or not to filter the edge (bit=1 indicates filter edge)//// NO, unless one or more of the following is true:// i. block on either side is INTRA// ii. cbp bit for block on either side set// iii. mvd bit for edge set// also, picture edges are never filtered//// The pixel activity portion of whether to filter is determined within the filter.//// b. strong or weak filter (bit=1 indicates strong)// -- note content only important when var a bit is set, indicating filter edge//// WEAK, unless:// i. MB edge and block on either side is INTRA//// c. Clip level index applies only to WEAK filter, is an index into DeblockClipTable,// can be 0,1, or 2:// 2 if block on either side is INTRA// else 1 if cbp bit for block on either side set// else 0//// The pixel activity portion of the clip level is determined within the filter.//// Chroma blocks// -------------// This implementation filters the chroma block edges in the same MB loop// as the luma edges of the MB. The choice adds complexity to this function// because it needs to set up additional variables for the chroma blocks,// then traverse the edges of those blocks in the filtering part. But it takes// advantage of the definition that the edge-level decisions described above// are simply re-used for corresponding chroma edges.////----------------------------------------------------------------------------StatusDeblockingFilter::DeblockSegment(Ipp32u uFirstMB, Ipp32u uLumaOffset, Ipp32u uNumMB){ Status status = UMC_OK; Ipp32u uMB; Ipp32u uMBCol; // column of current MB, for left picture edge tests Ipp32u uQP, uQPChroma; const T_EncodeMBData *pMBInfo; // for the MB being filtered Ipp32u cbp; // luma Ipp32u mbtype; Ipp32u mvd; Ipp32u bhcbp; // bit-packed boolean, H edge has coded coef on either side (1=yes) Ipp32u bvcbp; // bit-packed boolean, V edge has coded coef on either side (1=yes) Ipp32u bhintra; // bit-packed boolean, H edge has intra block on either side (1=yes) Ipp32u bvintra; // bit-packed boolean, H edge has intra block on either side (1=yes) Ipp32u bhfilter; // bit-packed boolean, filter H edge (1=yes) Ipp32u bvfilter; // bit-packed boolean, filter V edge (1=yes) bool bOnTopEdge; bool bOnLeftEdge; Ipp32s iFilterOffsetAlpha; Ipp32s iFilterOffsetBeta; Ipp32u uSliceNum; Ipp32u uFilterControl; // can change each slice Ipp32s QPChromaIndex; // for adjacent MBs Ipp32u cbp_left; Ipp32u cbp_above; Ipp32u mbtype_adj; Ipp32u QP_left, QP_leftChroma; Ipp32u QP_above, QP_aboveChroma; Ipp32u QPavgLeft; Ipp32u QPavgAbove; Ipp32u QPavgLeftChroma; Ipp32u QPavgAboveChroma; // for adjacent blocks, formed by combining this MB and adjacent MB bits Ipp32u cbph_adj; Ipp32u cbpv_adj; const Ipp8u *pBlockClip; // points to QP-dependent set of 3 const Ipp8u *pBlockClipChroma; // QP-dependent filter lookup table indices and thresholds Ipp32s iAlphaClipIndex; Ipp32s iAlphaClipIndexChroma; Ipp32s iBetaIndex; Ipp32s iBetaIndexChroma; Ipp32s iAlphaClipIndexAbove; Ipp32s iAlphaClipIndexAboveChroma; Ipp32s iBetaIndexAbove; Ipp32s iBetaIndexAboveChroma; Ipp32s iAlphaClipIndexLeft; Ipp32s iAlphaClipIndexLeftChroma; Ipp32s iBetaIndexLeft; Ipp32s iBetaIndexLeftChroma; Ipp8u alpha[4]; // [0]: outer luma, [1]: inner luma, [2]: outer chroma, [3]: inner chroma Ipp8u beta[4]; Ipp8u *pY; Ipp8u *pV; Ipp8u *pU; Ipp32u uPitch = m_uPitch; Ipp32u uWidth = m_uWidth; Ipp32u uNumMBPerRow = m_uNumMBPerRow; uMBCol = uFirstMB % uNumMBPerRow; Ipp8u Bsl[16]; Ipp8u *Bs;#define uTopBlocksMask 0x000f#define uLeftBlocksMask 0x1111#define uBottomBlocksMask 0xf000#define uRightBlocksMask 0x8888 pMBInfo = &m_pMBInfoBase[uFirstMB]; uSliceNum = pMBInfo->uSlice; pY = m_pYPlane + uLumaOffset; pV = m_pVPlane + (uLumaOffset>>1); pU = m_pUPlane + (uLumaOffset>>1); for (uMB=uFirstMB; uMB<(uFirstMB+uNumMB); uMB++) { uFilterControl = m_pFilterSliceData[uSliceNum].disable_deblocking_filter_idc; if (uMB == m_uTotalNumMB) { status = UMC_BAD_FORMAT; break; } if (uFilterControl == DEBLOCK_FILTER_OFF) { // no filtering edges of this slice goto NextMB; } // Each loop iteration filters the Vertical (left) and // Horizontal (upper) 4x4 block edges of a 16x16 macroblock. cbp = pMBInfo->uCBP4x4; cbp = D_CBP_LUMA_TO_RASTERSCAN_ORDER(cbp); mbtype = pMBInfo->uMBType; uQP = pMBInfo->uMBQP; mvd = pMBInfo->uMVdelta; uSliceNum = pMBInfo->uSlice; iFilterOffsetAlpha = m_pFilterSliceData[uSliceNum].slice_alpha_c0_offset; iFilterOffsetBeta = m_pFilterSliceData[uSliceNum].slice_beta_offset; QPChromaIndex = uQP + m_pFilterSliceData[uSliceNum].chroma_qp_index_offset; QPChromaIndex = MIN(QPChromaIndex, (Ipp32s)QP_MAX); QPChromaIndex = MAX(0, QPChromaIndex); uQPChroma = QPtoChromaQP[QPChromaIndex]; bhintra = IS_INTRA_MBTYPE(mbtype) ? 0xffff : 0; bvintra = bhintra; { // Initialize left edge filter vars. Filter left edge of MB unless it // is a picture edge or is a slice edge and uFilterControl indicates // no filtering of slice edges. // To get MB info from MB to left const T_EncodeMBData *pMB = &pMBInfo[-1]; Ipp16u ThisSliceNum, AdjSliceNum = 0; bOnLeftEdge = false; if (uMBCol == 0) bOnLeftEdge = true; else { AdjSliceNum = pMB->uSlice; if (uFilterControl == DEBLOCK_FILTER_ON_NO_SLICE_EDGES) { // Filter left edge if MB to left is same slice ThisSliceNum = pMBInfo->uSlice; bOnLeftEdge = ThisSliceNum != AdjSliceNum; } } if (!bOnLeftEdge) { cbp_left = pMB->uCBP4x4; cbp_left = D_CBP_LUMA_TO_RASTERSCAN_ORDER(cbp_left); // If MB to left is INTRA, set the intra bits for the left edge blocks mbtype_adj = pMB->uMBType; QP_left = pMB->uMBQP; QPChromaIndex = QP_left + m_pFilterSliceData[AdjSliceNum].chroma_qp_index_offset; QPChromaIndex = MIN(QPChromaIndex, (Ipp32s)QP_MAX); QPChromaIndex = MAX(0, QPChromaIndex); QP_leftChroma = QPtoChromaQP[QPChromaIndex]; if (IS_INTRA_MBTYPE(mbtype_adj)) bvintra |= uLeftBlocksMask; } else { // no filter left edge of MB cbp_left = 0; QP_left = uQP; QP_leftChroma = uQP; // a legal value } // Initialize top edge filter vars. Filter top edge of MB unless it // is a picture edge or is a slice edge and uFilterControl indicates // no filtering of slice edges // To get MB info from MB above pMB = &pMBInfo[-((Ipp32s)uNumMBPerRow)]; bOnTopEdge = false; if (uMB < uNumMBPerRow) bOnTopEdge = true; else { AdjSliceNum = pMB->uSlice; if (uFilterControl == DEBLOCK_FILTER_ON_NO_SLICE_EDGES) { // Filter top edge if MB above is same slice ThisSliceNum = pMBInfo->uSlice; bOnTopEdge = ThisSliceNum != AdjSliceNum; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -