📄 umc_h264_npf.cpp
字号:
{
if ((Ipp32u) labs(y[k] - y[k - pitchPixels - 1]) < m_mf_thres_s)
s[m ++] = y[k - pitchPixels - 1];
if ((Ipp32u) labs(y[k] - y[k - pitchPixels + 1]) < m_mf_thres_s)
s[m ++] = y[k - pitchPixels + 1];
if ((Ipp32u) labs(y[k] - y[k + pitchPixels - 1]) < m_mf_thres_s)
s[m ++] = y[k + pitchPixels - 1];
if ((Ipp32u) labs(y[k] - y[k + pitchPixels + 1]) < m_mf_thres_s)
s[m ++] = y[k + pitchPixels + 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 5
template <class PixType>
void CNoiseReductionFilter<PixType>::RemoveNoisyEdges(
PixType* y,
PixType* u,
PixType* v,
const Ipp32s y_pitch_pixels,
const Ipp32s uv_pitch_pixels,
const Ipp32u width,
const Ipp32u height)
{
PixType* 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_pixels;
y2 = y1 + y_pitch_pixels;
y3 = y2 + y_pitch_pixels;
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, sizeof(PixType)*width);
memcpy(y1, y2, sizeof(PixType)*width);
memcpy(u, u + uv_pitch_pixels, sizeof(PixType)*halfw);
memcpy(v, v + uv_pitch_pixels, sizeof(PixType)*halfw);
// m_uBadEdge_Top = 2;
}
else
{
// ... else replace 1st row with the 2nd row
memcpy(y, y1, sizeof(PixType)*width);
memcpy(u, u + uv_pitch_pixels, sizeof(PixType)*halfw);
memcpy(v, v + uv_pitch_pixels, sizeof(PixType)*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_pixels; // 0.5 * height * pitch
for (i = 0, da = db = dc = v1 = v2 = 0; i < k; i += y_pitch_pixels)
{
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_pixels, j += uv_pitch_pixels)
{
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_pixels, j += uv_pitch_pixels)
{
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_pixels * (height - 1);
y1 = y0 - y_pitch_pixels;
y2 = y1 - y_pitch_pixels;
y3 = y2 - y_pitch_pixels;
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_pixels * (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, sizeof(PixType)*width);
memcpy(y1, y2, sizeof(PixType)*width);
memcpy(u + k, u + k - uv_pitch_pixels, sizeof(PixType)*halfw);
memcpy(v + k, v + k - uv_pitch_pixels, sizeof(PixType)*halfw);
// m_uBadEdge_Bottom = 2;
}
else
{
// ...else replace 1st row with the 2nd row
memcpy(y0, y1, sizeof(PixType)*width);
memcpy(u + k, u + k - uv_pitch_pixels, sizeof(PixType)*halfw);
memcpy(v + k, v + k - uv_pitch_pixels, sizeof(PixType)*halfw);
if (v2 > (width * thres_luma))
m_uBadEdge_Bottom = 1;
}
}
}
} // RemoveNoisyEdges
//----------------------------------------------------------------------------
// Temporal Filter (RN)
#define NL_CONSTANT 200
static 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
};
template <class PixType>
void CNoiseReductionFilter<PixType>::TemporalFilter(
PixType* y,
PixType* yp,
const Ipp32s pitchPixels,
const Ipp32s width,
const Ipp32s height)
{
Ipp32s line,pad;
register Ipp32s pel;
register PixType *s = yp;
register PixType *d = y;
if (m_bFirstFrame)
return;
pad = pitchPixels-width;
line = height;
do {
pel = width/4;
do {
register Ipp32u a,b;
a = *(s + 0);
b = *(d + 0);
b -= a;
*(d + 0) = (PixType) (a + *(FiltTab + 255 + b));
a = *(s + 1);
b = *(d + 1);
b -= a;
*(d + 1) = (PixType) (a + *(FiltTab + 255 + b));
a = *(s + 2);
b = *(d + 2);
b -= a;
*(d + 2) = (PixType) (a + *(FiltTab + 255 + b));
a = *(s + 3);
b = *(d + 3);
b -= a;
*(d + 3) = (PixType) (a + *(FiltTab + 255 + b));
s += 4;
d += 4;
} while (--pel);
d += pad;
} while (--line);
} // TemporalFilter
template class CNoiseReductionFilter<Ipp8u>;
#if defined BITDEPTH_9_12
template class CNoiseReductionFilter<Ipp16u>;
#endif // BITDEPTH_9_12
} //namespace UMC_H264_ENCODER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -