OSDN Git Service

add LoopFilter.
authorNoumi Akira <noumiakira@users.sourceforge.jp>
Thu, 2 Jul 2009 07:43:24 +0000 (16:43 +0900)
committerNoumi Akira <noumiakira@users.sourceforge.jp>
Thu, 2 Jul 2009 07:43:24 +0000 (16:43 +0900)
Lib/QTheoraEx/FrameReconstructor.c
Lib/QTheoraEx/FrameReconstructor.h
Tests/TBenchEx/Main.cpp

index 3c79120..163e363 100644 (file)
@@ -1027,12 +1027,134 @@ static void Reconstruct_CPlane(
 
 /* */
 
+static void Filter_LoopFilterH(
+       const LoopFilter_t* t,
+       UINT8*              b,
+       INT32               s)
+{
+       const INT16* d = t->Delta + 127;
+
+       INT32 p0[2];
+       INT32 p1[2];
+
+       INT32 q0[2];
+       INT32 q1[2];
+
+       UINT8* p   = b;
+       UINT8* end = p + s * 8;
+
+       p0[1] = 0;
+       p1[1] = 0;
+       q0[1] = 255;
+       q1[1] = 255;
+
+       for (; p < end; p += s) {
+               INT32 x = (p[-2] - p[1]) + 3 * (p[0] - p[-1]);
+               INT32 v = d[(x + 4) >> 3];
+
+               p0[0] = p[-1] + v;
+               p1[0] = p[ 0] - v;
+
+               q0[0] = p0[(p0[0] < 0)];
+               q1[0] = p1[(p1[0] < 0)];
+
+               p[-1] = q0[(q0[0] > 255)];
+               p[ 0] = q1[(q1[0] > 255)];
+       }
+}
+
+static void Filter_LoopFilterV(
+       const LoopFilter_t* t,
+       UINT8*              b,
+       INT32               s)
+{
+       const INT16* d = t->Delta + 127;
+
+       INT32 p0[2];
+       INT32 p1[2];
+
+       INT32 q0[2];
+       INT32 q1[2];
+
+       UINT8* p   = b;
+       UINT8* end = p + 8;
+
+       p0[1] = 0;
+       p1[1] = 0;
+       q0[1] = 255;
+       q1[1] = 255;
+
+       for (; p < end; p++) {
+               INT32 x = (p[-2 * s] - p[1 * s]) + 3 * (p[0] - p[-1 * s]);
+               INT32 v = d[(x + 4) >> 3];
+
+               p0[0] = p[-s] + v;
+               p1[0] = p[ 0] - v;
+
+               q0[0] = p0[(p0[0] < 0)];
+               q1[0] = p1[(p1[0] < 0)];
+
+               p[-s] = q0[(q0[0] > 255)];
+               p[ 0] = q1[(q1[0] > 255)];
+       }
+}
+
+/* */
+
+void QT_FrameLoopFilter(
+       FrameDecoder_t* t)
+{
+       INT32 i;
+       INT32 x, y;
+
+       const INT16* b = t->DC;
+
+       Plane_t* plane = t->Frame[1];
+
+       for (i = 0; i < 3; i++, plane++) {
+               INT32 bx = t->Index->BX[i];
+               INT32 by = t->Index->BY[i];
+
+               UINT8* r0 = plane->Plane;
+
+               for (y = 0; y < by; y++, r0 += plane->Pitch * 8) {
+                       UINT8* r = r0;
+
+                       for (x = 0; x < bx; x++, r += 8, b++) {
+                               if (*b != NOT_CODED) {
+                                       if (x > 0) {
+                                               Filter_LoopFilterH(&(t->Filter), r, plane->Pitch);
+                                       }
+
+                                       if (y > 0) {
+                                               Filter_LoopFilterV(&(t->Filter), r, plane->Pitch);
+                                       }
+
+                                       if (x < bx - 1 && b[ 1] == NOT_CODED) {
+                                               Filter_LoopFilterH(&(t->Filter), r + 8, plane->Pitch);
+                                       }
+
+                                       if (y < by - 1 && b[bx] == NOT_CODED) {
+                                               Filter_LoopFilterV(&(t->Filter), r + 8 * plane->Pitch, plane->Pitch);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+/* */
+
 void QT_ReconstructFrame(
        FrameDecoder_t* t)
 {
        Reconstruct_YPlane(t);
 
        Reconstruct_CPlane(t);
+
+       if (t->Filter.Limit > 0) {
+               QT_FrameLoopFilter(t);
+       }
 }
 
 /* */
index 58b3142..68f9ea8 100644 (file)
@@ -5,6 +5,9 @@
 
 #include "FrameDecoder.h"
 
+void QT_FrameLoopFilter(
+       FrameDecoder_t* t);
+
 void QT_ReconstructFrame(
        FrameDecoder_t* t);
 
index 7fe6301..31b83c2 100644 (file)
@@ -8,7 +8,7 @@
 #include "Matroska.h"
 #include "TheoraDecoder.h"
 
-// #include "YUVReader.h"
+#include "YUVReader.h"
 
 class TestApp {
 
@@ -22,12 +22,12 @@ class TestApp {
 
        QTheoraDecoder_t* m_vdecoder;
 
-//     YUVReader* m_yuv;
+       YUVReader* m_yuv;
 
 public:
 
        TestApp() : m_reader(0), m_vid(0), m_vd(0),
-               m_vsetup(0), m_vdecoder(0)
+               m_vsetup(0), m_vdecoder(0), m_yuv(0)
        {
        }
 
@@ -37,6 +37,8 @@ public:
 
                QT_ReleaseDecoder(m_vdecoder);
                QT_ReleaseDecoderSetup(m_vsetup);
+
+               delete m_yuv;
        }
 
        bool Setup(LPCWSTR mkv, LPCWSTR yuv)
@@ -54,7 +56,6 @@ public:
                        return false;
                }
 
-#if 0
                if (m_vid != 0 && yuv != 0) {
                        m_yuv = new YUVReader();
 
@@ -62,7 +63,6 @@ public:
                                return false;
                        }
                }
-#endif
 
                return true;
        }
@@ -105,17 +105,15 @@ public:
 
                                i++;
 
-#if 0
                                if (m_yuv != 0 && !Compare(&output)) {
                                        printf("ERROR Compare : %d\n", i);
                                }
-#endif
 
-
-                               if (i >= 10) {
+#if 0
+                               if (i >= 2) {
                                        break;
                                }
-
+#endif
 
                        }
                }
@@ -141,7 +139,6 @@ public:
 
 private:
 
-#if 0
        bool Compare(QT_Output_t* output)
        {
                if (!m_yuv->ReadFrame()) {
@@ -154,7 +151,6 @@ private:
 
                return true;
        }
-#endif
 
        bool CheckVideo()
        {
@@ -278,16 +274,15 @@ int wmain(int argc, wchar_t* argv[])
                return -1;
        }
 
-#if 0
        if (no_SSE2) {
                QT_SetEnableSSE2(FALSE);
        }
-#endif
-
 
+#if 0
+       QT_SetEnableX86(FALSE);
        QT_SetEnableMMX(FALSE);
        QT_SetEnableSSE2(FALSE);
-
+#endif
 
        SetThreadAffinityMask(GetCurrentThread(), 1);