X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_bm3d.c;h=326b258616f3e5635377451ab1d72beb66dea80d;hb=a04ad248a05e7b613abe09b3bb067f555108d794;hp=75c356728e222035351992ecabf79b822d7615e0;hpb=34a0a9746b2f441db7c45983838a88aa87a33834;p=ffmpeg diff --git a/libavfilter/vf_bm3d.c b/libavfilter/vf_bm3d.c index 75c356728e2..326b258616f 100644 --- a/libavfilter/vf_bm3d.c +++ b/libavfilter/vf_bm3d.c @@ -153,7 +153,7 @@ static const AVOption bm3d_options[] = { { "final", "final estimate", 0, AV_OPT_TYPE_CONST, {.i64=FINAL}, 0, 0, FLAGS, "mode" }, { "ref", "have reference stream", - OFFSET(ref), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS }, + OFFSET(ref), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=7}, 0, 15, FLAGS }, { NULL } @@ -164,9 +164,8 @@ AVFILTER_DEFINE_CLASS(bm3d); static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_GRAY8, - AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, - AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY9, AV_PIX_FMT_GRAY10, + AV_PIX_FMT_GRAY12, AV_PIX_FMT_GRAY14, AV_PIX_FMT_GRAY16, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, @@ -182,6 +181,11 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_YUVA444P9, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA444P12, AV_PIX_FMT_YUVA444P16, + AV_PIX_FMT_YUVA422P9, AV_PIX_FMT_YUVA422P10, AV_PIX_FMT_YUVA422P12, AV_PIX_FMT_YUVA422P16, + AV_PIX_FMT_YUVA420P9, AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_YUVA420P16, + AV_PIX_FMT_GBRAP, AV_PIX_FMT_GBRAP10, AV_PIX_FMT_GBRAP12, AV_PIX_FMT_GBRAP16, AV_PIX_FMT_NONE }; @@ -439,7 +443,7 @@ static void basic_block_filtering(BM3DContext *s, const uint8_t *src, int src_li } } - threshold[0] = s->hard_threshold * s->sigma; + threshold[0] = s->hard_threshold * s->sigma * M_SQRT2 * block_size * block_size * (1 << (s->depth - 8)) / 255.f; threshold[1] = threshold[0] * sqrtf(2.f); threshold[2] = threshold[0] * 2.f; threshold[3] = threshold[0] * sqrtf(8.f); @@ -660,7 +664,7 @@ static void do_output(BM3DContext *s, uint8_t *dst, int dst_linesize, sum_den += den; } - dstp[j] = av_clip_uint8(sum_num / sum_den); + dstp[j] = av_clip_uint8(lrintf(sum_num / sum_den)); } } } @@ -688,7 +692,7 @@ static void do_output16(BM3DContext *s, uint8_t *dst, int dst_linesize, sum_den += den; } - dstp[j] = av_clip_uintp2_c(sum_num / sum_den, depth); + dstp[j] = av_clip_uintp2_c(lrintf(sum_num / sum_den), depth); } } } @@ -706,8 +710,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int plane = td->plane; const int width = s->planewidth[plane]; const int height = s->planeheight[plane]; - const int block_pos_bottom = height - s->block_size; - const int block_pos_right = width - s->block_size; + const int block_pos_bottom = FFMAX(0, height - s->block_size); + const int block_pos_right = FFMAX(0, width - s->block_size); const int slice_start = (((height + block_step - 1) / block_step) * jobnr / nb_jobs) * block_step; const int slice_end = (jobnr == nb_jobs - 1) ? block_pos_bottom + block_step : (((height + block_step - 1) / block_step) * (jobnr + 1) / nb_jobs) * block_step; @@ -748,7 +752,7 @@ static int filter_frame(AVFilterContext *ctx, AVFrame **out, AVFrame *in, AVFram av_frame_copy_props(*out, in); for (p = 0; p < s->nb_planes; p++) { - const int nb_jobs = FFMIN(s->nb_threads, s->planeheight[p] / s->block_step); + const int nb_jobs = FFMAX(1, FFMIN(s->nb_threads, s->planeheight[p] / s->block_size)); ThreadData td; if (!((1 << p) & s->planes) || ctx->is_disabled) { @@ -796,8 +800,8 @@ static int config_input(AVFilterLink *inlink) for (i = 0; i < s->nb_threads; i++) { SliceContext *sc = &s->slices[i]; - sc->num = av_calloc(s->planewidth[0] * s->planeheight[0], sizeof(FFTSample)); - sc->den = av_calloc(s->planewidth[0] * s->planeheight[0], sizeof(FFTSample)); + sc->num = av_calloc(FFALIGN(s->planewidth[0], s->block_size) * FFALIGN(s->planeheight[0], s->block_size), sizeof(FFTSample)); + sc->den = av_calloc(FFALIGN(s->planewidth[0], s->block_size) * FFALIGN(s->planeheight[0], s->block_size), sizeof(FFTSample)); if (!sc->num || !sc->den) return AVERROR(ENOMEM); @@ -857,6 +861,8 @@ static int activate(AVFilterContext *ctx) int ret, status; int64_t pts; + FF_FILTER_FORWARD_STATUS_BACK(ctx->outputs[0], ctx->inputs[0]); + if ((ret = ff_inlink_consume_frame(ctx->inputs[0], &frame)) > 0) { ret = filter_frame(ctx, &out, frame, frame); av_frame_free(&frame); @@ -936,27 +942,19 @@ static av_cold int init(AVFilterContext *ctx) } pad.type = AVMEDIA_TYPE_VIDEO; - pad.name = av_strdup("source"); + pad.name = "source"; pad.config_props = config_input; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, 0, &pad)) < 0) return ret; - } if (s->ref) { pad.type = AVMEDIA_TYPE_VIDEO; - pad.name = av_strdup("reference"); + pad.name = "reference"; pad.config_props = NULL; - if (!pad.name) - return AVERROR(ENOMEM); - if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) { - av_freep(&pad.name); + if ((ret = ff_insert_inpad(ctx, 1, &pad)) < 0) return ret; - } } return 0; @@ -1021,9 +1019,6 @@ static av_cold void uninit(AVFilterContext *ctx) BM3DContext *s = ctx->priv; int i; - for (i = 0; i < ctx->nb_inputs; i++) - av_freep(&ctx->input_pads[i].name); - if (s->ref) ff_framesync_uninit(&s->fs); @@ -1060,7 +1055,7 @@ static const AVFilterPad bm3d_outputs[] = { { NULL } }; -AVFilter ff_vf_bm3d = { +const AVFilter ff_vf_bm3d = { .name = "bm3d", .description = NULL_IF_CONFIG_SMALL("Block-Matching 3D denoiser."), .priv_size = sizeof(BM3DContext),