From patchwork Sun Oct 27 09:31:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lance Wang X-Patchwork-Id: 15987 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 75212446881 for ; Sun, 27 Oct 2019 11:32:46 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5DE7E68B038; Sun, 27 Oct 2019 11:32:46 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f195.google.com (mail-pf1-f195.google.com [209.85.210.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6730468B024 for ; Sun, 27 Oct 2019 11:32:39 +0200 (EET) Received: by mail-pf1-f195.google.com with SMTP id p26so498787pfq.8 for ; Sun, 27 Oct 2019 02:32:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=r//edBm2XPC7Ta6CawODJpBMMFRAityIhnFFP5PYBpI=; b=FOkWE2ukvm01nJOAYydakfil9WY7UGvoKt62WEbd7DcxFVC3pIuY0RKWCwImy1/vA6 zcIC7ChyLzYxzJ7rg2HpXQ52RG6uLD7c5sBYvRJJplA11JKLhU7EAs5sGJE9rHn59aUv aw+oTujr94fGyXEYiLGh1EcQ4wh4nw5BQxz9OBfLN4dLKi8v9I4p/aF85sS8I+/aTWLt w1olTsxy+5N0tnGHd0S+/I37xwydv3vpB2IUnD3wrMz8JRB0pnM/fNpIVUHF2zQICiiK vRcMXbOJaBKSitamjYfUrlwf+Bw4tZjaLKCM+cCh6JNXwASy8rRd98OifS8KpnyYy/8e T5gg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=r//edBm2XPC7Ta6CawODJpBMMFRAityIhnFFP5PYBpI=; b=XSyk1ysEUd+LVB/BDhXi6M5Fq/2iMbYRGgc0OuSlf8NpxfX7Ljn1IN0irlp+AJewhC R50GawpGsJIOxCuw9kAKGXyw7cFhxJBzupdVe4su1VB/MuQTRZslyCLR83GRoxG/cD0T usFSJh8wIyxifllJi5QSiiGSPEHMZKN9Aq3m7LDVKfqYY5wgK2/YMFoPl8FYfXzbO83A fmDIZik8E2MD+6a+POSeG1/KDeIf8N1nI6MoSxv5KCDgCd/nu/qiwgxh8BepElQQkYFF sq64cQA2UrKvz5ehQm7mMmzSh/xSCJIMmaGzBCry2LxwHtw0ACLYp3rI+gGZ8gYbnUUe OaUg== X-Gm-Message-State: APjAAAWUUA40Urjk2KNNm1FKE2xvGF5lDLJ37WNJlz1RfCHI4k9XJsfB ELgioNE5o0G7gIY/JGN7cBthUrxMRhU= X-Google-Smtp-Source: APXvYqzqB9FqtqldxP39gZod5g3T1uBb1mA049qt9mKmWuTldcLoFyDrzWJd+cBQbSa9HWyacryY4w== X-Received: by 2002:a17:90a:7f81:: with SMTP id m1mr15268521pjl.92.1572168757222; Sun, 27 Oct 2019 02:32:37 -0700 (PDT) Received: from vpn.localdomain ([47.90.99.151]) by smtp.gmail.com with ESMTPSA id w2sm7048801pfn.57.2019.10.27.02.32.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 27 Oct 2019 02:32:36 -0700 (PDT) From: lance.lmwang@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Sun, 27 Oct 2019 17:31:50 +0800 Message-Id: <20191027093150.13024-2-lance.lmwang@gmail.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20191027093150.13024-1-lance.lmwang@gmail.com> References: <20191027093150.13024-1-lance.lmwang@gmail.com> Subject: [FFmpeg-devel] [PATCH v1 2/2] avfilter/vf_colorbalance: rewrite the code with macro-based function 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 Cc: Limin Wang MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Limin Wang rename the function to lut_planar_##bits and lut_packed_##bits to make it more clear Signed-off-by: Limin Wang --- libavfilter/vf_colorbalance.c | 253 +++++++++++++++--------------------------- 1 file changed, 89 insertions(+), 164 deletions(-) diff --git a/libavfilter/vf_colorbalance.c b/libavfilter/vf_colorbalance.c index fd003fd..c7262ce 100644 --- a/libavfilter/vf_colorbalance.c +++ b/libavfilter/vf_colorbalance.c @@ -51,6 +51,7 @@ typedef struct ColorBalanceContext { uint8_t rgba_map[4]; int step; + int bps; int (*apply_lut)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); } ColorBalanceContext; @@ -96,161 +97,89 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } -static int apply_lut8_p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - ColorBalanceContext *s = ctx->priv; - ThreadData *td = arg; - AVFrame *in = td->in; - AVFrame *out = td->out; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; - const uint8_t *srcg = in->data[0] + slice_start * in->linesize[0]; - const uint8_t *srcb = in->data[1] + slice_start * in->linesize[1]; - const uint8_t *srcr = in->data[2] + slice_start * in->linesize[2]; - const uint8_t *srca = in->data[3] + slice_start * in->linesize[3]; - uint8_t *dstg = out->data[0] + slice_start * out->linesize[0]; - uint8_t *dstb = out->data[1] + slice_start * out->linesize[1]; - uint8_t *dstr = out->data[2] + slice_start * out->linesize[2]; - uint8_t *dsta = out->data[3] + slice_start * out->linesize[3]; - int i, j; - - for (i = slice_start; i < slice_end; i++) { - for (j = 0; j < out->width; j++) { - dstg[j] = s->lut[G][srcg[j]]; - dstb[j] = s->lut[B][srcb[j]]; - dstr[j] = s->lut[R][srcr[j]]; - if (in != out && out->linesize[3]) - dsta[j] = srca[j]; - } - - srcg += in->linesize[0]; - srcb += in->linesize[1]; - srcr += in->linesize[2]; - srca += in->linesize[3]; - dstg += out->linesize[0]; - dstb += out->linesize[1]; - dstr += out->linesize[2]; - dsta += out->linesize[3]; - } - - return 0; +#define DEF_PLANAR_LUT_FUNC(type, nbits) \ +static int lut_planar_##nbits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ +{ \ + ColorBalanceContext *s = ctx->priv; \ + ThreadData *td = arg; \ + AVFrame *in = td->in; \ + AVFrame *out = td->out; \ + const int slice_start = (out->height * jobnr) / nb_jobs; \ + const int slice_end = (out->height * (jobnr+1)) / nb_jobs; \ + const type *srcg = (const type *)in->data[0] + slice_start * in->linesize[0] / s->bps; \ + const type *srcb = (const type *)in->data[1] + slice_start * in->linesize[1] / s->bps; \ + const type *srcr = (const type *)in->data[2] + slice_start * in->linesize[2] / s->bps; \ + const type *srca = (const type *)in->data[3] + slice_start * in->linesize[3] / s->bps; \ + type *dstg = (type *)out->data[0] + slice_start * out->linesize[0] / s->bps; \ + type *dstb = (type *)out->data[1] + slice_start * out->linesize[1] / s->bps; \ + type *dstr = (type *)out->data[2] + slice_start * out->linesize[2] / s->bps; \ + type *dsta = (type *)out->data[3] + slice_start * out->linesize[3] / s->bps; \ + int i, j; \ + \ + for (i = slice_start; i < slice_end; i++) { \ + for (j = 0; j < out->width; j++) { \ + dstg[j] = s->lut[G][srcg[j]]; \ + dstb[j] = s->lut[B][srcb[j]]; \ + dstr[j] = s->lut[R][srcr[j]]; \ + if (in != out && out->linesize[3]) \ + dsta[j] = srca[j]; \ + } \ + \ + srcg += in->linesize[0] / s->bps; \ + srcb += in->linesize[1] / s->bps; \ + srcr += in->linesize[2] / s->bps; \ + srca += in->linesize[3] / s->bps; \ + dstg += out->linesize[0] / s->bps; \ + dstb += out->linesize[1] / s->bps; \ + dstr += out->linesize[2] / s->bps; \ + dsta += out->linesize[3] / s->bps; \ + } \ + \ + return 0; \ } - -static int apply_lut16_p(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - ColorBalanceContext *s = ctx->priv; - ThreadData *td = arg; - AVFrame *in = td->in; - AVFrame *out = td->out; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; - const uint16_t *srcg = (const uint16_t *)in->data[0] + slice_start * in->linesize[0] / 2; - const uint16_t *srcb = (const uint16_t *)in->data[1] + slice_start * in->linesize[1] / 2; - const uint16_t *srcr = (const uint16_t *)in->data[2] + slice_start * in->linesize[2] / 2; - const uint16_t *srca = (const uint16_t *)in->data[3] + slice_start * in->linesize[3] / 2; - uint16_t *dstg = (uint16_t *)out->data[0] + slice_start * out->linesize[0] / 2; - uint16_t *dstb = (uint16_t *)out->data[1] + slice_start * out->linesize[1] / 2; - uint16_t *dstr = (uint16_t *)out->data[2] + slice_start * out->linesize[2] / 2; - uint16_t *dsta = (uint16_t *)out->data[3] + slice_start * out->linesize[3] / 2; - int i, j; - - for (i = slice_start; i < slice_end; i++) { - for (j = 0; j < out->width; j++) { - dstg[j] = s->lut[G][srcg[j]]; - dstb[j] = s->lut[B][srcb[j]]; - dstr[j] = s->lut[R][srcr[j]]; - if (in != out && out->linesize[3]) - dsta[j] = srca[j]; - } - - srcg += in->linesize[0] / 2; - srcb += in->linesize[1] / 2; - srcr += in->linesize[2] / 2; - srca += in->linesize[3] / 2; - dstg += out->linesize[0] / 2; - dstb += out->linesize[1] / 2; - dstr += out->linesize[2] / 2; - dsta += out->linesize[3] / 2; - } - - return 0; -} - -static int apply_lut8(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - ColorBalanceContext *s = ctx->priv; - ThreadData *td = arg; - AVFrame *in = td->in; - AVFrame *out = td->out; - AVFilterLink *outlink = ctx->outputs[0]; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; - const uint8_t *srcrow = in->data[0] + slice_start * in->linesize[0]; - const uint8_t roffset = s->rgba_map[R]; - const uint8_t goffset = s->rgba_map[G]; - const uint8_t boffset = s->rgba_map[B]; - const uint8_t aoffset = s->rgba_map[A]; - const int step = s->step; - uint8_t *dstrow; - int i, j; - - dstrow = out->data[0] + slice_start * out->linesize[0]; - for (i = slice_start; i < slice_end; i++) { - const uint8_t *src = srcrow; - uint8_t *dst = dstrow; - - for (j = 0; j < outlink->w * step; j += step) { - dst[j + roffset] = s->lut[R][src[j + roffset]]; - dst[j + goffset] = s->lut[G][src[j + goffset]]; - dst[j + boffset] = s->lut[B][src[j + boffset]]; - if (in != out && step == 4) - dst[j + aoffset] = src[j + aoffset]; - } - - srcrow += in->linesize[0]; - dstrow += out->linesize[0]; - } - - return 0; -} - -static int apply_lut16(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) -{ - ColorBalanceContext *s = ctx->priv; - ThreadData *td = arg; - AVFrame *in = td->in; - AVFrame *out = td->out; - AVFilterLink *outlink = ctx->outputs[0]; - const int slice_start = (out->height * jobnr) / nb_jobs; - const int slice_end = (out->height * (jobnr+1)) / nb_jobs; - const uint16_t *srcrow = (const uint16_t *)in->data[0] + slice_start * in->linesize[0] / 2; - const uint8_t roffset = s->rgba_map[R]; - const uint8_t goffset = s->rgba_map[G]; - const uint8_t boffset = s->rgba_map[B]; - const uint8_t aoffset = s->rgba_map[A]; - const int step = s->step / 2; - uint16_t *dstrow; - int i, j; - - dstrow = (uint16_t *)out->data[0] + slice_start * out->linesize[0] / 2; - for (i = slice_start; i < slice_end; i++) { - const uint16_t *src = srcrow; - uint16_t *dst = dstrow; - - for (j = 0; j < outlink->w * step; j += step) { - dst[j + roffset] = s->lut[R][src[j + roffset]]; - dst[j + goffset] = s->lut[G][src[j + goffset]]; - dst[j + boffset] = s->lut[B][src[j + boffset]]; - if (in != out && step == 4) - dst[j + aoffset] = src[j + aoffset]; - } - - srcrow += in->linesize[0] / 2; - dstrow += out->linesize[0] / 2; - } - - return 0; +DEF_PLANAR_LUT_FUNC(uint16_t, 16); +DEF_PLANAR_LUT_FUNC(uint8_t, 8); + +#define DEF_LUT_PACKETED_FUNC(type, nbits) \ +static int lut_packed_##nbits(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) \ +{ \ + ColorBalanceContext *s = ctx->priv; \ + ThreadData *td = arg; \ + AVFrame *in = td->in; \ + AVFrame *out = td->out; \ + AVFilterLink *outlink = ctx->outputs[0]; \ + const int slice_start = (out->height * jobnr) / nb_jobs; \ + const int slice_end = (out->height * (jobnr+1)) / nb_jobs; \ + const type *srcrow = (const type *)in->data[0] + slice_start * in->linesize[0] / s->bps; \ + const uint8_t roffset = s->rgba_map[R]; \ + const uint8_t goffset = s->rgba_map[G]; \ + const uint8_t boffset = s->rgba_map[B]; \ + const uint8_t aoffset = s->rgba_map[A]; \ + const int step = s->step; \ + type *dstrow; \ + int i, j; \ + \ + dstrow = (type *)out->data[0] + slice_start * out->linesize[0] / s->bps; \ + for (i = slice_start; i < slice_end; i++) { \ + const type *src = srcrow; \ + type *dst = dstrow; \ + \ + for (j = 0; j < outlink->w * step; j += step) { \ + dst[j + roffset] = s->lut[R][src[j + roffset]]; \ + dst[j + goffset] = s->lut[G][src[j + goffset]]; \ + dst[j + boffset] = s->lut[B][src[j + boffset]]; \ + if (in != out && step == 4) \ + dst[j + aoffset] = src[j + aoffset]; \ + } \ + \ + srcrow += in->linesize[0] / s->bps; \ + dstrow += out->linesize[0] / s->bps; \ + } \ + \ + return 0; \ } +DEF_LUT_PACKETED_FUNC(uint16_t, 16); +DEF_LUT_PACKETED_FUNC(uint8_t, 8); static int config_output(AVFilterLink *outlink) { @@ -259,19 +188,15 @@ static int config_output(AVFilterLink *outlink) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format); const int depth = desc->comp[0].depth; const int max = 1 << depth; - const int planar = av_pix_fmt_count_planes(outlink->format) > 1; + const int is_planar = desc->flags & AV_PIX_FMT_FLAG_PLANAR; double *shadows, *midtones, *highlights, *buffer; int i, r, g, b; - if (max == 256 && planar) { - s->apply_lut = apply_lut8_p; - } else if (planar) { - s->apply_lut = apply_lut16_p; - } else if (max == 256) { - s->apply_lut = apply_lut8; - } else { - s->apply_lut = apply_lut16; - } + s->bps = depth > 8 ? 2 : 1; + if (!is_planar) + s->apply_lut = (depth <= 8) ? lut_packed_8 : lut_packed_16; + else + s->apply_lut = (depth <= 8) ? lut_planar_8 : lut_planar_16; buffer = av_malloc(max * 3 * sizeof(*buffer)); if (!buffer) @@ -317,7 +242,7 @@ static int config_output(AVFilterLink *outlink) av_free(buffer); ff_fill_rgba_map(s->rgba_map, outlink->format); - s->step = av_get_padded_bits_per_pixel(desc) >> 3; + s->step = (av_get_padded_bits_per_pixel(desc) >> 3) / s->bps; return 0; }