From patchwork Wed Jun 29 10:12:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Niklas Haas X-Patchwork-Id: 36528 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:8b27:b0:88:1bbf:7fd2 with SMTP id l39csp207264pzh; Wed, 29 Jun 2022 03:14:09 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sEfoxgzPaJyMBx8hVv9PI2+jixHuG+RDKLUnxyvneG/KK4e4IG5M8DFpGJZvi+wP9Gq53W X-Received: by 2002:a05:6402:270a:b0:437:63ea:f2b5 with SMTP id y10-20020a056402270a00b0043763eaf2b5mr3238611edd.33.1656497649496; Wed, 29 Jun 2022 03:14:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656497649; cv=none; d=google.com; s=arc-20160816; b=TQ4VvrV5KMu7QznI4arQGKMWMZYXRa1aT20+2ErRhQkFJV1i84xsOCMB9vHM/zfMNw sc+iX8JYano3vTN3d60mFfNzHZTzqbxmXvSjsyXfNW+v1T6yEh+dvp2xXylCjMhvjEaI jze4Vvt9uD34fUf2AXR16CvMfmndpQ0LvrqYTfixzO4v0/mNx1eYQZ2Jbm2qkVZzzm9X sMDdpW2Dx5au0WP+k5+3cTGZFcXmd7GKHcV0Zrztz/zE9ci/HYRQU83OKJI2O72q+2uB SeKzxUXwMEOKijUmOTFXuiOyRODWUlOvuym5TuOI1bMC6gbJQCjiVYBXJwG3Swfj9qqC u9wQ== 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=ddBHRuRtmdFFmv1Fu3fMWPrwxazyECo1XW7Iu4oahkY=; b=sEbIWQWVyKxvbFhtw9IzyK7DL/MJQSWzKU/avwZTGE+EM9Wa85l2xSuOmzEyopDiD2 KHNn9FZnfPYETg/Q2KdjWdJift0WJ2BTDTcZk3RLYLcKf5iouBDf8KnhJQl6vRkDLFVE X0ejixthvTig+7FrGRaXY762E5dncJOqUt/4Y1TrLciqdWTb6RSZw56znfD5n9ZqJRRo 1IJDP+tuYS8dkCvWAzYI2A8yzfPcJPl3rARxJj3Hf9Cn0iy+Tizft/boyRuJS4e+smQc FgqqMjdCraWUoVepi9NTDuWuznmCAukS16WdoR6aQ29Yarwdu7V2mV2unlW69gU9RW9y +o8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@haasn.xyz header.s=mail header.b=pzzu9nf4; 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 f20-20020a056402355400b0043774af6f0asi3895907edd.371.2022.06.29.03.14.07; Wed, 29 Jun 2022 03:14:09 -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=pzzu9nf4; 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 A575A68B73C; Wed, 29 Jun 2022 13:13:09 +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 689E668B704 for ; Wed, 29 Jun 2022 13:13:01 +0300 (EEST) Received: from haasn.dev (unknown [10.30.0.2]) by haasn.dev (Postfix) with ESMTP id 0449C4A7F4; Wed, 29 Jun 2022 12:12:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=haasn.xyz; s=mail; t=1656497579; bh=2eXqwu4pHKH+Mjil0Bi++fsFEfcpHZO7ScOluSPGUQ4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pzzu9nf4PRBD/E/RHLVLQpKEH3Kk50Rw10GuP8/FaKESjht6wtS3nWt+duOmsEWC/ 4F/Ep/2daov8Q6Lh7lP+A2SnTkfMsE0s7jp10dAcDl+TNTFvRch1TmWa7ahoHkRomV F8DSsj3VycajW0kxNL8fSrFKadFXXpPEVdH9rYqQ= From: Niklas Haas To: ffmpeg-devel@ffmpeg.org Date: Wed, 29 Jun 2022 12:12:51 +0200 Message-Id: <20220629101251.13236-7-ffmpeg@haasn.xyz> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220629101251.13236-1-ffmpeg@haasn.xyz> References: <20220629101251.13236-1-ffmpeg@haasn.xyz> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 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: KUZXKd4aeZMN 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..d1fb6f3a75 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; }