[FFmpeg-devel] [PATCH] avcodec/amfenc: properly set primaries, transfer, and matrix values
Damiano Galassi
damiog at gmail.com
Sat Oct 19 16:53:39 EEST 2024
HEVC and AV1 encoders had hard-coded color values for 8-bit and 10-bit depths,
and they were completely disregarding the provided values.
---
libavcodec/amfenc.c | 109 +++++++++++++++++++++++++++++++++++++++
libavcodec/amfenc.h | 2 +
libavcodec/amfenc_av1.c | 16 +++---
libavcodec/amfenc_h264.c | 10 ++--
libavcodec/amfenc_hevc.c | 15 +++---
5 files changed, 129 insertions(+), 23 deletions(-)
diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c
index 225fb9df27..a83f5b2013 100644
--- a/libavcodec/amfenc.c
+++ b/libavcodec/amfenc.c
@@ -917,6 +917,115 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
return ret;
}
+int ff_amf_get_color_primaries(AVCodecContext *avctx)
+{
+ amf_int64 color_primaries = AMF_COLOR_PRIMARIES_UNDEFINED;
+ switch (avctx->color_primaries) {
+ case AVCOL_PRI_BT709:
+ color_primaries = AMF_COLOR_PRIMARIES_BT709;
+ break;
+ case AVCOL_PRI_UNSPECIFIED:
+ color_primaries = AMF_COLOR_PRIMARIES_UNSPECIFIED;
+ break;
+ case AVCOL_PRI_RESERVED:
+ color_primaries = AMF_COLOR_PRIMARIES_RESERVED;
+ break;
+ case AVCOL_PRI_BT470M:
+ color_primaries = AMF_COLOR_PRIMARIES_BT470M;
+ break;
+ case AVCOL_PRI_BT470BG:
+ color_primaries = AMF_COLOR_PRIMARIES_BT470BG;
+ break;
+ case AVCOL_PRI_SMPTE170M:
+ color_primaries = AMF_COLOR_PRIMARIES_SMPTE170M;
+ break;
+ case AVCOL_PRI_SMPTE240M:
+ color_primaries = AMF_COLOR_PRIMARIES_SMPTE240M;
+ break;
+ case AVCOL_PRI_FILM:
+ color_primaries = AMF_COLOR_PRIMARIES_FILM;
+ break;
+ case AVCOL_PRI_BT2020:
+ color_primaries = AMF_COLOR_PRIMARIES_BT2020;
+ break;
+ case AVCOL_PRI_SMPTE428:
+ color_primaries = AMF_COLOR_PRIMARIES_SMPTE428;
+ break;
+ case AVCOL_PRI_SMPTE431:
+ color_primaries = AMF_COLOR_PRIMARIES_SMPTE431;
+ break;
+ case AVCOL_PRI_SMPTE432:
+ color_primaries = AMF_COLOR_PRIMARIES_SMPTE432;
+ break;
+ case AVCOL_PRI_EBU3213:
+ color_primaries = AMF_COLOR_PRIMARIES_JEDEC_P22;
+ break;
+ }
+ return color_primaries;
+}
+
+int ff_amf_get_transfer_characteristic(AVCodecContext *avctx)
+{
+ amf_int64 transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNDEFINED;
+ switch (avctx->color_trc) {
+ case AVCOL_TRC_BT709:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709;
+ break;
+ case AVCOL_TRC_UNSPECIFIED:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_UNSPECIFIED;
+ break;
+ case AVCOL_TRC_RESERVED:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_RESERVED;
+ break;
+ case AVCOL_TRC_GAMMA22:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_GAMMA22;
+ break;
+ case AVCOL_TRC_GAMMA28:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_GAMMA28;
+ break;
+ case AVCOL_TRC_SMPTE170M:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE170M;
+ break;
+ case AVCOL_TRC_SMPTE240M:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE240M;
+ break;
+ case AVCOL_TRC_LINEAR:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_LINEAR;
+ break;
+ case AVCOL_TRC_LOG:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_LOG;
+ break;
+ case AVCOL_TRC_LOG_SQRT:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_LOG_SQRT;
+ break;
+ case AVCOL_TRC_IEC61966_2_4:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_IEC61966_2_4;
+ break;
+ case AVCOL_TRC_BT1361_ECG:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_BT1361_ECG;
+ break;
+ case AVCOL_TRC_IEC61966_2_1:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_IEC61966_2_1;
+ break;
+ case AVCOL_TRC_BT2020_10:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_BT2020_10;
+ break;
+ case AVCOL_TRC_BT2020_12:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_BT2020_12;
+ break;
+ case AVCOL_TRC_SMPTE2084:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084;
+ break;
+ case AVCOL_TRC_SMPTE428:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE428;
+ break;
+ case AVCOL_TRC_ARIB_STD_B67:
+ transfer_characteristic = AMF_COLOR_TRANSFER_CHARACTERISTIC_ARIB_STD_B67;
+ break;
+ }
+ return transfer_characteristic;
+}
+
int ff_amf_get_color_profile(AVCodecContext *avctx)
{
amf_int64 color_profile = AMF_VIDEO_CONVERTER_COLOR_PROFILE_UNKNOWN;
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 0f2abcbd82..0c0624e786 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -174,6 +174,8 @@ int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);
*/
extern const enum AVPixelFormat ff_amf_pix_fmts[];
+int ff_amf_get_color_primaries(AVCodecContext *avctx);
+int ff_amf_get_transfer_characteristic(AVCodecContext *avctx);
int ff_amf_get_color_profile(AVCodecContext *avctx);
/**
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index b40d54f70c..a947c1d232 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -187,6 +187,8 @@ static av_cold int amf_encode_init_av1(AVCodecContext* avctx)
AMFRate framerate;
AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
amf_int64 color_depth;
+ amf_int64 color_primaries;
+ amf_int64 transfer_characteristic;
amf_int64 color_profile;
enum AVPixelFormat pix_fmt;
@@ -239,7 +241,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
/// Color profile
+ color_primaries = ff_amf_get_color_primaries(avctx);
+ transfer_characteristic = ff_amf_get_transfer_characteristic(avctx);
color_profile = ff_amf_get_color_profile(avctx);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, color_primaries);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, transfer_characteristic);
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
/// Color Depth
@@ -251,16 +257,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_COLOR_BIT_DEPTH, color_depth);
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PROFILE, color_profile);
- if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
- /// Color Transfer Characteristics (AMF matches ISO/IEC)
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
- /// Color Primaries (AMF matches ISO/IEC)
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
- } else {
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
- }
profile_level = avctx->level;
if (profile_level == AV_LEVEL_UNKNOWN) {
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index 959be9eab6..2406f7401f 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -202,6 +202,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_primaries;
+ amf_int64 transfer_characteristic;
amf_int64 color_profile;
enum AVPixelFormat pix_fmt;
@@ -274,7 +276,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_ASPECT_RATIO, ratio);
}
+ color_primaries = ff_amf_get_color_primaries(avctx);
+ transfer_characteristic = ff_amf_get_transfer_characteristic(avctx);
color_profile = ff_amf_get_color_profile(avctx);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_COLOR_PRIMARIES, color_primaries);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_TRANSFER_CHARACTERISTIC, transfer_characteristic);
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_OUTPUT_COLOR_PROFILE, color_profile);
/// Color Range (Support for older Drivers)
@@ -288,10 +294,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_RETURN_IF_FALSE(ctx, pix_fmt != AV_PIX_FMT_P010, AVERROR_INVALIDDATA, "10-bit input video is not supported by AMF H264 encoder\n");
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_COLOR_BIT_DEPTH, AMF_COLOR_BIT_DEPTH_8);
- /// Color Transfer Characteristics (AMF matches ISO/IEC)
- 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_OUTPUT_COLOR_PRIMARIES, (amf_int64)avctx->color_primaries);
// 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 f9f6f8adb3..84587c9fb6 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -168,6 +168,8 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
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_primaries;
+ amf_int64 transfer_characteristic;
amf_int64 color_profile;
enum AVPixelFormat pix_fmt;
@@ -242,7 +244,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_ASPECT_RATIO, ratio);
}
+ color_primaries = ff_amf_get_color_primaries(avctx);
+ transfer_characteristic = ff_amf_get_transfer_characteristic(avctx);
color_profile = ff_amf_get_color_profile(avctx);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, color_primaries);
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, transfer_characteristic);
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PROFILE, color_profile);
/// Color Range (Support for older Drivers)
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE, !!(avctx->color_range == AVCOL_RANGE_JPEG));
@@ -254,15 +260,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
color_depth = AMF_COLOR_BIT_DEPTH_10;
}
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH, color_depth);
- if (color_depth == AMF_COLOR_BIT_DEPTH_8) {
- /// Color Transfer Characteristics (AMF matches ISO/IEC)
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_BT709);
- /// Color Primaries (AMF matches ISO/IEC)
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709);
- } else {
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE2084);
- AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT2020);
- }
// Picture control properties
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, ctx->gops_per_idr);
--
2.39.5 (Apple Git-154)
More information about the ffmpeg-devel
mailing list