📄 umc_h264_npf.cpp
字号:
m_options.mf_simple = opt.mf_simple; m_options.mf_thres_s = LIMIT_THRESHOLD_RANGE(opt.mf_thres_s); m_options.mf_thres_t = LIMIT_THRESHOLD_RANGE(opt.mf_thres_t); UpdateAndScaleThresholds();} // PutNoiseReductionOptions//----------------------------------------------------------------------------// Set up calls to filter a single plane#if defined(_MSC_VER)inline#endifvoid CNoiseReductionFilter::FilterPlane( Ipp8u* x, Ipp8u* xp, Ipp32u pitch, Ipp32u width, Ipp32u height){ if (m_uMode & H264_Noise_Reduction_INR_Mode) { SpatioTemporalFilter(x, xp, pitch, width, height); } if (m_uMode & H264_Noise_Reduction_TNR_Mode) TemporalFilter(x, xp, pitch, width, height);} // FilterPlane//----------------------------------------------------------------------------// Perform noise reduction filtering on the Y, U, and V planes//// Note : Due to limitations in the mmx noise reduction filter, the pitch of// the buffer must be 8x. The width and height of the picture must be// 4x and no smaller than 8.bool CNoiseReductionFilter::DoFiltering( Ipp8u* y, Ipp8u* u, Ipp8u* v, Ipp32u y_pitch, Ipp32u uv_pitch, Ipp32u width, Ipp32u height){ // Skip all if the filter has been disabled if (!m_bEnabled) return true; // Make sure that the picture dimensions are supported if ((y_pitch & 3) || (uv_pitch & 1) || (width & 3) || (height & 3) || (width < 8) || (height < 8)) { return false; } // Proceed with noisy edge removal if enabled if (m_uMode & H264_Noise_Reduction_NER_Mode) RemoveNoisyEdges(y, u, v, y_pitch, uv_pitch, width, height); // Done if none of the other noise reduction modes is enabled if (!(m_uMode & H264_Noise_Reduction_INR_Mode) && !(m_uMode & H264_Noise_Reduction_TNR_Mode)) return true; // Make sure that the local buffer size is correct if (!CheckBuffer(y_pitch, uv_pitch, width, height)) return false; // m_bFirstFrame must be false if m_bFirstFrame_MF is false // Filter Y plane if m_options.y is set if (m_options.y) FilterPlane(y, m_pLastFrameY, y_pitch, width, height); // Update Y plane in last frame buffer Ipp32u i, j; for (i = 0, j = (height >> 1) * y_pitch; i < j; i += y_pitch) { memcpy(m_pLastFrameY + i, y + i, width); memcpy(m_pLastFrameY + i + j, y + i + j, width); } // Adjust dimensions for U and V planes width >>= 1; height >>= 1; // Filter U plane if m_options.u is set if (m_options.u) FilterPlane(u, m_pLastFrameU, uv_pitch, width, height); // Filter V plane if m_options.v is set if (m_options.v) FilterPlane(v, m_pLastFrameV, uv_pitch, width, height); // Update U and V planes in last frame buffer for (i = 0, j = (height >> 1) * uv_pitch; i < j; i += uv_pitch) { memcpy(m_pLastFrameU + i, u + i, width); memcpy(m_pLastFrameU + i + j, u + i + j, width); memcpy(m_pLastFrameV + i, v + i, width); memcpy(m_pLastFrameV + i + j, v + i + j, width); } // Last frame buffer has been filled, clear flag m_bFirstFrame = false; // Done filtering return true;} // DoFiltering//----------------------------------------------------------------------------// Sort given array of 5 into ascending order#if defined(_MSC_VER)// Some compilation systems don't like "inline" here, given that "inline"// is not specified at the declaration in "umc_h264_npf.h", and thus not seen// when Sort5 is called within "npf_c.cpp".// But, MSVC doesn't seem to mind.inline#endifvoid CNoiseReductionFilter::Sort5(Ipp8u* v){ Ipp8u u; if (v[1] > v[0]) { u = v[1]; v[1] = v[0]; v[0] = u; } if (v[2] > v[1]) { u = v[2]; v[2] = v[1]; if (u > v[0]) { v[1] = v[0]; v[0] = u; } else v[1] = u; } if (v[3] > v[2]) { u = v[3]; v[3] = v[2]; if (u > v[1]) { v[2] = v[1]; if (u > v[0]) { v[1] = v[0]; v[0] = u; } else v[1] = u; } else v[2] = u; } if (v[4] > v[3]) { u = v[4]; v[4] = v[3]; if (u > v[2]) { v[3] = v[2]; if (u > v[1]) { v[2] = v[1]; if (u > v[0]) { v[1] = v[0]; v[0] = u; } else v[1] = u; } else v[2] = u; } else v[3] = u; }} // Sort5//----------------------------------------------------------------------------// Sort given array v of n elements into ascending order#if defined(_MSC_VER)// Some compilation systems don't like "inline" here, given that "inline"// is not specified at the declaration in "umc_h264_npf.h", and thus not seen// when Sort is called within "npf_c.cpp".// But, MSVC doesn't seem to mind.inline#endifvoid CNoiseReductionFilter::Sort(Ipp8u* v, const Ipp32u n){ Ipp32u i, j; Ipp8u u; for (i = 1; i < n; i ++) { u = v[i]; for (j = i; j > 0 && u > v[j - 1]; j --) v[j] = v[j - 1]; v[j] = u; }} // Sort//----------------------------------------------------------------------------// Compute a weighted average on given inputs// 0.625 * y + 0.375 * x if |x - y| < thres1// z = 0.5 * y + 0.5 * x else if |x - y| < thres2// 0.375 * y + 0.625 * x else if |x - y| < thres3// x otherwise#if defined(_MSC_VER)// Some compilation systems don't like "inline" here, given that "inline"// is not specified at the declaration in "umc_h264_npf.h", and thus not seen// when WeightedAvg is called within "npf_c.cpp".// But, MSVC doesn't seem to mind.inline#endifIpp32u CNoiseReductionFilter::WeightedAvg(register Ipp32u x, register Ipp32u y){ return Ipp32u(x + m_pTFtaps[255 + y - x]);} // WeightedAvg//----------------------------------------------------------------------------// Perform spatio-temporal filtering on a given plane// x : pointer to input buffer// y : pointer to output buffer// yp : pointer to previous output buffer// width : width of color plane// height : height of color plane//// Notes : pitch >= width// width must be 2x and >= 4// height must be 2x and >= 4#define FILTERING(offs) \ if (Ipp32u(labs(y[offs] - yp[offs])) >= m_mf_thres_t) \ y[offs] = MedianFilter(y, pitch, offs);void CNoiseReductionFilter::SpatioTemporalFilter( Ipp8u* y, Ipp8u* yp, const Ipp32u pitch, const Ipp32u width, const Ipp32u height){ // Spatial median filtering // Filter second row thru second last row, two rows at a time Ipp32u i, j, k; Ipp32u dpitch = (pitch - width) + pitch; for (k = pitch, i = 1; i < height - 1; i += 2, k += dpitch) { // Col 1 thru 2: no median filtering on column 0 FILTERING(k+1) FILTERING(k+1+pitch) k += 2; // Col 3 thru Col width-2 for (j = k + width - 4; k < j; k += 2) { FILTERING(k) FILTERING(k+1) FILTERING(k+pitch) FILTERING(k+1+pitch) } // Last two columns: no median filtering on last column FILTERING(k) FILTERING(k+pitch) k += 2; } // If this is the first frame, clear flag and skip temporal filtering if (m_bFirstFrame_MF) { m_bFirstFrame_MF = false; return; } // Temporal filtering for (i = 0; i < height; i ++, y += pitch, yp += pitch) { for (j = 0; j < width; j += 4) { y[j + 0] = Ipp8u(WeightedAvg(y[j + 0], yp[j + 0])); y[j + 1] = Ipp8u(WeightedAvg(y[j + 1], yp[j + 1])); y[j + 2] = Ipp8u(WeightedAvg(y[j + 2], yp[j + 2])); y[j + 3] = Ipp8u(WeightedAvg(y[j + 3], yp[j + 3])); } }} // SpatioTemporalFilter//----------------------------------------------------------------------------// Find the median of a given point from it neighbors// x : pointer to input buffer// y : pointer to output buffer// width : width of color plane// height : height of color plane// k : index to point of interestIpp8u CNoiseReductionFilter::MedianFilter( Ipp8u* y, const Ipp32u pitch, const Ipp32u k){ Ipp32u m, n; Ipp8u s[9]; // Initialize the sort buffer with given input, x[k], and 0's s[0] = y[k]; s[1] = s[2] = s[3] = s[4] = s[5] = s[6] = s[7] = s[8] = 0; m = 1; // Check to include neighbors x[k + 1], x[k + width] // Neighbors x[k - 1] and x[k - width] are substituted by the output // y[k - 1] and y[k - width] // Also, outliers that differ from x[k] by more than the threshold // m_mfo.thres_s are excluded if ((Ipp32u) labs(y[k] - y[k - 1]) < m_mf_thres_s) s[m ++] = y[k - 1]; if ((Ipp32u) labs(y[k] - y[k + 1]) < m_mf_thres_s) s[m ++] = y[k + 1]; if ((Ipp32u) labs(y[k] - y[k - pitch]) < m_mf_thres_s) s[m ++] = y[k - pitch]; if ((Ipp32u) labs(y[k] - y[k + pitch]) < m_mf_thres_s) s[m ++] = y[k + pitch]; // Check to include diagonal neighbors x[k + width - 1], x[k + width + 1] // Neighbors x[k - width - 1] and x[k - width + 1] are substituted by the // output y[k - width - 1] and y[k - width + 1] // Again excluded outliers if (!m_options.mf_simple) { if ((Ipp32u) labs(y[k] - y[k - pitch - 1]) < m_mf_thres_s) s[m ++] = y[k - pitch - 1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -