From patchwork Fri Aug 3 14:34:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Niedermayer X-Patchwork-Id: 9878 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:104:0:0:0:0:0 with SMTP id c4-v6csp204314jad; Fri, 3 Aug 2018 07:35:46 -0700 (PDT) X-Google-Smtp-Source: AAOMgpd6gbczUIGdS4U278wfO6ZBKDPm/oTr1C35rSAHyJ2znd/6yqiplicGaFdjCLrP8dfDSHF+ X-Received: by 2002:adf:dfcd:: with SMTP id q13-v6mr2695424wrn.113.1533306946159; Fri, 03 Aug 2018 07:35:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533306946; cv=none; d=google.com; s=arc-20160816; b=nXkxhKhdMCLlK7Szu9Gz2KywOWxAlKs6Xu3c62uDAlAMk3iwq5X3C+W3hTazg1q6FV Ob6SV/D73cMZPuPIdPX4XyzaXvw2MehcW/1nuRPDO33/2ih///UGVYeIgwqKCYoF/o4e fujSRf2VPljfsxUslkvDHmAJRgYVYgyE5h9tEHz87Y6IsmrcDndKje5CUhWbrU1MYiqG nlyl5NpY2E+RR80nwGJGc1UXqi1Wk89uEJqaHYvomjF/SXqNExW8xEkYHbJrrw4P9d3v OdvaSu7zzWzknRhkFpq0N0tVlxJ9cXJa9CXT6tyx/9gKUXNORgxAUQU/6vyiBWXh9dAM Pvfw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:delivered-to :arc-authentication-results; bh=fsNtV0CFELCSgGv0KzTC6Ym6D6rUoWTBTzWOHWcx0ow=; b=VCdysuMXJYurKxFG8O5JgPcqmfD/BxCn2EZELTTD0UvmViWSvnA1OeVDmNKVb5003/ TcdbeK0NijRhHRSQnzgN8mXY8j6tpBqkMnAtrdzzQfYrAETMxhltj3ze6lawRjz702s9 XoOz3JXZEDsoY16KZShapt/Y3vziY4aqrahZhsFqweAVqLmxwf2OF6JUCWC6Zd+PQ+hL M2cOQyQNPh0zBw7tKBJele1NWat6vF5SiejEX2CKxDcl5uj0iCLTYVC26sZPYMNWZ/91 Dp6OJYhnCa4JMSr/DkcKY7mvYRNvqsrNQs45x7cf/Dlhd39tGf7IAKLoxZ2Fa1CVQr+U q2Bg== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id z74-v6si3485590wmc.99.2018.08.03.07.35.45; Fri, 03 Aug 2018 07:35:46 -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; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6620D68A4A6; Fri, 3 Aug 2018 17:35:24 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from vie01a-qmta-pe01-3.mx.upcmail.net (vie01a-qmta-pe01-3.mx.upcmail.net [62.179.121.180]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A48E868A497 for ; Fri, 3 Aug 2018 17:35:17 +0300 (EEST) Received: from [172.31.218.44] (helo=vie01a-dmta-pe05-2.mx.upcmail.net) by vie01a-pqmta-pe01.mx.upcmail.net with esmtp (Exim 4.88) (envelope-from ) id 1flbB1-0007mf-TE for ffmpeg-devel@ffmpeg.org; Fri, 03 Aug 2018 16:35:35 +0200 Received: from [172.31.216.43] (helo=vie01a-pemc-psmtp-pe01) by vie01a-dmta-pe05.mx.upcmail.net with esmtp (Exim 4.88) (envelope-from ) id 1flbAw-0008BY-1v for ffmpeg-devel@ffmpeg.org; Fri, 03 Aug 2018 16:35:30 +0200 Received: from localhost ([213.47.41.20]) by vie01a-pemc-psmtp-pe01 with SMTP @ mailcloud.upcmail.net id JebM1y01D0S5wYM01ebNAb; Fri, 03 Aug 2018 16:35:23 +0200 X-SourceIP: 213.47.41.20 From: Michael Niedermayer To: FFmpeg development discussions and patches Date: Fri, 3 Aug 2018 16:34:51 +0200 Message-Id: <20180803143451.16825-1-michael@niedermayer.cc> X-Mailer: git-send-email 2.18.0 Subject: [FFmpeg-devel] [PATCH] avfilter/vf_hue: 10bit support 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: Michael Niedermayer --- libavfilter/vf_hue.c | 103 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 11 deletions(-) diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c index 45a5a1a92f..323333b33c 100644 --- a/libavfilter/vf_hue.c +++ b/libavfilter/vf_hue.c @@ -80,6 +80,9 @@ typedef struct HueContext { uint8_t lut_l[256]; uint8_t lut_u[256][256]; uint8_t lut_v[256][256]; + uint16_t lut_l16[65536]; + uint16_t lut_u10[1024][1024]; + uint16_t lut_v10[1024][1024]; } HueContext; #define OFFSET(x) offsetof(HueContext, x) @@ -117,6 +120,9 @@ static inline void create_luma_lut(HueContext *h) for (i = 0; i < 256; i++) { h->lut_l[i] = av_clip_uint8(i + b * 25.5); } + for (i = 0; i < 65536; i++) { + h->lut_l16[i] = av_clip_uintp2(i + b * 102.4, 10); + } } static inline void create_chrominance_lut(HueContext *h, const int32_t c, @@ -148,6 +154,25 @@ static inline void create_chrominance_lut(HueContext *h, const int32_t c, h->lut_v[i][j] = av_clip_uint8(new_v); } } + for (i = 0; i < 1024; i++) { + for (j = 0; j < 1024; j++) { + u = i - 512; + v = j - 512; + /* + * Apply the rotation of the vector : (c * u) - (s * v) + * (s * u) + (c * v) + * De-normalize the components (without forgetting to scale 512 + * by << 16) + * Finally scale back the result by >> 16 + */ + new_u = ((c * u) - (s * v) + (1 << 15) + (512 << 16)) >> 16; + new_v = ((s * u) + (c * v) + (1 << 15) + (512 << 16)) >> 16; + + /* Prevent a potential overflow */ + h->lut_u10[i][j] = av_clip_uintp2(new_u, 10); + h->lut_v10[i][j] = av_clip_uintp2(new_v, 10); + } + } } static int set_expr(AVExpr **pexpr_ptr, char **expr_ptr, @@ -231,6 +256,11 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA420P, + AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10, + AV_PIX_FMT_YUV420P10, + AV_PIX_FMT_YUV440P10, + AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_YUVA422P10, + AV_PIX_FMT_YUVA420P10, AV_PIX_FMT_NONE }; AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts); @@ -271,6 +301,22 @@ static void apply_luma_lut(HueContext *s, } } +static void apply_luma_lut10(HueContext *s, + uint16_t *ldst, const int dst_linesize, + uint16_t *lsrc, const int src_linesize, + int w, int h) +{ + int i; + + while (h--) { + for (i = 0; i < w; i++) + ldst[i] = s->lut_l16[lsrc[i]]; + + lsrc += src_linesize; + ldst += dst_linesize; + } +} + static void apply_lut(HueContext *s, uint8_t *udst, uint8_t *vdst, const int dst_linesize, uint8_t *usrc, uint8_t *vsrc, const int src_linesize, @@ -294,6 +340,29 @@ static void apply_lut(HueContext *s, } } +static void apply_lut10(HueContext *s, + uint16_t *udst, uint16_t *vdst, const int dst_linesize, + uint16_t *usrc, uint16_t *vsrc, const int src_linesize, + int w, int h) +{ + int i; + + while (h--) { + for (i = 0; i < w; i++) { + const int u = av_clip_uintp2(usrc[i], 10); + const int v = av_clip_uintp2(vsrc[i], 10); + + udst[i] = s->lut_u10[u][v]; + vdst[i] = s->lut_v10[u][v]; + } + + usrc += src_linesize; + vsrc += src_linesize; + udst += dst_linesize; + vdst += dst_linesize; + } +} + #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) #define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb)) @@ -305,6 +374,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) const int32_t old_hue_sin = hue->hue_sin, old_hue_cos = hue->hue_cos; const float old_brightness = hue->brightness; int direct = 0; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); + const int bps = desc->comp[0].depth > 8 ? 2 : 1; if (av_frame_is_writable(inpic)) { direct = 1; @@ -367,21 +438,31 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) if (!direct) { if (!hue->brightness) av_image_copy_plane(outpic->data[0], outpic->linesize[0], - inpic->data[0], inpic->linesize[0], - inlink->w, inlink->h); + inpic->data[0], inpic->linesize[0], + inlink->w * bps, inlink->h); if (inpic->data[3]) av_image_copy_plane(outpic->data[3], outpic->linesize[3], - inpic->data[3], inpic->linesize[3], - inlink->w, inlink->h); + inpic->data[3], inpic->linesize[3], + inlink->w * bps, inlink->h); } - apply_lut(hue, outpic->data[1], outpic->data[2], outpic->linesize[1], - inpic->data[1], inpic->data[2], inpic->linesize[1], - AV_CEIL_RSHIFT(inlink->w, hue->hsub), - AV_CEIL_RSHIFT(inlink->h, hue->vsub)); - if (hue->brightness) - apply_luma_lut(hue, outpic->data[0], outpic->linesize[0], - inpic->data[0], inpic->linesize[0], inlink->w, inlink->h); + if (bps > 1) { + apply_lut10(hue, (uint16_t*)outpic->data[1], (uint16_t*)outpic->data[2], outpic->linesize[1]/2, + (uint16_t*) inpic->data[1], (uint16_t*) inpic->data[2], inpic->linesize[1]/2, + AV_CEIL_RSHIFT(inlink->w, hue->hsub), + AV_CEIL_RSHIFT(inlink->h, hue->vsub)); + if (hue->brightness) + apply_luma_lut10(hue, (uint16_t*)outpic->data[0], outpic->linesize[0]/2, + (uint16_t*) inpic->data[0], inpic->linesize[0]/2, inlink->w, inlink->h); + } else { + apply_lut(hue, outpic->data[1], outpic->data[2], outpic->linesize[1], + inpic->data[1], inpic->data[2], inpic->linesize[1], + AV_CEIL_RSHIFT(inlink->w, hue->hsub), + AV_CEIL_RSHIFT(inlink->h, hue->vsub)); + if (hue->brightness) + apply_luma_lut(hue, outpic->data[0], outpic->linesize[0], + inpic->data[0], inpic->linesize[0], inlink->w, inlink->h); + } if (!direct) av_frame_free(&inpic);