diff mbox series

[FFmpeg-devel] Add NVENC "Maximum encoded slice size in bytes" for H.264/HEVC codecs.

Message ID CAGRUmzCEdnfpvjSSnKJwnLFLTG2jGAgvbi9oWLBL8v+GDZMr5A@mail.gmail.com
State Accepted
Commit 7eb0d9e905f3b1ba66d37ebe5e7fe4c2f7077931
Headers show
Series [FFmpeg-devel] Add NVENC "Maximum encoded slice size in bytes" for H.264/HEVC codecs. | expand

Checks

Context Check Description
yinshiyou/commit_msg_loongarch64 warning The first line of the commit message must start with a context terminated by a colon and a space, for example "lavu/opt: " or "doc: ".
andriy/commit_msg_x86 warning The first line of the commit message must start with a context terminated by a colon and a space, for example "lavu/opt: " or "doc: ".
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Водянников Александр July 27, 2023, 2:39 a.m. UTC
From: Aleksoid <Aleksoid1978@mail.ru>
Date: Thu, 27 Jul 2023 12:26:23 +1000
Subject: [PATCH] Add NVENC "Maximum encoded slice size in bytes" for
 H.264/HEVC codecs.

Signed-off-by: Aleksoid <Aleksoid1978@mail.ru>
---
 libavcodec/nvenc.c      | 18 ++++++++++++++----
 libavcodec/nvenc.h      |  1 +
 libavcodec/nvenc_h264.c |  2 ++
 libavcodec/nvenc_hevc.c |  2 ++
 4 files changed, 19 insertions(+), 4 deletions(-)

Comments

Timo Rothenpieler July 27, 2023, 12:08 p.m. UTC | #1
Looks sensible to me.
I'm curious, what is the use case for this mode?
Kieran Kunhya July 27, 2023, 1:22 p.m. UTC | #2
On Thu, 27 Jul 2023 at 13:09, Timo Rothenpieler <timo@rothenpieler.org>
wrote:

> Looks sensible to me.
> I'm curious, what is the use case for this mode?
>

The classical use-case for this feature is to fit a slice in a UDP packet
for RTP streaming.

Kieran
Timo Rothenpieler Aug. 13, 2023, 5:36 p.m. UTC | #3
Did you actually get this to work?
I'm testing it right now, and at stupid low values like 10 bytes I get a 
working but heavily artifacted video.
If I set it to something like 2048 all I get is a full size video that 
VLC decodes to a black screen.
Kieran Kunhya Aug. 13, 2023, 11:08 p.m. UTC | #4
On Sun, 13 Aug 2023 at 18:36, Timo Rothenpieler <timo@rothenpieler.org>
wrote:

> Did you actually get this to work?
> I'm testing it right now, and at stupid low values like 10 bytes I get a
> working but heavily artifacted video.
> If I set it to something like 2048 all I get is a full size video that
> VLC decodes to a black screen.


This could be a bug in hwaccel decode. Does it work in software decode?

Kieran
Timo Rothenpieler Aug. 14, 2023, 9:20 p.m. UTC | #5
On 14.08.2023 01:08, Kieran Kunhya wrote:
> On Sun, 13 Aug 2023 at 18:36, Timo Rothenpieler <timo@rothenpieler.org>
> wrote:
> 
>> Did you actually get this to work?
>> I'm testing it right now, and at stupid low values like 10 bytes I get a
>> working but heavily artifacted video.
>> If I set it to something like 2048 all I get is a full size video that
>> VLC decodes to a black screen.
> 
> 
> This could be a bug in hwaccel decode. Does it work in software decode?

Yeah, it works fine with software decode. At least in VLC.
Though surprisingly the bigger slice size limit looks significantly 
worse than the stupid low one of 10, it might have just ignored me?
diff mbox series

Patch

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 0b6417674e..c82fcbfe1e 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -1166,8 +1166,13 @@  static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
         || vui->videoFormat != 5
         || vui->videoFullRangeFlag != 0);
 
-    h264->sliceMode = 3;
-    h264->sliceModeData = avctx->slices > 0 ? avctx->slices : 1;
+    if (ctx->max_slice_size > 0) {
+        h264->sliceMode = 1;
+        h264->sliceModeData = ctx->max_slice_size;
+    } else {
+        h264->sliceMode = 3;
+        h264->sliceModeData = avctx->slices > 0 ? avctx->slices : 1;
+    }
 
     if (ctx->intra_refresh) {
         h264->enableIntraRefresh = 1;
@@ -1287,8 +1292,13 @@  static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
         || vui->videoFormat != 5
         || vui->videoFullRangeFlag != 0);
 
-    hevc->sliceMode = 3;
-    hevc->sliceModeData = avctx->slices > 0 ? avctx->slices : 1;
+    if (ctx->max_slice_size > 0) {
+        hevc->sliceMode = 1;
+        hevc->sliceModeData = ctx->max_slice_size;
+    } else {
+        hevc->sliceMode = 3;
+        hevc->sliceModeData = avctx->slices > 0 ? avctx->slices : 1;
+    }
 
     if (ctx->intra_refresh) {
         hevc->enableIntraRefresh = 1;
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 3a4b456a41..cf0e8e5946 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -262,6 +262,7 @@  typedef struct NvencContext
     int udu_sei;
     int timing_info;
     int highbitdepth;
+    int max_slice_size;
 } NvencContext;
 
 int ff_nvenc_encode_init(AVCodecContext *avctx);
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index a99860998e..4440e49b25 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -206,6 +206,8 @@  static const AVOption options[] = {
                                                             OFFSET(intra_refresh),AV_OPT_TYPE_BOOL,  { .i64 = 0 }, 0, 1, VE },
     { "single-slice-intra-refresh", "Use single slice intra refresh",
                                                             OFFSET(single_slice_intra_refresh), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+    { "max_slice_size", "Maximum encoded slice size in bytes",
+                                                            OFFSET(max_slice_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
     { "constrained-encoding", "Enable constrainedFrame encoding where each slice in the constrained picture is independent of other slices",
                                                             OFFSET(constrained_encoding), AV_OPT_TYPE_BOOL,  { .i64 = 0 }, 0, 1, VE },
     { NULL }
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index a02f277888..e606655e7e 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -187,6 +187,8 @@  static const AVOption options[] = {
                                                             OFFSET(intra_refresh),AV_OPT_TYPE_BOOL,  { .i64 = 0 }, 0, 1, VE },
     { "single-slice-intra-refresh", "Use single slice intra refresh",
                                                             OFFSET(single_slice_intra_refresh), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+    { "max_slice_size", "Maximum encoded slice size in bytes",
+                                                            OFFSET(max_slice_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
     { "constrained-encoding", "Enable constrainedFrame encoding where each slice in the constrained picture is independent of other slices",
                                                             OFFSET(constrained_encoding), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
     { NULL }