From patchwork Wed Jan 12 23:17:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Fabian 'Xaymar' Dirks X-Patchwork-Id: 33286 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:cd86:0:0:0:0:0 with SMTP id d128csp5065186iog; Wed, 12 Jan 2022 15:18:16 -0800 (PST) X-Google-Smtp-Source: ABdhPJy4gFCx5Wtvm/6n26YirTqYJ7hDURumUtPLIJpmttsieLHzuj9oKmUB9SpFN4SOqtWxtugw X-Received: by 2002:a05:6402:3554:: with SMTP id f20mr1681668edd.343.1642029496356; Wed, 12 Jan 2022 15:18:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642029496; cv=none; d=google.com; s=arc-20160816; b=B/7B2/95nogxTvLX9xiek4tVaLY1GfgxYsPvGFydgsjcP+ya29i9H3229cy+2TBaee 5AboDAL9NL9boXKtUW3eb+aKrfBhh0cOclRnVFCLUEbSHPuDLEUamsyy4efozijG8s29 8/53WPFiv+KjpnFeliixd3UUZbTrs1cSOGgGUaYIOKz9N6udyU313IpSkBHZ51TWTi1L qCd+aiHAHXzJwq7gvDtTvyl8k0ZmbFHxHUCVCH5MqAY+Q9bnsADx+f0kiHnIoD6BPkNI wCq6RlqfxL9SR8FmuJrAlqhjPihRqPIP/rv5u2djFAGEVcyXYtzqcfeV3qERhsrTnRa0 ywDQ== 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=3KMYfKGbDYpRblfCXKdassNOE1bmgCk0xRwqoD6/p04=; b=aafA5a2zMwJdIyBACnFoACoWQiYrP+JDnappOdwyCDj3yJ41Lu1uTreE8HiJvTwt1c Yc125YE8szaF+U6ykV8Pr9um5svDAxFECMFx/bYzzQ9L9rQpxRmZpotPYyYUznZO4GCu luPls6BaFo2ZlUCira1Mv1ufKKnoXMjK2SJeyZ/8ZYveezpthwcQleT2mqiiP1i9Wz4Q M+7mPqYrqN2P1GEKWPvYeEX3Giu92Fq0muFlR8STkOhnEunY2pCJqFKbfy+imW/oAAq4 Voluve/U00wOhfqzGD8kTlo1wStYrnVA+GUbW29Vgw1Il+2SEw/FE8HRepMU4gsQO873 NA7Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@xaymar.com header.s=2021 header.b=AFUuzUe+; 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; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=xaymar.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id a15si638294edn.5.2022.01.12.15.18.16; Wed, 12 Jan 2022 15:18:16 -0800 (PST) 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=@xaymar.com header.s=2021 header.b=AFUuzUe+; 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; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=xaymar.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0CD8968AEC1; Thu, 13 Jan 2022 01:17:59 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.xaymar.com (xaymar.com [95.217.118.166]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 45ACD68AD96 for ; Thu, 13 Jan 2022 01:17:51 +0200 (EET) Received: from localhost.localdomain (unknown [IPv6:2a02:8106:c:6a00:ccbc:cf2c:5bb9:d3cf]) by mail.xaymar.com (Postfix) with ESMTPSA id 660BC61332; Thu, 13 Jan 2022 00:17:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xaymar.com; s=2021; t=1642029470; bh=QGEEnvQRRKpGEJ0aw6Siu1qWwGxn6mlQZ0K5wokFI6Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AFUuzUe+bwrVMjzWWS6lJZ7Xfvuqh2OSS0kGc8zFX8vz3qer0O0YIHy+l338KWjzK smMJuWTtbleypc0lLMF67e54zesFl9d5+9Htj5zFeDAHenns7UTUQwmHtICkzczuEU SaubaOV3DkL1ElGpvtrUvdTUZKaxP6DQK0Gtf4QrNgLH9spQS5ClaoiEy44fEfk8eo TVhHW6Aetga7ZDD9+2XQMX9kIZB/igb2vJeaoj5+tWRSXs9fj5lLshomw/eom5puAH e+ye/+wvvyGedW31D2wN5LdIJ5Bu2/M4XpdNBGfqmswiu40EAt0Q6dB9H321JHQk++ aZTtuAZ62diOVrbJ7oBKNqYKaZ4w5UXrhwhKSntDu1yQFKZbqqF1NK4QVyIiyG52OI kUiufDJbYGp/SwUNEYtVkRrobqYeueyREUa8Kq3zZ14cX8V8pSKOOVVBzYgEJn8vm0 sYvlsWEAt3oORQyUz8s7EkXv0QY6lEEjzvBHUCmPV0jvoINogmYGFUXh0Ay1v1HFbe vvRWAmM9MsBlxHxf6rtJxGvRwvqzINwKasvbJ+wRf2EVW/BM/K1YI7PuedzS3azIHL Hn1MTXbIfFiT1heSdyn7YejSn/FBq7S0QuVbjwKrJQc8H/OMMWHeg4t+4VlbEuNzsK 5AdwwPH30IyLjQez14tQ= From: Michael Fabian 'Xaymar' Dirks To: ffmpeg-devel@ffmpeg.org Date: Thu, 13 Jan 2022 00:17:21 +0100 Message-Id: X-Mailer: git-send-email 2.34.1.windows.1 In-Reply-To: References: MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/5] avcodec/amfenc: Set all color metadata for AMF 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: Michael Fabian 'Xaymar' Dirks Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: RTAPKYDRRAW0 From: Michael Fabian 'Xaymar' Dirks Fixes the color information in the output from the AMD encoder being wrong, which led to weird transcoding results. This problem appeared out of thin air, and I've been unable to tie it to a specific driver that supports my hardware. Unfortunately this requires AMF SDK version 1.4.23 or later, but it should still work fine on older drivers. Theoretical support for HDR encoding is also now possible, although the implementation is not complete. I have no clear idea on how to generate AMFs HDR metadata structure, or where to even take this information from. --- libavcodec/amfenc.h | 1 + libavcodec/amfenc_h264.c | 48 +++++++++++++++++++++++++++++++++++++- libavcodec/amfenc_hevc.c | 50 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h index 358b2ef778..951e529362 100644 --- a/libavcodec/amfenc.h +++ b/libavcodec/amfenc.h @@ -21,6 +21,7 @@ #include +#include #include #include diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c index aeca99f7c6..009378e9f1 100644 --- a/libavcodec/amfenc_h264.c +++ b/libavcodec/amfenc_h264.c @@ -137,6 +137,8 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx) AMFRate framerate; AMFSize framesize = AMFConstructSize(avctx->width, avctx->height); int deblocking_filter = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0; + amf_int64 color_depth; + amf_int64 color_profile; if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den); @@ -194,10 +196,54 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx) AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_ASPECT_RATIO, ratio); } - /// Color Range (Partial/TV/MPEG or Full/PC/JPEG) + // Color Metadata + /// Color Range (Support for older Drivers) if (avctx->color_range == AVCOL_RANGE_JPEG) { AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, 1); + } else { + AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, 0); + } + /// Color Space & Depth + color_depth = AMF_COLOR_BIT_DEPTH_8; + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN; + switch (avctx->colorspace) { + case AVCOL_SPC_SMPTE170M: + if (avctx->color_range == AVCOL_RANGE_JPEG) { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601; + } else { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601; + } + break; + case AVCOL_SPC_BT709: + if (avctx->color_range == AVCOL_RANGE_JPEG) { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709; + } else { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709; + } + break; + case AVCOL_SPC_BT2020_NCL: + case AVCOL_SPC_BT2020_CL: + // !FIXME: Verify that this is correct on Hardware supporting it. + // !FIXME: Figure out how to decide on bit depth. + if (avctx->color_range == AVCOL_RANGE_JPEG) { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020; + color_depth = AMF_COLOR_BIT_DEPTH_10; + } else { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020; + color_depth = AMF_COLOR_BIT_DEPTH_10; + } + break; } + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_COLOR_BIT_DEPTH, color_depth); + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INPUT_COLOR_PROFILE, color_profile); + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_COLOR_PROFILE, color_profile); + /// Color Transfer Characteristics (AMF matches ISO/IEC) + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc); + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc); + /// Color Primaries (AMF matches ISO/IEC) + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_INPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries); + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries); + /// !TODO: AMF HDR Metadata generation // autodetect rate control method if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN) { diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c index 79541b9b2f..900e1482b4 100644 --- a/libavcodec/amfenc_hevc.c +++ b/libavcodec/amfenc_hevc.c @@ -104,6 +104,8 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx) AMFRate framerate; AMFSize framesize = AMFConstructSize(avctx->width, avctx->height); int deblocking_filter = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0; + amf_int64 color_depth; + amf_int64 color_profile; if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den); @@ -152,6 +154,54 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx) AMFRatio ratio = AMFConstructRatio(avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_ASPECT_RATIO, ratio); } + + // Color Metadata + /// Color Range (Support for older Drivers) + if (avctx->color_range == AVCOL_RANGE_JPEG) { + AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE, 1); + } else { + AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE, 0); + } + /// Color Space & Depth + color_depth = AMF_COLOR_BIT_DEPTH_8; + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN; + switch (avctx->colorspace) { + case AVCOL_SPC_SMPTE170M: + if (avctx->color_range == AVCOL_RANGE_JPEG) { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_601; + } else { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_601; + } + break; + case AVCOL_SPC_BT709: + if (avctx->color_range == AVCOL_RANGE_JPEG) { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709; + } else { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_709; + } + break; + case AVCOL_SPC_BT2020_NCL: + case AVCOL_SPC_BT2020_CL: + // !FIXME: Verify that this is correct on Hardware supporting it. + // !FIXME: Figure out how to decide on bit depth. + if (avctx->color_range == AVCOL_RANGE_JPEG) { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_2020; + color_depth = AMF_COLOR_BIT_DEPTH_10; + } else { + color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_2020; + color_depth = AMF_COLOR_BIT_DEPTH_10; + } + break; + } + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH, color_depth); + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_COLOR_PROFILE, color_profile); + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PROFILE, color_profile); + /// Color Transfer Characteristics (AMF matches ISO/IEC) + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc); + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, (amf_int64)avctx->color_trc); + /// Color Primaries (AMF matches ISO/IEC) + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_INPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries); + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries); // Picture control properties AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, ctx->gops_per_idr);