From patchwork Sun Apr 10 18:47:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 35247 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:671c:b0:7c:62c8:b2d1 with SMTP id q28csp696881pzh; Sun, 10 Apr 2022 11:45:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzBYwn51W8PyvZaTaU3IyhOrS8eNdmtRwYnXgj/FHylbP7WQI4J0NSfeB6IhILvaoIKCbAT X-Received: by 2002:a05:6402:298c:b0:41d:6b63:aa67 with SMTP id eq12-20020a056402298c00b0041d6b63aa67mr8106709edb.42.1649616317127; Sun, 10 Apr 2022 11:45:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649616317; cv=none; d=google.com; s=arc-20160816; b=t3UazKtbX0OxD5rnczS5f2V7RH5feZ+oYYY98yD//hUFiGvVsNI2ALq4tojTmBcHCQ nweIpYj0VZOhs3VGkB0k6mAWovk9zy83+PsLet03uRaa/8tkm3bgbzz2yoUGZ11sKO7J 5sTnIfuaNdhNs7O216+xxizoIw3OJQn118h9BIyQmO0q9UlnQvp69bZKvTXdHRKrNDoP HVtpDM0yVBcdbjhceftmsHyQckCTxDGWcw4UHWSP3RPANYTvOIipeBBxqqxf3pLowKxa 0hh8Yz3ShxH1uIZTL1i4YsIbAbqf1W9aLHhYBBT3jdnoEOwv5OrcKIqbhrGRaRwOHBNs 66nA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=vF9+GyUqK2Pkw0G6VGmtsj9jIKTKAoTJ9Cz5vhGVVBk=; b=PJiQRBbuNC08787ZcigJ0TuHoWFaljHjxcSc9/GnZprPug9Zlg6ctOKkyjdpk3GS6Y wXc8kcSknFfzTB5ISoXyinG7HMOm5MNAhAtHfgLWwNOnWg5b41PEJ89dvgzEEN5XREoL 3QykQFotZwfND9tNaZARYvgzFE/S2BeT81S97f7kAWd6QDtjZyE+4lD8ZNPk9JYgy4UO JAYG6wq1yy1jU6tly22x2GERKzhmInvPp3wH2TVTmoxrLhZuucjmUPsLZoXUgAYkGSLX 0U0vWY/x7G2RB3iTxDgNexm5ec6ovF5Wm6bJK8e7zcrCOC0Jl5/vGe2gzLeEVgl2C/HC DLCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=p8Z2U5oB; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id z14-20020a170906944e00b006df76385c95si5718012ejx.309.2022.04.10.11.45.16; Sun, 10 Apr 2022 11:45:17 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=p8Z2U5oB; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B315468B33A; Sun, 10 Apr 2022 21:45:05 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4C9AD68B229 for ; Sun, 10 Apr 2022 21:44:57 +0300 (EEST) Received: by mail-wm1-f47.google.com with SMTP id n126-20020a1c2784000000b0038e8af3e788so7228813wmn.1 for ; Sun, 10 Apr 2022 11:44:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=lwPX+pM+jczfhwAuCqiT2o634C26ekZfRrAvyDMi8vQ=; b=p8Z2U5oBDkTKPEiZbSNtRBeoayS2tPtWbe+YWUc0romfL1zNpoH+R4cgbakx70Y5nY 9A8mQJ/DejrcVe9fUBzwkzcHKAvO9Ynq7Tr3VHMQxPxyWyo0bX0zYykviV45LuPHfLwV hrqGsh7scmaaa+AWh/fvRGsfC+E0Xl6FNYM8K9YW3dF10BiOZsvJhatnyVqBTQzZXJmT /B8B/gTGf5tTsZZtz7Wl1iDiCLUXiyCmdNwPk4Mn0L8qrIjDZIM2aUo09553a5tzT0kJ 4qI70e/145/O5mOPqL8vuXBsfDSURCplcLhu0vKGIOkTfU88Zox4eJI9PBZtKwYVT70r 5DzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lwPX+pM+jczfhwAuCqiT2o634C26ekZfRrAvyDMi8vQ=; b=vvhcg9JivvTrMz8CQx12ts2orbIqXrhQ/mHQwJDOUNJDOuiOV/YdlUhBOHxBnWjov1 dVdybxxlZJWEHgagCYZGlPARKbME56oaz/UB8kKdQ1cCbTUPBwNZ1u8ix8IWLULePtAj s87E+7aen2Myb0wak5Nlcx2PROZVQI9uAsscDm1rTpJ+m90mWmQ6/VjqZ9nUelMM13iz dOp5cBSm4RPPZZbffCl4n2CAnqhDvWgI+JfFW+mF4ZErTqxLNkp3/sSiqBgMz2dibGxJ MfRvqv4q3ZrK/whjnx4hDFlo9UZpoZbVlp/ja1zDZxoJi067zA7NSSUgV4AuYtpAlBKE LmPA== X-Gm-Message-State: AOAM531YGLSuay8v9eJVHTPD23bLTdoR0y52YkGKcscqhFAZwcJinhzL 0IvQv1lE/Dr5DcMzGTCfASMoG1dUzXA= X-Received: by 2002:a05:600c:1994:b0:38c:48dd:23ba with SMTP id t20-20020a05600c199400b0038c48dd23bamr25965751wmq.206.1649616296493; Sun, 10 Apr 2022 11:44:56 -0700 (PDT) Received: from localhost.localdomain ([212.15.177.33]) by smtp.gmail.com with ESMTPSA id b15-20020a05600018af00b002057c72d45fsm29079409wri.77.2022.04.10.11.44.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Apr 2022 11:44:56 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Sun, 10 Apr 2022 20:47:14 +0200 Message-Id: <20220410184714.60045-2-onemda@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220410184714.60045-1-onemda@gmail.com> References: <20220410184714.60045-1-onemda@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/2] avfilter: add colorchart video filter X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 1jS4Q3rM10H5 Signed-off-by: Paul B Mahol --- libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/vsrc_testsrc.c | 153 +++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index d9865ef25e..d69bd59bb6 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -540,6 +540,7 @@ OBJS-$(CONFIG_ALLRGB_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_ALLYUV_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_CELLAUTO_FILTER) += vsrc_cellauto.o OBJS-$(CONFIG_COLOR_FILTER) += vsrc_testsrc.o +OBJS-$(CONFIG_COLORCHART_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_COLORSPECTRUM_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_COREIMAGESRC_FILTER) += vf_coreimage.o OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 8574d62e85..abd1fe2367 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -511,6 +511,7 @@ extern const AVFilter ff_vsrc_allrgb; extern const AVFilter ff_vsrc_allyuv; extern const AVFilter ff_vsrc_cellauto; extern const AVFilter ff_vsrc_color; +extern const AVFilter ff_vsrc_colorchart; extern const AVFilter ff_vsrc_colorspectrum; extern const AVFilter ff_vsrc_coreimagesrc; extern const AVFilter ff_vsrc_frei0r_src; diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index f859cf2f48..32f13c0c40 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -55,6 +55,7 @@ typedef struct TestSourceContext { const AVClass *class; int w, h; + int pw, ph; unsigned int nb_frame; AVRational time_base, frame_rate; int64_t pts; @@ -1885,3 +1886,155 @@ const AVFilter ff_vsrc_colorspectrum = { }; #endif /* CONFIG_COLORSPECTRUM_FILTER */ + +#if CONFIG_COLORCHART_FILTER + +static const AVOption colorchart_options[] = { + COMMON_OPTIONS_NOSIZE + { "patch_size", "set the single patch size", OFFSET(pw), AV_OPT_TYPE_IMAGE_SIZE, {.str="64x64"}, 0, 0, FLAGS }, + { "preset", "set the color checker chart preset", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "preset" }, + { "reference", "reference", 0, AV_OPT_TYPE_CONST,{.i64=0}, 0, 0, FLAGS, "preset" }, + { "skintones", "skintones", 0, AV_OPT_TYPE_CONST,{.i64=1}, 0, 0, FLAGS, "preset" }, + { NULL } +}; + +AVFILTER_DEFINE_CLASS(colorchart); + +static const uint8_t reference_colors[][3] = { + { 115, 82, 68 }, // dark skin + { 194, 150, 130 }, // light skin + { 98, 122, 157 }, // blue sky + { 87, 108, 67 }, // foliage + { 133, 128, 177 }, // blue flower + { 103, 189, 170 }, // bluish green + + { 214, 126, 44 }, // orange + { 80, 91, 166 }, // purple red + { 193, 90, 99 }, // moderate red + { 94, 60, 108 }, // purple + { 157, 188, 64 }, // yellow green + { 224, 163, 46 }, // orange yellow + + { 56, 61, 150 }, // blue + { 70, 148, 73 }, // green + { 175, 54, 60 }, // red + { 233, 199, 31 }, // yellow + { 187, 86, 149 }, // magenta + { 8, 133, 161 }, // cyan + + { 243, 243, 242 }, // white + { 200, 200, 200 }, // neutral 8 + { 160, 160, 160 }, // neutral 65 + { 122, 122, 121 }, // neutral 5 + { 85, 85, 85 }, // neutral 35 + { 52, 52, 52 }, // black +}; + +static const uint8_t skintones_colors[][3] = { + { 54, 38, 43 }, + { 105, 43, 42 }, + { 147, 43, 43 }, + { 77, 41, 42 }, + { 134, 43, 41 }, + { 201, 134, 118 }, + + { 59, 41, 41 }, + { 192, 103, 76 }, + { 208, 156, 141 }, + { 152, 82, 61 }, + { 162, 132, 118 }, + { 212, 171, 150 }, + + { 205, 91, 31 }, + { 164, 100, 55 }, + { 204, 136, 95 }, + { 178, 142, 116 }, + { 210, 152, 108 }, + { 217, 167, 131 }, + + { 206, 166, 126 }, + { 208, 163, 97 }, + { 245, 180, 0 }, + { 212, 184, 125 }, + { 179, 165, 150 }, + { 196, 184, 105 }, +}; + +typedef struct ColorChartPreset { + int w, h; + const uint8_t (*colors)[3]; +} ColorChartPreset; + +static const ColorChartPreset colorchart_presets[] = { + { 6, 4, reference_colors, }, + { 6, 4, skintones_colors, }, +}; + +static int colorchart_config_props(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->src; + TestSourceContext *s = ctx->priv; + + av_assert0(ff_draw_init(&s->draw, inlink->format, 0) >= 0); + if (av_image_check_size(s->w, s->h, 0, ctx) < 0) + return AVERROR(EINVAL); + return config_props(inlink); +} + +static void colorchart_fill_picture(AVFilterContext *ctx, AVFrame *frame) +{ + TestSourceContext *test = ctx->priv; + const int preset = test->type; + const int w = colorchart_presets[preset].w; + const int h = colorchart_presets[preset].h; + const int pw = test->pw; + const int ph = test->pw; + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + uint32_t pc = AV_RB24(colorchart_presets[preset].colors[y * w + x]); + FFDrawColor color; + + set_color(test, &color, pc); + ff_fill_rectangle(&test->draw, &color, frame->data, frame->linesize, + x * pw, y * ph, pw, ph); + } + } +} + +static av_cold int colorchart_init(AVFilterContext *ctx) +{ + TestSourceContext *test = ctx->priv; + const int preset = test->type; + const int w = colorchart_presets[preset].w; + const int h = colorchart_presets[preset].h; + + test->w = w * test->pw; + test->h = h * test->ph; + test->draw_once = 1; + test->fill_picture_fn = colorchart_fill_picture; + return init(ctx); +} + +static const AVFilterPad avfilter_vsrc_colorchart_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .config_props = colorchart_config_props, + }, +}; + +const AVFilter ff_vsrc_colorchart = { + .name = "colorchart", + .description = NULL_IF_CONFIG_SMALL("Generate color checker chart."), + .priv_size = sizeof(TestSourceContext), + .priv_class = &colorchart_class, + .init = colorchart_init, + .uninit = uninit, + .activate = activate, + .inputs = NULL, + FILTER_OUTPUTS(avfilter_vsrc_colorchart_outputs), + FILTER_SINGLE_PIXFMT(AV_PIX_FMT_GBRP), +}; + +#endif /* CONFIG_COLORCHART_FILTER */