| @@ -121,11 +121,11 @@ static void denoise_spatial(HQDN3DContext *s, | |||
| } | |||
| av_always_inline | |||
| static void denoise_depth(HQDN3DContext *s, | |||
| uint8_t *src, uint8_t *dst, | |||
| uint16_t *line_ant, uint16_t **frame_ant_ptr, | |||
| int w, int h, int sstride, int dstride, | |||
| int16_t *spatial, int16_t *temporal, int depth) | |||
| static int denoise_depth(HQDN3DContext *s, | |||
| uint8_t *src, uint8_t *dst, | |||
| uint16_t *line_ant, uint16_t **frame_ant_ptr, | |||
| int w, int h, int sstride, int dstride, | |||
| int16_t *spatial, int16_t *temporal, int depth) | |||
| { | |||
| // FIXME: For 16bit depth, frame_ant could be a pointer to the previous | |||
| // filtered frame rather than a separate buffer. | |||
| @@ -134,6 +134,8 @@ static void denoise_depth(HQDN3DContext *s, | |||
| if (!frame_ant) { | |||
| uint8_t *frame_src = src; | |||
| *frame_ant_ptr = frame_ant = av_malloc(w*h*sizeof(uint16_t)); | |||
| if (!frame_ant) | |||
| return AVERROR(ENOMEM); | |||
| for (y = 0; y < h; y++, src += sstride, frame_ant += w) | |||
| for (x = 0; x < w; x++) | |||
| frame_ant[x] = LOAD(x); | |||
| @@ -148,15 +150,25 @@ static void denoise_depth(HQDN3DContext *s, | |||
| denoise_temporal(src, dst, frame_ant, | |||
| w, h, sstride, dstride, temporal, depth); | |||
| emms_c(); | |||
| return 0; | |||
| } | |||
| #define denoise(...) \ | |||
| switch (s->depth) {\ | |||
| case 8: denoise_depth(__VA_ARGS__, 8); break;\ | |||
| case 9: denoise_depth(__VA_ARGS__, 9); break;\ | |||
| case 10: denoise_depth(__VA_ARGS__, 10); break;\ | |||
| case 16: denoise_depth(__VA_ARGS__, 16); break;\ | |||
| } | |||
| #define denoise(...) \ | |||
| do { \ | |||
| int ret = AVERROR_INVALIDDATA; \ | |||
| switch (s->depth) { \ | |||
| case 8: ret = denoise_depth(__VA_ARGS__, 8); break; \ | |||
| case 9: ret = denoise_depth(__VA_ARGS__, 9); break; \ | |||
| case 10: ret = denoise_depth(__VA_ARGS__, 10); break; \ | |||
| case 16: ret = denoise_depth(__VA_ARGS__, 16); break; \ | |||
| } \ | |||
| if (ret < 0) { \ | |||
| av_frame_free(&out); \ | |||
| if (!direct) \ | |||
| av_frame_free(&in); \ | |||
| return ret; \ | |||
| } \ | |||
| } while (0) | |||
| static int16_t *precalc_coefs(double dist25, int depth) | |||
| { | |||
| @@ -280,13 +292,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) | |||
| HQDN3DContext *s = inlink->dst->priv; | |||
| AVFilterLink *outlink = inlink->dst->outputs[0]; | |||
| AVFrame *out; | |||
| int direct, c; | |||
| int c, direct = av_frame_is_writable(in); | |||
| if (av_frame_is_writable(in)) { | |||
| direct = 1; | |||
| if (direct) { | |||
| out = in; | |||
| } else { | |||
| direct = 0; | |||
| out = ff_get_video_buffer(outlink, outlink->w, outlink->h); | |||
| if (!out) { | |||
| av_frame_free(&in); | |||