...
|
...
|
@@ -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++) {
|