@@ -90,6 +90,7 @@ typedef struct AmfContext {
int quality;
int b_frame_delta_qp;
int ref_b_frame_delta_qp;
+ int query_timeout;
// Dynamic options, can be set after Init() call
@@ -122,6 +122,8 @@ static const AVOption options[] = {
{ "1080p", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_64X16_1080P_CODED_1082 }, 0, 0, VE, .unit = "align" },
{ "none", "", 0, AV_OPT_TYPE_CONST, {.i64 = AMF_VIDEO_ENCODER_AV1_ALIGNMENT_MODE_NO_RESTRICTIONS }, 0, 0, VE, .unit = "align" },
+ { "query_timeout", "Timeout in ms for QueryOutput", OFFSET(query_timeout), AV_OPT_TYPE_INT, { .i64 = 50 }, -1, 1000, VE },
+
{ "log_to_dbg", "Enable AMF logging to debug output", OFFSET(log_to_dbg), AV_OPT_TYPE_BOOL,{.i64 = 0 }, 0, 1, VE },
//Pre Analysis options
@@ -318,6 +320,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
}
+ // Timeout for QueryOutput()
+ if (ctx->query_timeout != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_QUERY_TIMEOUT, ctx->query_timeout);
+ }
+
// init dynamic rate control params
if (ctx->enforce_hrd != -1) {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ENFORCE_HRD, ((ctx->enforce_hrd == 0) ? false : true));
@@ -135,6 +135,7 @@ static const AVOption options[] = {
{ "aud", "Inserts AU Delimiter NAL unit", OFFSET(aud) , AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE },
+ { "query_timeout", "Timeout in ms for QueryOutput", OFFSET(query_timeout), AV_OPT_TYPE_INT, { .i64 = 50 }, -1, 1000, VE },
{ "log_to_dbg", "Enable AMF logging to debug output", OFFSET(log_to_dbg) , AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
@@ -318,6 +319,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QUALITY_PRESET, ctx->quality);
}
+ // Timeout for QueryOutput()
+ if (ctx->query_timeout != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_QUERY_TIMEOUT, ctx->query_timeout);
+ }
+
// Dynamic parameters
AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD, ctx->rate_control_mode);
@@ -101,6 +101,7 @@ static const AVOption options[] = {
{ "aud", "Inserts AU Delimiter NAL unit", OFFSET(aud) ,AV_OPT_TYPE_BOOL,{ .i64 = -1 }, -1, 1, VE },
+ { "query_timeout", "Timeout in ms for QueryOutput", OFFSET(query_timeout), AV_OPT_TYPE_INT, { .i64 = 50 }, -1, 1000, VE },
{ "log_to_dbg", "Enable AMF logging to debug output", OFFSET(log_to_dbg), AV_OPT_TYPE_BOOL,{ .i64 = 0 }, 0, 1, VE },
@@ -316,7 +317,12 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
if (ctx->me_quarter_pel != -1) {
AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_MOTION_QUARTERPIXEL, ctx->me_quarter_pel);
- }
+ }
+
+ // Timeout for QueryOutput()
+ if (ctx->query_timeout != -1) {
+ AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_QUERY_TIMEOUT, ctx->query_timeout);
+ }
// init dynamic rate control params
if (ctx->enforce_hrd != -1) {
Using QUERY_TIMEOUT rather than a polling loop with a fixed sleep results in both better performance and lower power consumption by sleeping until the frame is ready. The length of the fixed sleep is constrained to a granularity of at least the process's timer resolution (typically ~15 ms) which acts as a lower bound on the encoding latency. The default output timeout value is 50 ms, which matches with AMD's chosen default value for the new High Quality (HQ) and High Quality Low Latency (HQLL) usages. It is also the value used in AMD's AMF EncoderLatency sample. For older drivers without support for the QUERY_TIMEOUT property, they will still have the current non-blocking QueryOutput() which results in the same polling behavior as today. Fixes poor encoding performance with low resolution video as reported in #10622. Signed-off-by: Cameron Gutman <aicommander@gmail.com> --- libavcodec/amfenc.h | 1 + libavcodec/amfenc_av1.c | 7 +++++++ libavcodec/amfenc_h264.c | 6 ++++++ libavcodec/amfenc_hevc.c | 8 +++++++- 4 files changed, 21 insertions(+), 1 deletion(-)