From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 5549B4DE7C for ; Sat, 5 Jul 2025 18:21:05 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 1B2C669066C; Sat, 5 Jul 2025 21:21:02 +0300 (EEST) To: "ffmpeg-devel@ffmpeg.org" Date: Sat, 5 Jul 2025 18:20:50 +0000 MIME-Version: 1.0 Message-ID: List-Id: FFmpeg development discussions and patches List-Post: From: Sarthak Indurkhya via ffmpeg-devel Precedence: list Cc: Sarthak Indurkhya X-Mailman-Version: 2.1.29 X-BeenThere: ffmpeg-devel@ffmpeg.org List-Subscribe: , List-Unsubscribe: , List-Archive: Reply-To: FFmpeg development discussions and patches List-Help: Subject: [FFmpeg-devel] [PATCH] avfilter: add inverse tone mapping Content-Type: multipart/mixed; boundary="===============7677634792933913416==" Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: --===============7677634792933913416== Content-Type: message/rfc822 Content-Disposition: inline Return-Path: X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from NAM10-DM6-obe.outbound.protection.outlook.com (mail-dm6nam10on2050.outbound.protection.outlook.com [40.107.93.50]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 6D62E690640 for ; Sat, 5 Jul 2025 21:20:55 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=kpd8snLViNkH1h/KP5pGYamN8h4UZbDcO2JLDvESnmomy25p4agOcSBL5fveub+rGZY3jkoIfPOG0saign1wqZvRqYFzF3LsMZa9yI+2nwI+ZBY8q7NR25ZEqEEGoXbEeKRMUQzxsA4bgEOoLNT2jOBT3mcuCXTyYg+hFTRSwUtUtbK0KSh4/ei9IJmB9Z4ApZ81yzGjE5112C12GxvASXFFjAoyrKs1VAbcwQ0GIPogx7FnzVGCKp0BhrnHUb+sc+EQjQJyuqT4tc0ECUQfqakxAKGUaog82MXHS0MRKHC655HNuqrkXc1OpSDPCdqivFJjowcnrn653Bo0sleqOQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=eeCEfeEqsPg0K/8pQ5rFJ2J5CAY24KXQM7wUIInyTz8=; b=yYwXcZYlz5u8lsiJiqG3UeCOLVRcIhLiJko7S6tUpK83gb477FhLJi0rsGPxF6vMKrmIh2oSvRQ0eXufhcUikZlGu92n9cEHNOSKjQ67Cl9dl7XiLZ3ETD+AWE+D1NShYZLWylvKZIWmiAb3i+yGpd0eBL7GMeWZnMaoDJV99JKx/emlTtGtUhfom4aW32koh5NMdbiyLzCVsqt3PPuhOajRaJzQddCOHE9I9bmy5KAK4opLWt+H1ogqEYvSHDodL7qQqHHLO2aXo9+dP4T/U0Hz3oS742PCcZ2rT+yUtTX7Q+ubiMr0PTSI5BDyrs1yCewgJmNLxQPG5SRwsdYa7g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=adobe.com; dmarc=pass action=none header.from=adobe.com; dkim=pass header.d=adobe.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adobe.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=eeCEfeEqsPg0K/8pQ5rFJ2J5CAY24KXQM7wUIInyTz8=; b=rqnIcD/VgPtk/lDldIeYm3EdgG5h7YU3n0UDoqx+16J9IhshbiqczcP57IoM+uouwlUOZPO5+gvFoZmvGxZchg71m24ifeAebTy5YQx+XtBNWGbKOHnnx60vNEBhAF6ST1qWxTqKptLkM/gx9XQ7EeqZZx6j3eQp/hTwSbVo1DY= Received: from BN0PR02MB7887.namprd02.prod.outlook.com (2603:10b6:408:14b::16) by BY5PR02MB6930.namprd02.prod.outlook.com (2603:10b6:a03:23e::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8901.23; Sat, 5 Jul 2025 18:20:50 +0000 Received: from BN0PR02MB7887.namprd02.prod.outlook.com ([fe80::5019:a130:f524:7826]) by BN0PR02MB7887.namprd02.prod.outlook.com ([fe80::5019:a130:f524:7826%3]) with mapi id 15.20.8901.021; Sat, 5 Jul 2025 18:20:50 +0000 From: Sarthak Indurkhya To: "ffmpeg-devel@ffmpeg.org" Subject: [PATCH] avfilter: add inverse tone mapping Thread-Topic: [PATCH] avfilter: add inverse tone mapping Thread-Index: AQHb7djWcWZe8LayD0mOjiVjF/tqZg== Date: Sat, 5 Jul 2025 18:20:50 +0000 Message-ID: Accept-Language: en-IN, en-US Content-Language: en-IN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-reactions: allow authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=adobe.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: BN0PR02MB7887:EE_|BY5PR02MB6930:EE_ x-ms-office365-filtering-correlation-id: 05bde9fe-2c22-46bd-efa9-08ddbbf0ab9a x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0;ARA:13230040|376014|366016|1800799024|8096899003|38070700018; x-microsoft-antispam-message-info: =?us-ascii?Q?TMqBDaB1znQjhv6Jp9/tj8CRPGyI8LNhmLfxAheDcgL52Rhzj0oMcosUclxU?= =?us-ascii?Q?C/3cup7bfyfc0nx9dJsr8Id8zFvT3F3aV2/4Z1C7g6GWc6hXm+X653ial99z?= =?us-ascii?Q?bnuSCwhvubc5fwTtIAz34SodBd+PIpi/Xmy0yODZOdqE9O1prd1JA9xziUnU?= =?us-ascii?Q?wXp6WY/p+xYGnSmWjSejx/f5k6MkI/6rAqV+aX/S+fGWX+UEG0wZ/su0ScPd?= =?us-ascii?Q?0WuAL1zFGOFNaJiGd98vjUvwniyDnSB/cH2cTg+u4w32KbKmGlLpFZnuWVJ7?= =?us-ascii?Q?nY4DGKVAYRVTJlfjsHAMGgh06FN6pWiRff5tlBPZkR7ZRX8hG4ojuNG5Q/9h?= =?us-ascii?Q?A1IRPCoyVlZtel4nmc30rgMHSxQbMvGGcRzLsdchsUbfwzRPZDf3W59wS/y2?= =?us-ascii?Q?h37JrBIuoteiBB14+a/krYO7dld/CELa6MF4BGUB84yAFXFKlJ3yJA5F6oIT?= =?us-ascii?Q?LGtTGz6mC1NjMFHxO43RRAj7NJ0Zkp3nRtds9y5K/DsIuOWGnftuC/eZsjGt?= =?us-ascii?Q?Abl77hUpMvqWQGQKNg3l0ngJ0omBrrbi8GjNDb5prv5IEGxqX0pS33qkwZD9?= =?us-ascii?Q?0fuz2CXZVnSg1ZfbQEdKphyBOn4A//OYSOwdCQ6ZKa6JO9OTa/xh1W7h2hti?= =?us-ascii?Q?m2VvJDkqOo1PavH+Irz+i55oN14J583qXvyw39PGR2mCFLFLyNCj15WXBN/8?= =?us-ascii?Q?QX/i+W6Uk6Eq+7z2UQ4Z9ShB0bIy+j2AFT9BbBcxhJ2ws04KC0U3g3bHnMB0?= =?us-ascii?Q?p2Py6ct/ZxnhAFxdxKHELs+IYY1wrKuXgWUyDy8//iLP9gRypNFihnB+KkMu?= =?us-ascii?Q?87x2y2D9F+GK6fTisYcLABZJDi3UKwYXv3RhhDoSuwaPf7IEF+8sR38EFzWG?= =?us-ascii?Q?vW4i1/nmt2pOzpNTbz4w0C9YYHYvrDTm2TemQQfxLwZ8qSMXXSjzAKBwYT+K?= =?us-ascii?Q?e7A2Zcuiz1gEBbjDC6vMkG3+0jocTbMgEwrDMG3OBxN7nDun7lYPlz9zso/J?= =?us-ascii?Q?BkKm1SmS7c1aPkm2vt6UGftWJjMnU2SbXO03gmMJB2SaGJiuMXwLkzbZb1Fm?= =?us-ascii?Q?5/UtNBhEFLd/uOHyElC8oFCUTMGHtdWPJeTplXhUc4NExjfYVvCYsaD9btSz?= =?us-ascii?Q?gwU3SvEtEFp4xlfmhSXQS74KYJjV5BXWQY9XD8bCsQBPAElF8tGnJTOrKSI+?= =?us-ascii?Q?FqyqvYxA0Kz63foXCqo9DxuZsecRuFgsLQdYeARVR4QQ2ckV0a7DPKykYnP6?= =?us-ascii?Q?Bqbu714LZIeEh0tfOBdwHqOj9OsRFXsD95jspgLHsZTd4qAj/hQkso+ltkX9?= =?us-ascii?Q?3+979W1oR4y6vw7uEkHCRbZxm5okKalohpPnVWyxBUSlDIf04tKJl2g9+5Lv?= =?us-ascii?Q?8yDTtggLHjnSg9n7rIQqLSucdSe3bN+E5RI7lLknMQx3wCZ86t46pO6yoFsT?= =?us-ascii?Q?VvOkLKaBOQo=3D?= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BN0PR02MB7887.namprd02.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024)(8096899003)(38070700018);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?cggPzGbfK0j/rAEiAhXjvOe5/1Dsi6I00ve7CqB/qyY75Zsk/hH9Tc3LFOEY?= =?us-ascii?Q?1RHiGPYn94q076sKfFsiW/E9cGpMeOzb6SwhsKkJThcOHepn0wTIMwPb9qqX?= =?us-ascii?Q?mnoXNqtad54j2uttq7/yEJYBSIgVglsFDLwm2jZZHr1lBi+00ViaJch+/cKW?= =?us-ascii?Q?wpQFwcfsflUUodMoOASL0Tokcc75xkeIITTJs0i6gizvuRyeYGBhAshBJKlZ?= =?us-ascii?Q?gBf0Tcjn1SU/lY7Xaot318y1XfQbavEnP11PuGzKKLZg8i8IAhASDkBNZm+k?= =?us-ascii?Q?pn9nM5yxe0l4toCKURIkG419BeJM1kvVbfZXihsDAUtB7BWwpCk4iP7QP5WO?= =?us-ascii?Q?WqPky9NygJ1TJYWaPCM4wlwlMJCZvADBf/yS+Gy/8Pkw+hjzWADh0VrW5IX2?= =?us-ascii?Q?4CGmSrZ2aJd0MlGX06tqBJP5+bMwkMxq/rahKiv9xcipOKKulrnKuH7ARlrk?= =?us-ascii?Q?hkGgQBsqdHr3SV1l8ePN4+WRiuJck7vfDEluB7mgJKUkYQAkL0m7YLV9aRYw?= =?us-ascii?Q?TzgLr7acOYHtJl129bWx4lS2tYfCnzpQRNM5ttQKXGkQC6PGJfs22nkD0TL0?= =?us-ascii?Q?TJ8QSuNtIzdalmd9mAuiex0IRjlt2jfkCHlw2GRKIuhSxAdfv9b8E4hnca4J?= =?us-ascii?Q?QWJAQuEBf20SkzoqeR3Hd6TvH2fp9fejx2IQFFLFUHserYZN2NaeGAM6ni1d?= =?us-ascii?Q?02oc0KOmPo/eyeFoWuuXkPzTAXByBcfBGidU2z3qbRmPj0VVE6cRsfeFYwlS?= =?us-ascii?Q?SMfaGxLEFc/xmZdj0+gmefvj3Z8lxjkFAOspF4OSJoPIhrjVgJ5FahxAFQl3?= =?us-ascii?Q?WbWtC3Txg0nFB5j9jdNpt0SahsDYl7T0hCXXCM7K7IKw9Ne4RXD2oZnZ92tK?= =?us-ascii?Q?3gLOdMpaWEIeLPmX2cCrYf+G1Wvo3c/GhMx9YcUv14mUrXw4bDKGgrVpCgSK?= =?us-ascii?Q?p7N6sPFQ/06ZY1zWJT2rLLnhGj3AGzUpiujZlIlfZPHkh0t7pguqhbcV4ZPV?= =?us-ascii?Q?1U3sUozusFPGYl4PBNTZBUSJ3f0HMVmSo+e13JtWhclIIAF0nh8x9wdKlMB0?= =?us-ascii?Q?MM5w+kAWCNh8Bj3SaF30cMqS4PHxWh+iPUFYi6EwKjA3ETve1jPFevF5ztal?= =?us-ascii?Q?0rOciBpl1OltOuYd2dqcmwFGdiiGhT1ANTzkYMBd3jpSjaLCQTvFF/E0ysm6?= =?us-ascii?Q?LGR3S4GxVZ8sgDMppIKBBtk518lfQURInirG4uJVr65hk4gO3bJwq+UkDbc0?= =?us-ascii?Q?kZ5Z/iYrQrZkKmWB4GWDDSfgmggpwyn9l6gnbSyn43QHnbmkkQLgIjkaIvc7?= =?us-ascii?Q?uXw9tNiI4+Cc9esr89t7SMDLz7bZh31sYJjRngTQRJT28E+eTos1bI0yrlS4?= =?us-ascii?Q?IZgmguZJiMkskny3ChWKuy/IMphXCCw+SNg8pV3re+wK44s5S4IGUPOgyhoc?= =?us-ascii?Q?EzdHC02QclnYLoim5a3utX+qtdcbRR7gC5aX4Q7R3OwX8Vn/+VNsddgXb/0p?= =?us-ascii?Q?6kpN0P6ljxJ/BmKbgF3nZftzTpbkSDZcBflBUrjd4kJnwhLc39z6fZXksHSg?= =?us-ascii?Q?LzBys9tUPVtGxkEUF3w9DNFLpOTrqCb4EhdsC5dKDxsdDlRGpxTHmwMO7DNw?= =?us-ascii?Q?Qw=3D=3D?= MIME-Version: 1.0 X-OriginatorOrg: adobe.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BN0PR02MB7887.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 05bde9fe-2c22-46bd-efa9-08ddbbf0ab9a X-MS-Exchange-CrossTenant-originalarrivaltime: 05 Jul 2025 18:20:50.1903 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: fa7b1b5a-7b34-4387-94ae-d2c178decee1 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: j1J2Isnes/6JqnJ9dITRQ9qiVkG0zMhULPULZjixjQgiZQALt82oFO3YjPDSH7ZtgB55EO/pCv4fGm7m+izENg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY5PR02MB6930 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.29 Hello FFmpeg developers, This patch introduces a new video filter called inversetonemap for FFmpeg. The filter performs SDR to HDR conversion by mapping SDR BT.709 video to HD= R BT.2020 PQ, using local adaptation and inverse tone mapping. The goal is = to provide a simple, flexible tool for upconverting SDR content for HDR dis= plays, with local adaptation, tone curve sensitivity, and chroma processing= . Please review. Thanks, Sarthak -- >From f563ee1ad93511dfe7dd252578d7801e0cbbe968 Mon Sep 17 00:00:00 2001 From: Sarthak Indurkhya sarthak@Sarthaks-MacBook-Pro.local Date: Sat, 5 Jul 2025 22:33:46 +0530 Subject: [PATCH] avfilter: add inversetonemap filter This filter performs inverse tone mapping from SDR to HDR using local adapt= ation and PQ mapping. - Added inversetonemap video filter for SDR to HDR conversion. --- Changelog | 1 + libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/vf_inversetonemap.c | 98 ++++++++++++++++----------------- 4 files changed, 51 insertions(+), 50 deletions(-) diff --git a/Changelog b/Changelog index 81e2cc813f..0aecf6dbf1 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,7 @@ Entries are sorted chronologically from oldest to youngest = within each release, releases are sorted from youngest to oldest. version : +- Added inversetonemap video filter for SDR to HDR conversion. - yasm support dropped, users need to use nasm - VVC VAAPI decoder - RealVideo 6.0 decoder diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 97f8f17272..e715a3a5e4 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -191,6 +191,7 @@ OBJS-$(CONFIG_SINE_FILTER) +=3D asrc_= sine.o OBJS-$(CONFIG_ANULLSINK_FILTER) +=3D asink_anullsink.o # video filters +OBJS-$(CONFIG_INVERSETONEMAP_FILTER) +=3D vf_inversetonemap.o OBJS-$(CONFIG_ADDROI_FILTER) +=3D vf_addroi.o OBJS-$(CONFIG_ALPHAEXTRACT_FILTER) +=3D vf_extractplanes.o OBJS-$(CONFIG_ALPHAMERGE_FILTER) +=3D vf_alphamerge.o framesync= .o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 3bc045b28f..2f67300ca1 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -176,6 +176,7 @@ extern const FFFilter ff_asrc_sine; extern const FFFilter ff_asink_anullsink; +extern const FFFilter ff_vf_inversetonemap; extern const FFFilter ff_vf_addroi; extern const FFFilter ff_vf_alphaextract; extern const FFFilter ff_vf_alphamerge; diff --git a/libavfilter/vf_inversetonemap.c b/libavfilter/vf_inversetonema= p.c index 28ea1ef29e..d8d8920151 100644 --- a/libavfilter/vf_inversetonemap.c +++ b/libavfilter/vf_inversetonemap.c @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2025 Sarthak Indurkhya + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-130= 1 USA + */ + /** * @file * @brief SDR to HDR inverse tone mapping filter for FFmpeg @@ -38,7 +57,7 @@ typedef struct FilterContext { float HDR_max; } FilterContext; -//declaring lookup table + static float bt709_gamma_lut[256]; static void init_bt709_gamma_lut(void) { @@ -51,14 +70,13 @@ static void init_bt709_gamma_lut(void) { } } -// Rec.709 to Rec.2020 matrix + static const float bt709_to_bt2020[3][3] =3D { {0.6274f, 0.3293f, 0.0433f}, {0.0691f, 0.9195f, 0.0114f}, {0.0164f, 0.0880f, 0.8956f} }; -// PQ transfer function #define PQ_M1 0.1593017578125f #define PQ_M2 78.84375f #define PQ_C1 0.8359375f @@ -80,12 +98,10 @@ static void compute_local_adaptation(const float *R_ful= l, float *sigma, int widt float *temp_blur =3D av_mallocz(npix * sizeof(float)); float *spatial_weights =3D av_malloc((2 * radius + 1) * sizeof(float))= ; - // 1D Gaussian kernel for separable blur for (int i =3D -radius; i <=3D radius; i++) { spatial_weights[i + radius] =3D expf(-(i * i) / (2 * sigma_spatial= * sigma_spatial)); } - // Scene max luminance float scene_max =3D 1e-6f; for (int i =3D 0; i < npix; i++) { if (R_full[i] > scene_max) @@ -93,7 +109,6 @@ static void compute_local_adaptation(const float *R_full= , float *sigma, int widt } float hdr_scale =3D HDR_max / scene_max; - // ---- Horizontal blur pass ---- for (int y =3D 0; y < height; y++) { for (int x =3D 0; x < width; x++) { float sum =3D 0.0f, sum_weights =3D 0.0f; @@ -113,7 +128,6 @@ static void compute_local_adaptation(const float *R_ful= l, float *sigma, int widt } } - // ---- Vertical blur pass ---- for (int y =3D 0; y < height; y++) { for (int x =3D 0; x < width; x++) { float sum =3D 0.0f, sum_weights =3D 0.0f; @@ -137,18 +151,15 @@ static void compute_local_adaptation(const float *R_f= ull, float *sigma, int widt av_free(spatial_weights); } static void compute_local_adaptation_fast(const float *R_full, float *sigma= , int width, int height, - float sigma_spatial, float sigma_range, float HDR_max) -{ + float sigma_spatial, float sigma_range, float HDR_max){ const int scale =3D 4; int down_w =3D width / scale; int down_h =3D height / scale; int npix_small =3D down_w * down_h; - // Allocating downsampled and result buffers float *R_small =3D av_malloc(npix_small * sizeof(float)); float *sigma_small =3D av_malloc(npix_small * sizeof(float)); - // Simple box downsampling for (int y =3D 0; y < down_h; y++) { for (int x =3D 0; x < down_w; x++) { float sum =3D 0.0f; @@ -167,7 +178,6 @@ static void compute_local_adaptation_fast(const float *= R_full, float *sigma, int compute_local_adaptation(R_small, sigma_small, down_w, down_h, sigma_s= patial, sigma_range, HDR_max); - // Upsampling sigma_small -> sigma struct SwsContext *sws_ctx =3D sws_getContext(down_w, down_h, AV_PIX_F= MT_GRAYF32, width, height, AV_PIX_FMT_GRAYF32, SWS_BILINEAR, NULL, NULL, NULL); @@ -199,14 +209,12 @@ static void compute_hdr_intensity(const float *R_full= , const float *sigma, float static void inverse_tone_map_linear_rgb( const float *R, const float *G, const float *B, float *R_hdr, float *G_hdr, float *B_hdr, - int width, int height, FilterContext *s) -{ + int width, int height, FilterContext *s){ int npix =3D width * height; float *Y =3D av_malloc(npix * sizeof(float)); float *Y_sigma =3D av_malloc(npix * sizeof(float)); float *Y_hdr =3D av_malloc(npix * sizeof(float)); - // Computing luminance (BT.2020) for (int i =3D 0; i < npix; i++) Y[i] =3D 0.2627f * R[i] + 0.6780f * G[i] + 0.0593f * B[i]; @@ -215,7 +223,6 @@ static void inverse_tone_map_linear_rgb( compute_hdr_intensity(Y, Y_sigma, Y_hdr, width, height, s->n, 1.0f); - // Scaling RGB channels for (int i =3D 0; i < npix; i++) { float scale =3D Y_hdr[i] / (Y[i] + 1e-6f); R_hdr[i] =3D R[i] * scale; @@ -249,11 +256,20 @@ static void dither_pq_to_10bit(const float *pq, uint1= 6_t *y_temp, int width, int } static int fil_func(AVFilterLink *inlink, AVFrame *in) { + const float exposure =3D 3.5f; + const float contrast =3D 1.02f; + const float black =3D 0.03f; + const float white =3D 8.0f; + const float s_curve_pow =3D 1.00f; + const float white_balance_r =3D 1.0f; + const float white_balance_g =3D 1.0f; + const float white_balance_b =3D 1.1f; + AVFilterContext *ctx =3D inlink->dst; FilterContext *s =3D ctx->priv; int width =3D in->width, height =3D in->height, npix =3D width * heigh= t; - // Converting to RGB24 + struct SwsContext *sws_ctx =3D sws_getContext( width, height, in->format, width, height, AV_PIX_FMT_RGB24, @@ -272,9 +288,6 @@ static int fil_func(AVFilterLink *inlink, AVFrame *in) = { rgb_frame->data, rgb_frame->linesize); sws_freeContext(sws_ctx); - //Calling gamma lookup table initialization - init_bt709_gamma_lut(); - // Gamma linearization & gamut mapping float *R =3D av_malloc(npix * sizeof(float)); float *G =3D av_malloc(npix * sizeof(float)); float *B =3D av_malloc(npix * sizeof(float)); @@ -290,20 +303,21 @@ static int fil_func(AVFilterLink *inlink, AVFrame *in= ) { } } - // Inverse Tone Mapping float *R_hdr =3D av_malloc(npix * sizeof(float)); float *G_hdr =3D av_malloc(npix * sizeof(float)); float *B_hdr =3D av_malloc(npix * sizeof(float)); inverse_tone_map_linear_rgb(R, G, B, R_hdr, G_hdr, B_hdr, width, heigh= t, s); - float exposure =3D 3.5f; //4.0 - float contrast =3D 1.02f; //1.10 - float black =3D 0.03f, white =3D 8.0f; //0.04 //12.0 - float s_curve_pow =3D 1.00f; //0.70 + /* + float exposure =3D 3.5f; //4.0 + float contrast =3D 1.02f; //1.10 + float black =3D 0.03f, white =3D 8.0f; //0.04 //12.0 + float s_curve_pow =3D 1.00f; //0.70 + */ for (int i =3D 0; i < npix; i++) { - float r =3D R[i] * exposure, g =3D G[i] * exposure, b =3D B[i] * e= xposure; + float r =3D R_hdr[i] * exposure, g =3D G_hdr[i] * exposure, b =3D = B_hdr[i] * exposure; float lum =3D 0.2627f * r + 0.6780f * g + 0.0593f * b; @@ -316,21 +330,14 @@ static int fil_func(AVFilterLink *inlink, AVFrame *in= ) { g *=3D scale; b *=3D scale; - // Contrast r =3D (r - 0.5f) * contrast + 0.5f; g =3D (g - 0.5f) * contrast + 0.5f; b =3D (b - 0.5f) * contrast + 0.5f; - // White balance correction - float white_balance_r =3D 1.0f; - float white_balance_g =3D 1.0f; - float white_balance_b =3D 1.1f; - r *=3D white_balance_r; g *=3D white_balance_g; b *=3D white_balance_b; - // Final clamp r =3D fminf(fmaxf(r, 0.0f), 1.0f); g =3D fminf(fmaxf(g, 0.0f), 1.0f); b =3D fminf(fmaxf(b, 0.0f), 1.0f); @@ -340,18 +347,16 @@ static int fil_func(AVFilterLink *inlink, AVFrame *in= ) { B_hdr[i] =3D b; } - //Computing linear luminance (BT.2020) float *Y =3D av_malloc(npix * sizeof(float)); for (int i =3D 0; i < npix; i++) Y[i] =3D 0.2627f * R_hdr[i] + 0.6780f * G_hdr[i] + 0.0593f * B_hdr= [i]; - // Applying PQ transfer float *pq =3D av_malloc(npix * sizeof(float)); for (int i =3D 0; i < npix; i++) { pq[i] =3D linear_to_pq(Y[i] * (10000.0f / s->HDR_max)); pq[i] =3D fminf(fmaxf(pq[i], 0.0f), 1.0f); } - //Allocating output frame (YUV420P10LE) + AVFrame *out =3D av_frame_alloc(); out->format =3D AV_PIX_FMT_YUV420P10LE; out->width =3D width; @@ -359,25 +364,21 @@ static int fil_func(AVFilterLink *inlink, AVFrame *in= ) { av_frame_get_buffer(out, 32); av_frame_copy_props(out, in); - // Setting HDR metadata + out->color_primaries =3D AVCOL_PRI_BT2020; - out->color_trc =3D AVCOL_TRC_SMPTE2084; // PQ + out->color_trc =3D AVCOL_TRC_SMPTE2084; out->colorspace =3D AVCOL_SPC_BT2020_NCL; - out->color_range =3D AVCOL_RANGE_MPEG; // Full range for HDR + out->color_range =3D AVCOL_RANGE_MPEG; - // Setting mastering display metadata if available if (out->metadata) { - // Mastering display primaries (BT.2020) av_dict_set(&out->metadata, "mastering_display_primaries", "0.708,0.292,0.170,0.797,0.131,0.046,0.3127,0.3290", 0)= ; - // Mastering display luminance (in nits) char luminance_str[64]; snprintf(luminance_str, sizeof(luminance_str), "%.1f,%.1f", - s->HDR_max, 0.001f); // Max luminance, min luminance + s->HDR_max, 0.001f); av_dict_set(&out->metadata, "mastering_display_luminance", luminan= ce_str, 0); - // Content light level char content_light_str[64]; float max_content_light =3D 0.0f; for (int i =3D 0; i < npix; i++) { @@ -389,12 +390,10 @@ static int fil_func(AVFilterLink *inlink, AVFrame *in= ) { av_dict_set(&out->metadata, "content_light_level", content_light_s= tr, 0); } - // Clearing Y, U, V planes av_frame_make_writable(out); for (int y =3D 0; y < height; y++) memset(out->data[0] + y * out->linesize[0], 0, out->linesize[0]); - // Dithering PQ to 10-bit Y plane uint16_t *y_temp =3D av_malloc(npix * sizeof(uint16_t)); dither_pq_to_10bit(pq, y_temp, width, height); for (int y =3D 0; y < height; y++) { @@ -402,7 +401,6 @@ static int fil_func(AVFilterLink *inlink, AVFrame *in) = { memcpy(row, y_temp + y * width, width * sizeof(uint16_t)); } - // Computing and encoding U, V chroma planes from original SDR RGB for (int y =3D 0; y < height / 2; y++) { uint16_t *u_row =3D (uint16_t *)(out->data[1] + y * out->linesize[= 1]); uint16_t *v_row =3D (uint16_t *)(out->data[2] + y * out->linesize[= 2]); @@ -425,8 +423,8 @@ static int fil_func(AVFilterLink *inlink, AVFrame *in) = { float U =3D (b - Y_sdr) / 1.8814f; float V =3D (r - Y_sdr) / 1.4746f; float chroma_blend =3D 1.0f - fminf(Y_sdr, 1.0f); - float chroma_boost =3D 0.85f * chroma_blend + 0.85f * (1.0f - = chroma_blend); //0.8 - // float chroma_boost =3D 1.08f; + float chroma_boost =3D 0.85f * chroma_blend + 0.85f * (1.0f - = chroma_blend); + U *=3D chroma_boost; V *=3D chroma_boost; U =3D fmaxf(fminf(U, 0.45f), -0.45f); @@ -471,7 +469,7 @@ static const AVFilterPad fil_outputs[] =3D { }; static int ff_filter_init(AVFilterContext *avctx) { - av_log_set_level(AV_LOG_DEBUG); + init_bt709_gamma_lut(); av_log(avctx, AV_LOG_INFO, "Initializing filter with 1 input and 1 out= put\n"); return 0; } -- 2.49.0 Get Outlook for Mac --===============7677634792933913416== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". --===============7677634792933913416==--