[FFmpeg-devel] [PATCH] avcodec/amfenc: Avoid polling with fixed sleep

Cameron Gutman aicommander at gmail.com
Wed Sep 4 07:03:20 EEST 2024


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 at 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(-)

diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 92a6486c96..b1595dbe6c 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -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
 
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index f2ad06c083..1018201675 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -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));
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index c80854c5f8..737e15282f 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -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);
 
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index 51fc243747..cae0786f18 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -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) {
-- 
2.43.0.windows.1



More information about the ffmpeg-devel mailing list