📄 umc_h264_npf.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 - 2007 Intel Corporation. All Rights Reserved.
//
// This file implements the core noise reduction filter class,
// CNoiseReductionFilter. It contains the constructor, destructor, and
// mainly all the custom interfaces exposed. Other methods that involve
// the actual spatio-temporal filtering operations are contained in the
// files npf_c.cpp and npf_mmx.cpp.
#include <memory.h>
#include <stdlib.h>
#include "umc_h264_npf.h"
#include "umc_h264_pub.h"
#include "umc_h264_config.h"
// following timing code are for development purposes
//----------------------------------------------------------------------------
// Constructor
namespace UMC_H264_ENCODER
{
template <class PixType>
CNoiseReductionFilter<PixType>::CNoiseReductionFilter(
const bool , // bIsMMX,
const bool , // bIsKNI,
const bool bIs7BitPel)
{
m_bFirstFrame = true;
m_bFirstFrame_MF = true;
m_b7BitPel = bIs7BitPel;
m_pLocalBuffer = NULL;
m_pLastFrame = NULL;
m_pLastFrameY = NULL;
m_pLastFrameU = NULL;
m_pLastFrameV = NULL;
m_uLocalBufferSize = 0;
m_pTFtapsBuffer = NULL;
m_pTFtaps = NULL;
m_uBadEdge_Top = 2;
m_uBadEdge_Left = 2;
m_uBadEdge_Bottom = 2;
m_uMode = GetDefaultNoiseReductionMode();
m_bEnabled = IsNoiseReductionEnabledByDefault();
// Allocate buffer for temporal filter taps
if ((m_pTFtapsBuffer = new Ipp8s[512 + 8]) != NULL)
m_pTFtaps = (Ipp8s*) H264_ALIGN(m_pTFtapsBuffer, 8);
// Set the filter options to their default values
GetDefaultNoiseReductionOptions(m_options);
UpdateAndScaleThresholds();
// No MMX optimization
m_bIsMMX = false;
#if defined(GET_NPF_TIMING)
timing_sum = timing_cnt = timing_pels = 0;
#endif
} // (Constructor)
//----------------------------------------------------------------------------
// Destructor
template <class PixType>
CNoiseReductionFilter<PixType>::~CNoiseReductionFilter()
{
if (m_pLocalBuffer)
{
delete [] m_pLocalBuffer;
m_pLocalBuffer = NULL;
m_pLastFrame = NULL;
m_pLastFrameY = NULL;
m_pLastFrameU = NULL;
m_pLastFrameV = NULL;
}
delete [] m_pTFtapsBuffer;
#if defined(GET_NPF_TIMING)
Ipp32u timing_avg = timing_cnt ? (timing_sum / timing_cnt) : 0;
printf("\nNoise Prefilter Avg = %d per frm, %d per pel\n",
timing_avg, timing_pels ? (timing_avg / timing_pels) : 0);
#endif
} // (Destructor)
//----------------------------------------------------------------------------
template <class PixType>
bool CNoiseReductionFilter<PixType>::Start_Sequence(
const Ipp32s width,
const Ipp32s height)
{
// Forget about any past memory
m_bFirstFrame = true;
m_bFirstFrame_MF = true;
m_uBadEdge_Top = 2;
m_uBadEdge_Left = 2;
m_uBadEdge_Bottom = 2;
// Width and height must be 4x and >= 8
if ((width & 3) || (height & 3) || (width < 8) || (height < 8))
{
return false;
}
// Pitch not known at this point
// Local buffer to be allocated later in DoFiltering
return true;
} // Start_Sequence
//----------------------------------------------------------------------------
// Enable or disable filter
template <class PixType>
bool CNoiseReductionFilter<PixType>::EnableNoiseReduction(const bool enable)
{
// If being turned off, reset our state for the next time we are enabled
if (!enable)
{
m_bFirstFrame = true;
m_bFirstFrame_MF = true;
}
m_bEnabled = enable;
return true;
} // EnableNoiseReduction
//----------------------------------------------------------------------------
template <class PixType>
bool CNoiseReductionFilter<PixType>::IsNoiseReductionEnabled()
{
return m_bEnabled;
}
//----------------------------------------------------------------------------
const bool IS_NOISEPF_ENABLED_BY_DEFAULT = false;
template <class PixType>
bool CNoiseReductionFilter<PixType>::IsNoiseReductionEnabledByDefault()
{
return IS_NOISEPF_ENABLED_BY_DEFAULT;
}
//----------------------------------------------------------------------------
template <class PixType>
bool CNoiseReductionFilter<PixType>::PutNoiseReductionMode(const Ipp32s mode)
{
if (!mode || (mode & ~(H264_Noise_Reduction_INR_Mode |
H264_Noise_Reduction_NER_Mode |
H264_Noise_Reduction_TNR_Mode)))
{
return false;
}
if (!(m_uMode & H264_Noise_Reduction_INR_Mode) &&
(mode & H264_Noise_Reduction_INR_Mode))
m_bFirstFrame_MF = true;
if (!(m_uMode & H264_Noise_Reduction_TNR_Mode) &&
(mode & H264_Noise_Reduction_TNR_Mode) && m_bFirstFrame_MF)
m_bFirstFrame = true;
m_uMode = mode;
return true;
}
//----------------------------------------------------------------------------
template <class PixType>
Ipp32u CNoiseReductionFilter<PixType>::GetNoiseReductionMode()
{
return m_uMode;
}
//----------------------------------------------------------------------------
const Ipp32u DEFAULT_NOISEPF_MODE =
(H264_Noise_Reduction_INR_Mode | H264_Noise_Reduction_NER_Mode);
template <class PixType>
Ipp32u CNoiseReductionFilter<PixType>::GetDefaultNoiseReductionMode()
{
return DEFAULT_NOISEPF_MODE;
}
//----------------------------------------------------------------------------
// Get default filter options and store in opt
template <class PixType>
void CNoiseReductionFilter<PixType>::GetDefaultNoiseReductionOptions(
H264_Noise_Reduction_Options& opt)
{
opt.y = true;
opt.u = true;
opt.v = true;
opt.tf_thres1 = 6;
opt.tf_thres2 = 12;
opt.tf_thres3 = 20;
opt.mf_simple = true;
opt.mf_thres_s = 15;
opt.mf_thres_t = 6;
} // GetDefaultNoiseReductionOptions
//----------------------------------------------------------------------------
// Update data used by the MMX / intrinsic routine with the current filter
// options in m_options
// Note: opt.mf_simple is not used, always apply simplified sort
template <class PixType>
void CNoiseReductionFilter<PixType>::UpdateAndScaleThresholds()
{
if (m_b7BitPel)
{
m_tf_thres1 = m_options.tf_thres1 >> 1;
m_tf_thres2 = m_options.tf_thres2 >> 1;
m_tf_thres3 = m_options.tf_thres3 >> 1;
m_mf_thres_s = m_options.mf_thres_s >> 1;
m_mf_thres_t = m_options.mf_thres_t >> 1;
}
else
{
m_tf_thres1 = m_options.tf_thres1;
m_tf_thres2 = m_options.tf_thres2;
m_tf_thres3 = m_options.tf_thres3;
m_mf_thres_s = m_options.mf_thres_s;
m_mf_thres_t = m_options.mf_thres_t;
}
// Initialize temporal filter taps
if (m_pTFtapsBuffer != NULL)
{
for (Ipp32s i = 0; i < 512; i ++)
{
Ipp32s j = i - 255; // ? 16 bits.
Ipp32u d = labs(j);
// note: All thresholds are < H264_Noise_Reduction_Max_Thres_TF.
// This ensures the difference to fit within 8 bits.
if (d < m_tf_thres1)
m_pTFtaps[i] = Ipp8s(((j << 2) + j + 3) >> 3); // * 0.625
else
if (d < m_tf_thres2)
m_pTFtaps[i] = Ipp8s(j >> 1); // * 0.5
else
if (d < m_tf_thres3)
m_pTFtaps[i] = Ipp8s(((j << 1) + j + 3) >> 3); // * 0.375
else
m_pTFtaps[i] = 0;
}
}
} // UpdateAndScaleThresholds
//----------------------------------------------------------------------------
// Get filter options with given values
template <class PixType>
void CNoiseReductionFilter<PixType>::GetNoiseReductionOptions(
H264_Noise_Reduction_Options& opt)
{
opt = m_options;
} // GetNoiseReductionOptions
//----------------------------------------------------------------------------
// Check to see if we need to allocate a local buffer for the filter and
// verify the buffer size
template <class PixType>
bool CNoiseReductionFilter<PixType>::CheckBuffer(
const Ipp32s y_pitch_pixels,
const Ipp32s uv_pitch_pixels,
const Ipp32s width,
const Ipp32s height)
{
// First check the filter taps buffer
if (m_pTFtapsBuffer == NULL)
return false;
Ipp32u size;
if (y_pitch_pixels == uv_pitch_pixels)
size = y_pitch_pixels * (height + (height >> 1));
else
size = (y_pitch_pixels + uv_pitch_pixels) * height;
// Reallocate last frame buffer if necessary
if (size > m_uLocalBufferSize)
{
delete [] m_pLocalBuffer;
m_pLocalBuffer = NULL;
m_pLastFrame = NULL;
m_pLastFrameY = NULL;
m_pLastFrameU = NULL;
m_pLastFrameV = NULL;
}
if (!m_pLocalBuffer)
{
// Extra 32 bytes for prefetching in the MMX filter
if ((m_pLocalBuffer = new PixType[size + 32 + 8]) == NULL)
{
return false;
}
// 8-byte aligned the buffer
m_pLastFrame = (PixType*)H264_ALIGN(m_pLocalBuffer, 8);
m_uLocalBufferSize = size;
// Set up YUV buffer pointers
m_pLastFrameY = m_pLastFrame;
m_pLastFrameU = m_pLastFrameY + y_pitch_pixels * height;
if (y_pitch_pixels == uv_pitch_pixels)
m_pLastFrameV = m_pLastFrameU + (((width >> 1) + 7) & ~7);
else
m_pLastFrameV = m_pLastFrameU + uv_pitch_pixels * (height >> 1);
}
// Clear the last frame buffer if this is the first frame to be filtered
if (m_bFirstFrame)
memset((void *) m_pLastFrame, 0, m_uLocalBufferSize*sizeof(PixType));
return true;
} // CheckBuffer
//----------------------------------------------------------------------------
// Set filter options with given values
#define LIMIT_THRESHOLD_RANGE(x) \
((x) > H264_Noise_Reduction_Max_Thres ? \
H264_Noise_Reduction_Max_Thres : (x))
#define LIMIT_THRESHOLD_RANGE_TF(x) \
((x) > H264_Noise_Reduction_Max_Thres_TF ? \
H264_Noise_Reduction_Max_Thres_TF : (x))
template <class PixType>
void CNoiseReductionFilter<PixType>::PutNoiseReductionOptions(
const H264_Noise_Reduction_Options& opt)
{
m_options.y = opt.y;
m_options.u = opt.u;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -