Browse code

avfilter/vf_owdenoise: hight bit-depth support

Paul B Mahol authored on 2016/08/27 06:56:38
Showing 1 changed files
... ...
@@ -42,6 +42,7 @@ typedef struct {
42 42
     float *plane[16+1][4];
43 43
     int linesize;
44 44
     int hsub, vsub;
45
+    int pixel_depth;
45 46
 } OWDenoiseContext;
46 47
 
47 48
 #define OFFSET(x) offsetof(OWDenoiseContext, x)
... ...
@@ -188,9 +189,18 @@ static void filter(OWDenoiseContext *s,
188 188
     while (1<<depth > width || 1<<depth > height)
189 189
         depth--;
190 190
 
191
-    for (y = 0; y < height; y++)
192
-        for(x = 0; x < width; x++)
193
-            s->plane[0][0][y*s->linesize + x] = src[y*src_linesize + x];
191
+    if (s->pixel_depth <= 8) {
192
+        for (y = 0; y < height; y++)
193
+            for(x = 0; x < width; x++)
194
+                s->plane[0][0][y*s->linesize + x] = src[y*src_linesize + x];
195
+    } else {
196
+        const uint16_t *src16 = (const uint16_t *)src;
197
+
198
+        src_linesize /= 2;
199
+        for (y = 0; y < height; y++)
200
+            for(x = 0; x < width; x++)
201
+                s->plane[0][0][y*s->linesize + x] = src16[y*src_linesize + x];
202
+    }
194 203
 
195 204
     for (i = 0; i < depth; i++)
196 205
         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,
211 211
     for (i = depth-1; i >= 0; i--)
212 212
         compose2D2(s->plane[i][0], s->plane[i + 1], s->plane[0] + 1, s->linesize, 1<<i, width, height);
213 213
 
214
-    for (y = 0; y < height; y++) {
215
-        for (x = 0; x < width; x++) {
216
-            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 :)
217
-            if ((unsigned)i > 255U) i = ~(i >> 31);
218
-            dst[y*dst_linesize + x] = i;
214
+    if (s->pixel_depth <= 8) {
215
+        for (y = 0; y < height; y++) {
216
+            for (x = 0; x < width; x++) {
217
+                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 :)
218
+                if ((unsigned)i > 255U) i = ~(i >> 31);
219
+                dst[y*dst_linesize + x] = i;
220
+            }
221
+        }
222
+    } else {
223
+        uint16_t *dst16 = (uint16_t *)dst;
224
+
225
+        dst_linesize /= 2;
226
+        for (y = 0; y < height; y++) {
227
+            for (x = 0; x < width; x++) {
228
+                i = s->plane[0][0][y*s->linesize + x];
229
+                dst16[y*dst_linesize + x] = i;
230
+            }
219 231
         }
220 232
     }
221 233
 }
... ...
@@ -277,6 +299,13 @@ static int query_formats(AVFilterContext *ctx)
277 277
         AV_PIX_FMT_YUV410P,      AV_PIX_FMT_YUV440P,
278 278
         AV_PIX_FMT_YUVA444P,     AV_PIX_FMT_YUVA422P,
279 279
         AV_PIX_FMT_YUVA420P,
280
+        AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
281
+        AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
282
+        AV_PIX_FMT_YUV440P10,
283
+        AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV420P12,
284
+        AV_PIX_FMT_YUV440P12,
285
+        AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV420P14,
286
+        AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
280 287
         AV_PIX_FMT_NONE
281 288
     };
282 289
     AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
... ...
@@ -294,6 +323,7 @@ static int config_input(AVFilterLink *inlink)
294 294
 
295 295
     s->hsub = desc->log2_chroma_w;
296 296
     s->vsub = desc->log2_chroma_h;
297
+    s->pixel_depth = desc->comp[0].depth;
297 298
 
298 299
     s->linesize = FFALIGN(inlink->w, 16);
299 300
     for (j = 0; j < 4; j++) {