From patchwork Tue Jun 28 13:41:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niklas Haas X-Patchwork-Id: 36512 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:8b27:b0:88:1bbf:7fd2 with SMTP id l39csp2661922pzh; Tue, 28 Jun 2022 06:43:16 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sbfzTRb/9B/zmcpBn1sg6PLlE+bZhbbW8Mg89Xvwoq2gps9Yw7PB6H78JfC3Cg5YzvMSw0 X-Received: by 2002:a17:907:da9:b0:726:cc6f:a7a7 with SMTP id go41-20020a1709070da900b00726cc6fa7a7mr3968242ejc.276.1656423796508; Tue, 28 Jun 2022 06:43:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656423796; cv=none; d=google.com; s=arc-20160816; b=FYvSuDRAHnTfJquHyNnCpibLRcrtkhNOqbodh/l1Yw3QrHSv+5/ywsIcMHGUrxkmkx 4ocFSlxrP7irkEI7SVtWh02tRncrpuZ8QE7pz8X2saxKYJB+beC0IGfNler95um4+0xS zZuzeX7m2XTTpVNkVJM82lk264cr/+T5E1DbEKENPszY8EKloYXRPeYycllBTiJFmqfy ZTeYPeRJXYQIVMQkuH69iU2ekXiBm5b7m8DjiUEwBvCc4whc2Jpmx4PO0cv1wLsCpKqL PDfwLyjRmFwqyWsavpnv7KEovSccfa0E3pwX0YzB2ZbtTlSdOj/vgRYxlu4KcdtvpvfA 0jmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc: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=7koY8aCXeRQv0C6pC8Yt/IGCpWrN7lDmSWkTP9a6oBQ=; b=aSKf7bhnRSsSzVIQAfvjKU491e6A+fSPLky1FKHeof6WGxBT4Fr2UDYOD1zOJfZTHg kd3wYVdZnMaG7CR5EsVEzk7ndXxYekgt+nUdjbkv8XxvbFEtbr3OBVArdQbyndiXKL/v u2jQHTdzchJOCoGX4uFoytQGB3l6bya7Uqjb1okZSyW4sgKzxzzpOepSvfOT1v21FCtF +/4IFYJ5DjxWiauWDRWZt6P/3tIPEz7eSowDfB+GI5Bfd4HzOKsWX4fqXl0D7xPux4Cy UrdpvcDK8s8qaaz4/OfRkchZ0l+vLzNYwCVJ+srE2jLH7QqjXTojrcTHFS2MtV7pR/v1 NAgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@haasn.xyz header.s=mail header.b=Gtd6U1oK; 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 n18-20020aa7c692000000b0042ecc123b85si3022928edq.24.2022.06.28.06.43.16; Tue, 28 Jun 2022 06:43:16 -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=@haasn.xyz header.s=mail header.b=Gtd6U1oK; 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 500B968B98F; Tue, 28 Jun 2022 16:42:30 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from haasn.dev (haasn.dev [78.46.187.166]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C081B68B989 for ; Tue, 28 Jun 2022 16:42:21 +0300 (EEST) Received: from haasn.dev (unknown [10.30.0.2]) by haasn.dev (Postfix) with ESMTP id A83E24A783; Tue, 28 Jun 2022 15:42:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=haasn.xyz; s=mail; t=1656423737; bh=K8p3Z7uVZSGJ0iBxVZ22zs/7KbFu/3g1sVjqJSM8A9A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Gtd6U1oKL7ya2NpzDNR8lnY9a2YN+k614tBwyR+5VYeZSAyiD2NBcZqPGPO/jr66I WmcFamOX0rrQ56W1YoHWuOO7KE8+xmYRPi0zshsUwCYnzojvt5I8zPeJMMPeFc54iO Rlv1EZjvGqnBgixa0u6NcSzAHztGb48LPMb0mjWY= From: Niklas Haas To: ffmpeg-devel@ffmpeg.org Date: Tue, 28 Jun 2022 15:41:11 +0200 Message-Id: <20220628134110.87770-7-ffmpeg@haasn.xyz> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220628134110.87770-1-ffmpeg@haasn.xyz> References: <20220628134110.87770-1-ffmpeg@haasn.xyz> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 6/6] avcodec/encode:: generate ICC profiles 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 Cc: Niklas Haas Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: Iw9WYOXNqfg4 From: Niklas Haas Only if requested, and only if the codec signals support for ICC profiles. Implementation roughly matches the functionality of the existing vf_iccgen filter, albeit with some reduced flexibility and no caching. Ideally, we'd also only do this on the first frame (e.g. mjpeg, apng), but there's no meaningful way for us to distinguish between this case and e.g. somebody using the image2 muxer, in which case we'd want to attach ICC profiles to every frame in the stream. Closes: #9672 Signed-off-by: Niklas Haas --- libavcodec/encode.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index b68bf1e184..978e32bd4b 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -308,6 +308,50 @@ static int encode_receive_packet_internal(AVCodecContext *avctx, AVPacket *avpkt return ret; } +#if CONFIG_LCMS2 +static int encode_generate_icc_profile(AVCodecContext *avctx, AVFrame *frame) +{ + enum AVColorTransferCharacteristic trc = frame->color_trc; + enum AVColorPrimaries prim = frame->color_primaries; + const FFCodec *const codec = ffcodec(avctx->codec); + AVCodecInternal *avci = avctx->internal; + cmsHPROFILE profile; + int ret; + + if (!avctx->icc_profiles || !(codec->caps_internal & FF_CODEC_CAP_ICC_PROFILES)) + return 0; /* don't generate ICC profiles if disabled or unsupported */ + + if (trc = AVCOL_TRC_UNSPECIFIED) + trc = avctx->color_trc; + if (prim == AVCOL_PRI_UNSPECIFIED) + prim = avctx->color_primaries; + if (trc == AVCOL_TRC_UNSPECIFIED || prim == AVCOL_PRI_UNSPECIFIED) + return 0; /* can't generate ICC profile with missing csp tags */ + + if (av_frame_get_side_data(frame, AV_FRAME_DATA_ICC_PROFILE)) + return 0; /* don't overwrite existing ICC profile */ + + if (!avci->icc.avctx) { + ret = ff_icc_context_init(&avci->icc, avctx); + if (ret < 0) + return ret; + } + + ret = ff_icc_profile_generate(&avci->icc, prim, trc, &profile); + if (ret < 0) + return ret; + + ret = ff_icc_profile_attach(&avci->icc, profile, frame); + cmsCloseProfile(profile); + return ret; +} +#else /* !CONFIG_LCMS2 */ +static int encode_generate_icc_profile(av_unused AVCodecContext *c, av_unused AVFrame *f) +{ + return 0; +} +#endif + static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src) { AVCodecInternal *avci = avctx->internal; @@ -352,6 +396,12 @@ static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src) return ret; } + if (avctx->codec->type == AVMEDIA_TYPE_VIDEO) { + ret = encode_generate_icc_profile(avctx, dst); + if (ret < 0) + return ret; + } + return 0; }