avfilter/vf_owdenoise: hight bit-depth support
authorPaul B Mahol <onemda@gmail.com>
Fri, 26 Aug 2016 21:56:38 +0000 (23:56 +0200)
committerPaul B Mahol <onemda@gmail.com>
Mon, 5 Sep 2016 23:29:46 +0000 (01:29 +0200)
libavfilter/vf_owdenoise.c

index 6becccc..e0a953f 100644 (file)
@@ -42,6 +42,7 @@ typedef struct {
     float *plane[16+1][4];
     int linesize;
     int hsub, vsub;
+    int pixel_depth;
 } OWDenoiseContext;
 
 #define OFFSET(x) offsetof(OWDenoiseContext, x)
@@ -188,9 +189,18 @@ static void filter(OWDenoiseContext *s,
     while (1<<depth > width || 1<<depth > height)
         depth--;
 
-    for (y = 0; y < height; y++)
-        for(x = 0; x < width; x++)
-            s->plane[0][0][y*s->linesize + x] = src[y*src_linesize + x];
+    if (s->pixel_depth <= 8) {
+        for (y = 0; y < height; y++)
+            for(x = 0; x < width; x++)
+                s->plane[0][0][y*s->linesize + x] = src[y*src_linesize + x];
+    } else {
+        const uint16_t *src16 = (const uint16_t *)src;
+
+        src_linesize /= 2;
+        for (y = 0; y < height; y++)
+            for(x = 0; x < width; x++)
+                s->plane[0][0][y*s->linesize + x] = src16[y*src_linesize + x];
+    }
 
     for (i = 0; i < depth; i++)
         decompose2D2(s->plane[i + 1], s->plane[i][0], s->plane[0] + 1, s->linesize, 1<<i, width, height);
@@ -211,11 +221,23 @@ static void filter(OWDenoiseContext *s,
     for (i = depth-1; i >= 0; i--)
         compose2D2(s->plane[i][0], s->plane[i + 1], s->plane[0] + 1, s->linesize, 1<<i, width, height);
 
-    for (y = 0; y < height; y++) {
-        for (x = 0; x < width; x++) {
-            i = s->plane[0][0][y*s->linesize + x] + dither[x&7][y&7]*(1.0/64) + 1.0/128; // yes the rounding is insane but optimal :)
-            if ((unsigned)i > 255U) i = ~(i >> 31);
-            dst[y*dst_linesize + x] = i;
+    if (s->pixel_depth <= 8) {
+        for (y = 0; y < height; y++) {
+            for (x = 0; x < width; x++) {
+                i = s->plane[0][0][y*s->linesize + x] + dither[x&7][y&7]*(1.0/64) + 1.0/128; // yes the rounding is insane but optimal :)
+                if ((unsigned)i > 255U) i = ~(i >> 31);
+                dst[y*dst_linesize + x] = i;
+            }
+        }
+    } else {
+        uint16_t *dst16 = (uint16_t *)dst;
+
+        dst_linesize /= 2;
+        for (y = 0; y < height; y++) {
+            for (x = 0; x < width; x++) {
+                i = s->plane[0][0][y*s->linesize + x];
+                dst16[y*dst_linesize + x] = i;
+            }
         }
     }
 }
@@ -277,6 +299,13 @@ static int query_formats(AVFilterContext *ctx)
         AV_PIX_FMT_YUV410P,      AV_PIX_FMT_YUV440P,
         AV_PIX_FMT_YUVA444P,     AV_PIX_FMT_YUVA422P,
         AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
+        AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
+        AV_PIX_FMT_YUV440P10,
+        AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12,
+        AV_PIX_FMT_YUV440P12,
+        AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14,
+        AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
         AV_PIX_FMT_NONE
     };
     AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
@@ -294,6 +323,7 @@ static int config_input(AVFilterLink *inlink)
 
     s->hsub = desc->log2_chroma_w;
     s->vsub = desc->log2_chroma_h;
+    s->pixel_depth = desc->comp[0].depth;
 
     s->linesize = FFALIGN(inlink->w, 16);
     for (j = 0; j < 4; j++) {