Compare commits

...

5 Commits

Author SHA1 Message Date
Michael Fabian 'Xaymar' Dirks ff72368ebe avcodec/amfenc: Add missing profiles
Adds the missing profiles to the '-help encoder=xxx_amf' list,
even if the user may never need these.
2022-07-06 22:06:48 +02:00
Michael Fabian 'Xaymar' Dirks 6b1b0d4f90 avcodec/amfenc: Add "High Motion Quality Boost" option
This option was missing from amfenc, and is now available.
2022-07-06 22:06:48 +02:00
Michael Fabian 'Xaymar' Dirks 0550d88130 avcodec/amfenc: Add the new usage presets
These enable some new features that otherwise require another
AMF component to be loaded. Requires AMF SDK 1.4.23 or newer.
2022-07-06 22:06:48 +02:00
Michael Fabian 'Xaymar' Dirks 8aa09a6ef5 avcodec/amfenc: Set all color metadata for AMF
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.
2022-07-06 22:06:48 +02:00
Michael Fabian 'Xaymar' Dirks 6582fd675f avcodec: Require AMF SDK v1.4.23 or newer
Increasing the minimum AMF SDK version allows us to support
more recent hardware and drivers, which is necessary to fix
some of the discrepancies between older and newer drivers on
AMD hardware with FFmpeg.
2022-07-06 22:06:47 +02:00
4 changed files with 124 additions and 15 deletions
Vendored
+1 -1
View File
@@ -6988,7 +6988,7 @@ fi
enabled amf && enabled amf &&
check_cpp_condition amf "AMF/core/Version.h" \ check_cpp_condition amf "AMF/core/Version.h" \
"(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x0001000400090000" "AMF_FULL_VERSION >= AMF_MAKE_FULL_VERSION(1, 4, 23, 0)"
# Funny iconv installations are not unusual, so check it after all flags have been set # Funny iconv installations are not unusual, so check it after all flags have been set
if enabled libc_iconv; then if enabled libc_iconv; then
+4
View File
@@ -21,6 +21,7 @@
#include <AMF/core/Factory.h> #include <AMF/core/Factory.h>
#include <AMF/components/ColorSpace.h>
#include <AMF/components/VideoEncoderVCE.h> #include <AMF/components/VideoEncoderVCE.h>
#include <AMF/components/VideoEncoderHEVC.h> #include <AMF/components/VideoEncoderHEVC.h>
@@ -107,6 +108,9 @@ typedef struct AmfContext {
int me_quarter_pel; int me_quarter_pel;
int aud; int aud;
// Unclear options, have different behavior based on codec.
int hmqb;
// HEVC - specific options // HEVC - specific options
int gops_per_idr; int gops_per_idr;
+62 -11
View File
@@ -29,18 +29,21 @@
static const AVOption options[] = { static const AVOption options[] = {
// Static // Static
/// Usage /// Usage
{ "usage", "Encoder Usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCONDING }, AMF_VIDEO_ENCODER_USAGE_TRANSCONDING, AMF_VIDEO_ENCODER_USAGE_WEBCAM, VE, "usage" }, { "usage", "Encoder Usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCODING }, AMF_VIDEO_ENCODER_USAGE_TRANSCODING, AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, "usage" },
{ "transcoding", "Generic Transcoding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCONDING }, 0, 0, VE, "usage" }, { "transcoding", "Generic Transcoding", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_TRANSCODING }, 0, 0, VE, "usage" },
{ "ultralowlatency","", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" }, { "ultralowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" },
{ "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" }, { "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" },
{ "webcam", "Webcam", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_WEBCAM }, 0, 0, VE, "usage" }, { "webcam", "Webcam", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_WEBCAM }, 0, 0, VE, "usage" },
{ "highquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_HIGH_QUALITY }, 0, 0, VE, "usage" },
{ "lowlatency_highqquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_USAGE_LOW_LATENCY_HIGH_QUALITY }, 0, 0, VE, "usage" },
/// Profile, /// Profile,
{ "profile", "Profile", OFFSET(profile),AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, AMF_VIDEO_ENCODER_PROFILE_BASELINE, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, "profile" }, { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, AMF_VIDEO_ENCODER_PROFILE_BASELINE, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH, VE, "profile" },
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, 0, 0, VE, "profile" }, { "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_BASELINE }, 0, 0, VE, "profile" },
{ "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_HIGH }, 0, 0, VE, "profile" }, { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_MAIN }, 0, 0, VE, "profile" },
{ "constrained_baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE }, 0, 0, VE, "profile" }, { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_HIGH }, 0, 0, VE, "profile" },
{ "constrained_high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH }, 0, 0, VE, "profile" }, { "constrained_baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE }, 0, 0, VE, "profile" },
{ "constrained_high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_HIGH }, 0, 0, VE, "profile" },
/// Profile Level /// Profile Level
{ "level", "Profile Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 62, VE, "level" }, { "level", "Profile Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 62, VE, "level" },
@@ -85,6 +88,7 @@ static const AVOption options[] = {
{ "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "frame_skipping", "Rate Control Based Frame Skip", OFFSET(skip_frame), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "frame_skipping", "Rate Control Based Frame Skip", OFFSET(skip_frame), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "hmqb", "High Motion Quality Boost", OFFSET(hmqb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
/// QP Values /// QP Values
{ "qp_i", "Quantization Parameter for I-Frame", OFFSET(qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE }, { "qp_i", "Quantization Parameter for I-Frame", OFFSET(qp_i), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
@@ -138,6 +142,8 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
AMFRate framerate; AMFRate framerate;
AMFSize framesize = AMFConstructSize(avctx->width, avctx->height); AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
int deblocking_filter = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0; 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) { if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den); framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den);
@@ -195,10 +201,54 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
AMF_ASSIGN_PROPERTY_RATIO(res, ctx->encoder, AMF_VIDEO_ENCODER_ASPECT_RATIO, ratio); 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) { if (avctx->color_range == AVCOL_RANGE_JPEG) {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, 1); 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 // autodetect rate control method
if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN) { if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_UNKNOWN) {
@@ -284,6 +334,7 @@ static av_cold int amf_encode_init_h264(AVCodecContext *avctx)
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENFORCE_HRD, !!ctx->enforce_hrd); AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENFORCE_HRD, !!ctx->enforce_hrd);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE, !!ctx->filler_data); AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE, !!ctx->filler_data);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE, !!ctx->skip_frame); AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_SKIP_FRAME_ENABLE, !!ctx->skip_frame);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HIGH_MOTION_QUALITY_BOOST_ENABLE, !!ctx->hmqb);
if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) { if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CONSTANT_QP) {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, 0); AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_VBAQ, 0);
if (ctx->enable_vbaq) if (ctx->enable_vbaq)
+57 -3
View File
@@ -25,14 +25,17 @@
#define OFFSET(x) offsetof(AmfContext, x) #define OFFSET(x) offsetof(AmfContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = { static const AVOption options[] = {
{ "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING }, AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING, AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM, VE, "usage" }, { "usage", "Set the encoding usage", OFFSET(usage), AV_OPT_TYPE_INT, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING }, AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING, AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY_HIGH_QUALITY, VE, "usage" },
{ "transcoding", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCONDING }, 0, 0, VE, "usage" }, { "transcoding", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_TRANSCODING }, 0, 0, VE, "usage" },
{ "ultralowlatency","", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" }, { "ultralowlatency","", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY }, 0, 0, VE, "usage" },
{ "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" }, { "lowlatency", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY }, 0, 0, VE, "usage" },
{ "webcam", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM }, 0, 0, VE, "usage" }, { "webcam", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_WEBCAM }, 0, 0, VE, "usage" },
{ "highquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_HIGH_QUALITY }, 0, 0, VE, "usage" },
{ "lowlatency_highqquality", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_USAGE_LOW_LATENCY_HIGH_QUALITY }, 0, 0, VE, "usage" },
{ "profile", "Set the profile (default main)", OFFSET(profile), AV_OPT_TYPE_INT,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, VE, "profile" }, { "profile", "Set the profile (default main)", OFFSET(profile), AV_OPT_TYPE_INT,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN, VE, "profile" },
{ "main", "", 0, AV_OPT_TYPE_CONST,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" }, { "main", "", 0, AV_OPT_TYPE_CONST,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN }, 0, 0, VE, "profile" },
{ "main10", "", 0, AV_OPT_TYPE_CONST,{ .i64 = AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN_10 }, 0, 0, VE, "profile" },
{ "profile_tier", "Set the profile tier (default main)", OFFSET(tier), AV_OPT_TYPE_INT,{ .i64 = AMF_VIDEO_ENCODER_HEVC_TIER_MAIN }, AMF_VIDEO_ENCODER_HEVC_TIER_MAIN, AMF_VIDEO_ENCODER_HEVC_TIER_HIGH, VE, "tier" }, { "profile_tier", "Set the profile tier (default main)", OFFSET(tier), AV_OPT_TYPE_INT,{ .i64 = AMF_VIDEO_ENCODER_HEVC_TIER_MAIN }, AMF_VIDEO_ENCODER_HEVC_TIER_MAIN, AMF_VIDEO_ENCODER_HEVC_TIER_HIGH, VE, "tier" },
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_TIER_MAIN }, 0, 0, VE, "tier" }, { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_VIDEO_ENCODER_HEVC_TIER_MAIN }, 0, 0, VE, "tier" },
@@ -73,6 +76,7 @@ static const AVOption options[] = {
{ "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, VE }, { "gops_per_idr", "GOPs per IDR 0-no IDR will be inserted", OFFSET(gops_per_idr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, VE },
{ "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE}, { "preanalysis", "Enable preanalysis", OFFSET(preanalysis), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE}, { "vbaq", "Enable VBAQ", OFFSET(enable_vbaq), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "hmqb", "High Motion Quality Boost", OFFSET(hmqb), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE}, { "enforce_hrd", "Enforce HRD", OFFSET(enforce_hrd), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE}, { "filler_data", "Filler Data Enable", OFFSET(filler_data), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
{ "max_au_size", "Maximum Access Unit Size for rate control (in bits)", OFFSET(max_au_size), AV_OPT_TYPE_INT,{ .i64 = 0 }, 0, INT_MAX, VE}, { "max_au_size", "Maximum Access Unit Size for rate control (in bits)", OFFSET(max_au_size), AV_OPT_TYPE_INT,{ .i64 = 0 }, 0, INT_MAX, VE},
@@ -105,6 +109,8 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
AMFRate framerate; AMFRate framerate;
AMFSize framesize = AMFConstructSize(avctx->width, avctx->height); AMFSize framesize = AMFConstructSize(avctx->width, avctx->height);
int deblocking_filter = (avctx->flags & AV_CODEC_FLAG_LOOP_FILTER) ? 1 : 0; 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) { if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {
framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den); framerate = AMFConstructRate(avctx->framerate.num, avctx->framerate.den);
@@ -153,6 +159,54 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
AMFRatio ratio = AMFConstructRatio(avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); 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); 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 // Picture control properties
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, ctx->gops_per_idr); AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, ctx->gops_per_idr);
@@ -180,7 +234,6 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
} }
} }
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD, ctx->rate_control_mode); AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD, ctx->rate_control_mode);
if (avctx->rc_buffer_size) { if (avctx->rc_buffer_size) {
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_VBV_BUFFER_SIZE, avctx->rc_buffer_size); AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_VBV_BUFFER_SIZE, avctx->rc_buffer_size);
@@ -202,6 +255,7 @@ static av_cold int amf_encode_init_hevc(AVCodecContext *avctx)
} else { } else {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ, !!ctx->enable_vbaq); AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ, !!ctx->enable_vbaq);
} }
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_HIGH_MOTION_QUALITY_BOOST_ENABLE, !!ctx->hmqb);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MOTION_HALF_PIXEL, ctx->me_half_pel); AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MOTION_HALF_PIXEL, ctx->me_half_pel);
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MOTION_QUARTERPIXEL, ctx->me_quarter_pel); AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MOTION_QUARTERPIXEL, ctx->me_quarter_pel);