diff mbox series

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

Message ID 20240904040320.1724-1-aicommander@gmail.com
State New
Headers show
Series [FFmpeg-devel] avcodec/amfenc: Avoid polling with fixed sleep | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Cameron Gutman Sept. 4, 2024, 4:03 a.m. UTC
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(-)
diff mbox series

Patch

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) {