📄 umc_h264_npf.cpp
字号:
if ((Ipp32u) labs(y[k] - y[k - pitch + 1]) < m_mf_thres_s) s[m ++] = y[k - pitch + 1]; if ((Ipp32u) labs(y[k] - y[k + pitch - 1]) < m_mf_thres_s) s[m ++] = y[k + pitch - 1]; if ((Ipp32u) labs(y[k] - y[k + pitch + 1]) < m_mf_thres_s) s[m ++] = y[k + pitch + 1]; } // Now sort if (m_options.mf_simple) Sort5(s); else Sort(s, m); // Get the median and return n = m >> 1; return((m & 1) ? s[n] : ((s[n] + s[n - 1]) >> 1));} // MedianFilter//----------------------------------------------------------------------------// Detect and remove noise along the edges. Apply only to the top and// left edges. A maximum of two lines can be replaced. Bad lines// detected are simply replaced with the next valid neighbor.//// Notes: pitch >= width// width must be 2x// height must be 2x#define REASONABLE_LUMA 75#define AMOUNT_DARKER_THRESHOLD 5void CNoiseReductionFilter::RemoveNoisyEdges( Ipp8u* y, Ipp8u* u, Ipp8u* v, const Ipp32u y_pitch, const Ipp32u uv_pitch, const Ipp32u width, const Ipp32u height){ Ipp8u* y0, *y1, *y2, *y3; Ipp32u d1, d2, da, db, dc; Ipp32u v1, v2; Ipp32u i, j, k; Ipp32u thres1, thres2; Ipp32u halfw = (width >> 1); // 0.5 * width Ipp32u halfh = (height >> 1); // 0.5 * height Ipp32u thres_luma = REASONABLE_LUMA; Ipp32u thres_dark = AMOUNT_DARKER_THRESHOLD; if (!m_b7BitPel) { thres_luma <<= 1; thres_dark <<= 1; } // TOP: Detect and replace junk on the first/second rows // Note: Junk at the top is often closed-captioning info that requires some // different detection code than that to find junk on other sides if (m_uBadEdge_Top > 0) { thres1 = width * 5; thres2 = width * 2; if (!m_b7BitPel) { thres1 <<= 1; thres2 <<= 1; } y1 = y + y_pitch; y2 = y1 + y_pitch; y3 = y2 + y_pitch; for (i = 0, da = db = dc = v1 = v2 = 0; i < width; i += 2) { da += labs(y[i] - y1[i]) + labs(y[i+1] - y1[i+1]); db += labs(y2[i] - y1[i]) + labs(y2[i+1] - y1[i+1]); dc += labs(y3[i] - y2[i]) + labs(y3[i+1] - y2[i+1]); v1 += y[i] + y[i+1]; v2 += y2[i] + y2[i+1]; } d1 = labs(da - db); d2 = labs(dc - db); // If... // (1) difference between the gradient across all lines is small // (smooth at the top) and... // (2) the very top line is brighter than the third line and... // (3) the third line is reasonable bright then // ... then we can be sure that there is no junk at the top border. if ((d1 < thres2) && (d2 < thres2) && (v1 > v2) && (v2 > (width * thres_luma))) { m_uBadEdge_Top = 0; } // If there is a sufficient gradient to think we need 2 lines // replicated then... else if ((m_uBadEdge_Top == 2) && (d2 >= thres2)) { // ...replace 1st and 2nd rows with the 3rd row memcpy(y, y2, width); memcpy(y1, y2, width); memcpy(u, u + uv_pitch, halfw); memcpy(v, v + uv_pitch, halfw); // m_uBadEdge_Top = 2; } else { // ... else replace 1st row with the 2nd row memcpy(y, y1, width); memcpy(u, u + uv_pitch, halfw); memcpy(v, v + uv_pitch, halfw); m_uBadEdge_Top = 1; } } // LEFT: Detect and replace junk on the first/second columns if (m_uBadEdge_Left > 0) { thres1 = height * 10; thres2 = height * 2; if (!m_b7BitPel) { thres1 <<= 1; thres2 <<= 1; } k = halfh * y_pitch; // 0.5 * height * pitch for (i = 0, da = db = dc = v1 = v2 = 0; i < k; i += y_pitch) { da += labs(y[i] - y[i+1]) + labs(y[k+i] - y[k+i+1]); db += labs(y[i+1] - y[i+2]) + labs(y[k+i+1] - y[k+i+2]); dc += labs(y[i+3] - y[i+2]) + labs(y[k+i+3] - y[k+i+2]); v2 += y[i+1] + y[k+i+1]; // If the pels are all reasonably bright and there is not a // significantly darker pel along the border, this indicates // that the is no junk here. if ((y[i] > thres_luma) && ((y[i]+thres_dark) > y[i+2])) v1 ++; if ((y[k+i] > thres_luma) && ((y[k+i]+thres_dark) > y[k+i+2])) v1 ++; } // if the number of pels indicating that there is no black line is // more than 1/8 the border size, we can be sure there is no junk here if (v1 > (height >> 3)) { m_uBadEdge_Left = 0; } else { d1 = labs(da - db); d2 = labs(dc - db); // If there is sufficient gradient to think we need 2 lines // replicated then... if ((m_uBadEdge_Left == 2) && (d2 >= thres2) && (d1 < thres1)) { // ...replace 1st and 2nd columns with the 3rd column for (i = j = 0; i < k; i += y_pitch, j += uv_pitch) { y[i] = y[i+2]; y[i+1] = y[i+2]; y[k+i] = y[k+i+2]; y[k+i+1] = y[k+i+2]; u[j] = u[j+1]; v[j] = v[j+1]; } // m_uBadEdge_Left = 2; } else { // ...else replace 1st column with the 2nd column for (i = j = 0; i < k; i += y_pitch, j += uv_pitch) { y[i] = y[i+1]; y[k+i] = y[k+i+1]; u[j] = u[j+1]; v[j] = v[j+1]; } if (v2 > (height * thres_luma)) m_uBadEdge_Left = 1; } } } // BOTTOM: Detect and replace junk on the bottom two rows if (m_uBadEdge_Bottom > 0) { thres1 = width * 10; thres2 = width * 2; if (!m_b7BitPel) { thres1 <<= 1; thres2 <<= 1; } y0 = y + y_pitch * (height - 1); y1 = y0 - y_pitch; y2 = y1 - y_pitch; y3 = y2 - y_pitch; for (i = 0, da = db = dc = v1 = v2 = 0; i < width; i += 2) { da += labs(y0[i] - y1[i]) + labs(y0[i+1] - y1[i+1]); db += labs(y1[i] - y2[i]) + labs(y1[i+1] - y2[i+1]); dc += labs(y3[i] - y2[i]) + labs(y3[i+1] - y2[i+1]); v2 += y1[i] + y1[i+1]; // If the pels are all reasonably bright and there is not a // significantly darker pel along the border, this indicates // that the is no junk here. if ((y0[i] > thres_luma) && ((y0[i]+thres_dark) > y2[i])) v1 ++; if ((y0[i+1] > thres_luma) && ((y0[i+1]+thres_dark) > y2[i+1])) v1 ++; } if (v1 > (width >> 3)) { m_uBadEdge_Bottom = 0; } else { d1 = labs(da - db); d2 = labs(dc - db); k = uv_pitch * (halfh - 1); // If there is sufficient gradient to think we need 2 lines // replicated then... if ((m_uBadEdge_Bottom == 2) && (d2 >= thres2) && (d1 < thres1)) { // ...replace 1st and 2nd rows with the 3rd row memcpy(y0, y2, width); memcpy(y1, y2, width); memcpy(u + k, u + k - uv_pitch, halfw); memcpy(v + k, v + k - uv_pitch, halfw); // m_uBadEdge_Bottom = 2; } else { // ...else replace 1st row with the 2nd row memcpy(y0, y1, width); memcpy(u + k, u + k - uv_pitch, halfw); memcpy(v + k, v + k - uv_pitch, halfw); if (v2 > (width * thres_luma)) m_uBadEdge_Bottom = 1; } } }} // RemoveNoisyEdges//----------------------------------------------------------------------------// Temporal Filter (RN)#define NL_CONSTANT 200static Ipp8u FiltTab[512] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,233,234,235,236,238,239,241,242,244,245,246,248,249,250,252,253,254,254,255,255,255,255,255,255,255,0,1,1,1,1,1,1,1,2,2,3,4,6,7,8,10,11,12,14,15,17,18,20,21,22,23,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,0};void CNoiseReductionFilter::TemporalFilter( Ipp8u* y, Ipp8u* yp, const Ipp32u pitch, const Ipp32u width, const Ipp32u height){ int line,pad; register int pel; register unsigned char *s = yp; register unsigned char *d = y; if (m_bFirstFrame) return; pad = pitch-width; line = height; do { pel = width/4; do { register unsigned int a,b; a = *(s + 0); b = *(d + 0); b -= a; *(d + 0) = (unsigned char) (a + *(FiltTab + 255 + b)); a = *(s + 1); b = *(d + 1); b -= a; *(d + 1) = (unsigned char) (a + *(FiltTab + 255 + b)); a = *(s + 2); b = *(d + 2); b -= a; *(d + 2) = (unsigned char) (a + *(FiltTab + 255 + b)); a = *(s + 3); b = *(d + 3); b -= a; *(d + 3) = (unsigned char) (a + *(FiltTab + 255 + b)); s += 4; d += 4; } while (--pel); d += pad; } while (--line);} // TemporalFilter} //namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -