diff mbox series

[FFmpeg-devel,v2] avcodec/amfenc: add smart access video option

Message ID 20231123094246.14268-2-lucenticus@gmail.com
State New
Headers show
Series [FFmpeg-devel,v2] avcodec/amfenc: add smart access video option | 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

Evgeny Pavlov Nov. 23, 2023, 9:41 a.m. UTC
This commit adds option for enabling SmartAccess Video (SAV)
in AMF encoders. SAV is an AMD hardware-specific feature which
enables the parallelization of encode and decode streams across
multiple Video Codec Engine (VCN) hardware instances.

Signed-off-by: Evgeny Pavlov <lucenticus@gmail.com>
---
 libavcodec/amfenc.h      |  1 +
 libavcodec/amfenc_av1.c  | 18 ++++++++++++++++++
 libavcodec/amfenc_h264.c | 18 ++++++++++++++++++
 libavcodec/amfenc_hevc.c | 18 ++++++++++++++++++
 4 files changed, 55 insertions(+)

Comments

Dmitrii Ovchinnikov Nov. 24, 2023, 8:45 a.m. UTC | #1
If there are no objections, I would like to merge it in 2-3 days
Anton Khirnov Nov. 26, 2023, 10:32 a.m. UTC | #2
Quoting Dmitrii Ovchinnikov (2023-11-24 09:45:14)
>  If there are no objections, I would like to merge it in 2-3 days

The code looks significantly duplicated.
Dmitrii Ovchinnikov Nov. 26, 2023, 2:40 p.m. UTC | #3
>> The code looks significantly duplicated.

This is not moved to amfenc.c since the property has different names
 for different encoders, and many other properties (also common to
different encoders, but with different names) are separated in this way.
Mark Thompson Nov. 27, 2023, 1:09 p.m. UTC | #4
On 23/11/2023 09:41, Evgeny Pavlov wrote:
> This commit adds option for enabling SmartAccess Video (SAV)
> in AMF encoders. SAV is an AMD hardware-specific feature which
> enables the parallelization of encode and decode streams across
> multiple Video Codec Engine (VCN) hardware instances.
> 
> Signed-off-by: Evgeny Pavlov <lucenticus@gmail.com>
> ---
>   libavcodec/amfenc.h      |  1 +
>   libavcodec/amfenc_av1.c  | 18 ++++++++++++++++++
>   libavcodec/amfenc_h264.c | 18 ++++++++++++++++++
>   libavcodec/amfenc_hevc.c | 18 ++++++++++++++++++
>   4 files changed, 55 insertions(+)

Can you explain a bit more about what this option actually does?  I can't find any details about it beyond nebulous "make things better", but presumably there is some tradeoff so you don't always enable it.

Some documentation explaining what it does and hinting when the user might want it on or off would be helpful (can be a separate patch).

Patch itself seems fine for a standalone option, though I would mildly prefer not to put meaningless marketing names in the code if it's possible to have a descriptive name instead.

Thanks,

- Mark
Mark Thompson Nov. 27, 2023, 1:14 p.m. UTC | #5
On 26/11/2023 14:40, Dmitrii Ovchinnikov wrote:
>>> The code looks significantly duplicated.
> 
> This is not moved to amfenc.c since the property has different names
>   for different encoders, and many other properties (also common to
> different encoders, but with different names) are separated in this way.

Seems like we could template this to avoid the duplication, something like:

#define PER_CODEC_OPTION(name) \
   (ctx->codec == AV1  ? AMF_VIDEO_ENCODER_AV1_  ## name : \
    ctx->codec == HEVC ? AMF_VIDEO_ENCODER_HEVC_ ## name : \
                         AMF_VIDEO_ENCODER_      ## name)

?

Thanks,

- Mark
Evgeny Pavlov Nov. 28, 2023, 2:18 p.m. UTC | #6
>
>
> Seems like we could template this to avoid the duplication, something like:
>
> #define PER_CODEC_OPTION(name) \
>    (ctx->codec == AV1  ? AMF_VIDEO_ENCODER_AV1_  ## name : \
>     ctx->codec == HEVC ? AMF_VIDEO_ENCODER_HEVC_ ## name : \
>                          AMF_VIDEO_ENCODER_      ## name)
>

Thanks for the suggestion, I've extracted duplicated code to amfenc.c file,
but can't extract the whole smart_access_video option, because there are
some differences between av1 & hevc/h264 encoders while set low latency
mode.
In addition, I've added a more detailed description for SAV option, I hope
it will be enough for understanding.
Here is an updated version of this patch:
https://patchwork.ffmpeg.org/project/ffmpeg/patch/20231128135347.892-2-lucenticus@gmail.com/
diff mbox series

Patch

diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..e8d66164ed 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -89,6 +89,7 @@  typedef struct AmfContext {
     int                 quality;
     int                 b_frame_delta_qp;
     int                 ref_b_frame_delta_qp;
+    int                 smart_access_video;
 
     // Dynamic options, can be set after Init() call
 
diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index 3f164ccc59..912d6bf020 100644
--- a/libavcodec/amfenc_av1.c
+++ b/libavcodec/amfenc_av1.c
@@ -104,6 +104,8 @@  static const AVOption options[] = {
 
     { "log_to_dbg",     "Enable AMF logging to debug output",   OFFSET(log_to_dbg), AV_OPT_TYPE_BOOL,{.i64 = 0 }, 0, 1, VE },
 
+    { "smart_access_video",     "Enable Smart Access Video",                OFFSET(smart_access_video),             AV_OPT_TYPE_BOOL, {.i64 = -1  }, -1, 1, VE},
+
     //Pre Analysis options
     { "preanalysis",                            "Enable preanalysis",                                           OFFSET(preanalysis),                            AV_OPT_TYPE_BOOL,   {.i64 = -1 }, -1, 1, VE },
 
@@ -243,6 +245,22 @@  FF_ENABLE_DEPRECATION_WARNINGS
         }
     }
 
+    if (ctx->smart_access_video != -1) {
+        AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ENABLE_SMART_ACCESS_VIDEO, ctx->smart_access_video != 0);
+        if (res != AMF_OK) {
+            av_log(avctx, AV_LOG_ERROR, "The Smart Access Video is not supported by AMF.\n");
+            if (ctx->smart_access_video != 0)
+                return AVERROR(ENOSYS);
+        } else {
+            av_log(avctx, AV_LOG_INFO, "The Smart Access Video (%d) is set.\n", ctx->smart_access_video);
+            // Set low latency mode if Smart Access Video is enabled
+            if (ctx->smart_access_video != 0) {
+                AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE, AMF_VIDEO_ENCODER_AV1_ENCODING_LATENCY_MODE_LOWEST_LATENCY);
+                av_log(avctx, AV_LOG_INFO, "The Smart Access Video set low latency mode.\n");
+            }
+        }
+    }
+
     // Pre-Pass, Pre-Analysis, Two-Pass
     if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CONSTANT_QP) {
         AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_PREENCODE, 0);
diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c
index bd544d12df..b0b47645fc 100644
--- a/libavcodec/amfenc_h264.c
+++ b/libavcodec/amfenc_h264.c
@@ -136,6 +136,8 @@  static const AVOption options[] = {
 
     { "log_to_dbg",     "Enable AMF logging to debug output",   OFFSET(log_to_dbg)    , AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
 
+    { "smart_access_video",     "Enable Smart Access Video",    OFFSET(smart_access_video), AV_OPT_TYPE_BOOL, {.i64 = -1  }, -1, 1, VE},
+
     //Pre Analysis options
     { "preanalysis",                            "Enable preanalysis",                                           OFFSET(preanalysis),                            AV_OPT_TYPE_BOOL,   {.i64 = -1 }, -1, 1, VE },
 
@@ -353,6 +355,22 @@  FF_ENABLE_DEPRECATION_WARNINGS
         av_log(ctx, AV_LOG_WARNING, "rate control mode is PEAK_CONSTRAINED_VBR but rc_max_rate is not set\n");
     }
 
+    if (ctx->smart_access_video != -1) {
+        AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_ENABLE_SMART_ACCESS_VIDEO, ctx->smart_access_video != 0);
+        if (res != AMF_OK) {
+            av_log(avctx, AV_LOG_ERROR, "The Smart Access Video is not supported by AMF.\n");
+            if (ctx->smart_access_video != 0)
+                return AVERROR(ENOSYS);
+        } else {
+            av_log(avctx, AV_LOG_INFO, "The Smart Access Video (%d) is set.\n", ctx->smart_access_video);
+            // Set low latency mode if Smart Access Video is enabled
+            if (ctx->smart_access_video != 0) {
+                AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_LOWLATENCY_MODE, true);
+                av_log(avctx, AV_LOG_INFO, "The Smart Access Video set low latency mode.\n");
+            }
+        }
+    }
+
     if (ctx->preanalysis != -1) {
         AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_PRE_ANALYSIS_ENABLE, !!((ctx->preanalysis == 0) ? false : true));
     }
diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c
index 352564a301..a5b6b15ef7 100644
--- a/libavcodec/amfenc_hevc.c
+++ b/libavcodec/amfenc_hevc.c
@@ -99,6 +99,8 @@  static const AVOption options[] = {
 
     { "log_to_dbg",     "Enable AMF logging to debug output",   OFFSET(log_to_dbg), AV_OPT_TYPE_BOOL,{ .i64 = 0 }, 0, 1, VE },
 
+    { "smart_access_video",     "Enable Smart Access Video",        OFFSET(smart_access_video), AV_OPT_TYPE_BOOL, {.i64 = -1  }, -1, 1, VE},
+
     //Pre Analysis options
     { "preanalysis",                            "Enable preanalysis",                                           OFFSET(preanalysis),                            AV_OPT_TYPE_BOOL,   {.i64 = -1 }, -1, 1, VE },
 
@@ -241,6 +243,22 @@  FF_ENABLE_DEPRECATION_WARNINGS
         }
     }
 
+    if (ctx->smart_access_video != -1) {
+        AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_ENABLE_SMART_ACCESS_VIDEO, ctx->smart_access_video != 0);
+        if (res != AMF_OK) {
+            av_log(avctx, AV_LOG_ERROR, "The Smart Access Video is not supported by AMF.\n");
+            if (ctx->smart_access_video != 0)
+                return AVERROR(ENOSYS);
+        } else {
+            av_log(avctx, AV_LOG_INFO, "The Smart Access Video (%d) is set.\n", ctx->smart_access_video);
+            // Set low latency mode if Smart Access Video is enabled
+            if (ctx->smart_access_video != 0) {
+                AMF_ASSIGN_PROPERTY_BOOL(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_LOWLATENCY_MODE, true);
+                av_log(avctx, AV_LOG_INFO, "The Smart Access Video set low latency mode.\n");
+            }
+        }
+    }
+
     // Pre-Pass, Pre-Analysis, Two-Pass
     if (ctx->rate_control_mode == AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CONSTANT_QP) {
         AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, AMF_VIDEO_ENCODER_HEVC_PREENCODE_ENABLE, 0);