From patchwork Sun Jan 12 19:48:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 17306 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id BBD8C44B0B1 for ; Sun, 12 Jan 2020 21:49:06 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9FC0C68B080; Sun, 12 Jan 2020 21:49:06 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 134E26881F2 for ; Sun, 12 Jan 2020 21:48:58 +0200 (EET) Received: by mail-wr1-f66.google.com with SMTP id d16so6528198wre.10 for ; Sun, 12 Jan 2020 11:48:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=de4BVx9tbmdeEUCOgN/DUzy1ivYg/BO01Ur2y747kbA=; b=OCg9QYnmPmPodPNItgDm3MI1koEw+yjlGhHzzQKFTNo4Ut81DAI9AAvS1nqebz6yta dfxnJLx5ZWP7ymqbOy3U+fuZ990sjRtKfPVDGvixy8rR3HUgqqcTbtk8tqKyXsePW3sB nOPl2hNJ2jysTtmsMUwliDhsc/WWxKJa0Ajw+9+TQIZt1LmVH17yg0u7VMUwEBCiJ+G6 ZhtQ+wMHcO6d36VsCDeHEO4iOF6RmOuFKX8XAGiGpsT0TNrayqzs44fL4Fz4cR3mSypY GCit96VSr8Qkh/qho4+edkUA6kgnKrWI4+UpEMMb4tLSSHMp4f+WZK1MZFR5FpELPjA2 IGXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=de4BVx9tbmdeEUCOgN/DUzy1ivYg/BO01Ur2y747kbA=; b=A4quDhsPb+zKJjNgDV0o2qWTpoOqZuZBol1T8nHF/ddE2OfNVVqpc9FPrsyiBkI9Sm xw+8Ko9117/JnT8jrpifFgpNFxljXMEbo5K0fwscuKV4lTT0WNMlPANWLVQ6q41Ehmsl 4/jxH7LSDDr0SRinzbCd/FkQhSqGUN/om1BofTD91+Yro7uA69aogusIbxiauE3YdRL/ ghpaWY/sIkgXgwvcdm9pbKm+Jhpt6kjPqwezdSBbAUtHQCs+JKxHI7VWODaEOGnVrPev tiU1Z7KgOrpYuIBem8oGskCKKpAiaPOPwtts8T2R89jeVpBZ3v61U7dsjhlCzfyYSFBe OBNg== X-Gm-Message-State: APjAAAX6b5UdJbab69B3sjWr1+sSw3dsHfwzb6KBDKijOLBAoYp5nGap Bk7vi9AflnPAeZXDvFrqG3/x6KTMq78= X-Google-Smtp-Source: APXvYqzkjhRsPY0hc2BPbBUjD/A2pNyXLUe6qUPeiJirdpaFuQ0/S2h7cNCDsRAiu3VMm0jrS5/Ovw== X-Received: by 2002:a5d:5706:: with SMTP id a6mr2160678wrv.108.1578858537131; Sun, 12 Jan 2020 11:48:57 -0800 (PST) Received: from localhost.localdomain ([109.227.51.81]) by smtp.gmail.com with ESMTPSA id r62sm11930484wma.32.2020.01.12.11.48.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 12 Jan 2020 11:48:56 -0800 (PST) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Sun, 12 Jan 2020 20:48:45 +0100 Message-Id: <20200112194847.15750-2-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200112194847.15750-1-onemda@gmail.com> References: <20200112194847.15750-1-onemda@gmail.com> Subject: [FFmpeg-devel] [PATCH 2/4] avfilter/vf_normalize: factor code dealing with AVFrame pixels out X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Paul B Mahol --- libavfilter/vf_normalize.c | 69 ++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/libavfilter/vf_normalize.c b/libavfilter/vf_normalize.c index ef97aecc0e..d353d8b75a 100644 --- a/libavfilter/vf_normalize.c +++ b/libavfilter/vf_normalize.c @@ -113,6 +113,9 @@ typedef struct NormalizeContext { uint8_t *history_mem; // Single allocation for above history entries uint8_t lut[3][256]; // Lookup table + + void (*find_min_max)(struct NormalizeContext *s, AVFrame *in, NormalizeLocal min[3], NormalizeLocal max[3]); + void (*process)(struct NormalizeContext *s, AVFrame *in, AVFrame *out); } NormalizeContext; #define OFFSET(x) offsetof(NormalizeContext, x) @@ -130,6 +133,39 @@ static const AVOption normalize_options[] = { AVFILTER_DEFINE_CLASS(normalize); +static void find_min_max(NormalizeContext *s, AVFrame *in, NormalizeLocal min[3], NormalizeLocal max[3]) +{ + for (int c = 0; c < 3; c++) + min[c].in = max[c].in = in->data[0][s->co[c]]; + for (int y = 0; y < in->height; y++) { + uint8_t *inp = in->data[0] + y * in->linesize[0]; + for (int x = 0; x < in->width; x++) { + for (int c = 0; c < 3; c++) { + min[c].in = FFMIN(min[c].in, inp[s->co[c]]); + max[c].in = FFMAX(max[c].in, inp[s->co[c]]); + } + inp += s->step; + } + } +} + +static void process(NormalizeContext *s, AVFrame *in, AVFrame *out) +{ + for (int y = 0; y < in->height; y++) { + uint8_t *inp = in->data[0] + y * in->linesize[0]; + uint8_t *outp = out->data[0] + y * out->linesize[0]; + for (int x = 0; x < in->width; x++) { + for (int c = 0; c < 3; c++) + outp[s->co[c]] = s->lut[c][inp[s->co[c]]]; + if (s->num_components == 4) + // Copy alpha as-is. + outp[s->co[3]] = inp[s->co[3]]; + inp += s->step; + outp += s->step; + } + } +} + // This function is the main guts of the filter. Normalizes the input frame // into the output frame. The frames are known to have the same dimensions // and pixel format. @@ -140,22 +176,11 @@ static void normalize(NormalizeContext *s, AVFrame *in, AVFrame *out) float rgb_min_smoothed; // Min input range for linked normalization float rgb_max_smoothed; // Max input range for linked normalization - int x, y, c; + int c; // First, scan the input frame to find, for each channel, the minimum // (min.in) and maximum (max.in) values present in the channel. - for (c = 0; c < 3; c++) - min[c].in = max[c].in = in->data[0][s->co[c]]; - for (y = 0; y < in->height; y++) { - uint8_t *inp = in->data[0] + y * in->linesize[0]; - for (x = 0; x < in->width; x++) { - for (c = 0; c < 3; c++) { - min[c].in = FFMIN(min[c].in, inp[s->co[c]]); - max[c].in = FFMAX(max[c].in, inp[s->co[c]]); - } - inp += s->step; - } - } + s->find_min_max(s, in, min, max); // Next, for each channel, push min.in and max.in into their respective // histories, to determine the min.smoothed and max.smoothed for this frame. @@ -233,19 +258,7 @@ static void normalize(NormalizeContext *s, AVFrame *in, AVFrame *out) } // Finally, process the pixels of the input frame using the lookup tables. - for (y = 0; y < in->height; y++) { - uint8_t *inp = in->data[0] + y * in->linesize[0]; - uint8_t *outp = out->data[0] + y * out->linesize[0]; - for (x = 0; x < in->width; x++) { - for (c = 0; c < 3; c++) - outp[s->co[c]] = s->lut[c][inp[s->co[c]]]; - if (s->num_components == 4) - // Copy alpha as-is. - outp[s->co[3]] = inp[s->co[3]]; - inp += s->step; - outp += s->step; - } - } + s->process(s, in, out); s->frame_num++; } @@ -311,6 +324,10 @@ static int config_input(AVFilterLink *inlink) s->min[c].history = s->history_mem + (c*2) * s->history_len; s->max[c].history = s->history_mem + (c*2+1) * s->history_len; } + + s->find_min_max = find_min_max; + s->process = process; + return 0; }