⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umc_h264_npf.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    {
        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 + -