Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH] avcodec/nvenc: Use CBR filler data consistently across codecs
@ 2025-03-30  0:04 Cameron Gutman
  2025-03-30 15:33 ` Kieran Kunhya via ffmpeg-devel
  0 siblings, 1 reply; 7+ messages in thread
From: Cameron Gutman @ 2025-03-30  0:04 UTC (permalink / raw)
  To: timo, ffmpeg-devel

Previously, AV1 used filler data with CBR by default while H.264
and HEVC did not. Make this consistent by using filler data in
CBR mode across all codecs.

Since there are valid reasons to use CBR with or without filler,
also add a cbr_padding option to allow users to opt out.

Signed-off-by: Cameron Gutman <aicommander@gmail.com>
---
 libavcodec/nvenc.c      | 16 +++++++++++++---
 libavcodec/nvenc.h      |  2 ++
 libavcodec/nvenc_av1.c  |  2 ++
 libavcodec/nvenc_h264.c |  4 ++++
 libavcodec/nvenc_hevc.c |  4 ++++
 5 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 0f5e772b3e..41a4dc55f4 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -1304,7 +1304,12 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
     h264->idrPeriod = cc->gopLength;
 
     if (IS_CBR(cc->rcParams.rateControlMode)) {
-        h264->outputBufferingPeriodSEI = 1;
+        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
+        h264->outputBufferingPeriodSEI = ctx->cbr_padding;
+
+#ifdef NVENC_HAVE_FILLER_DATA
+        h264->enableFillerDataInsertion = ctx->cbr_padding;
+#endif
     }
 
     h264->outputPictureTimingSEI = 1;
@@ -1503,7 +1508,12 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
     hevc->idrPeriod = cc->gopLength;
 
     if (IS_CBR(cc->rcParams.rateControlMode)) {
-        hevc->outputBufferingPeriodSEI = 1;
+        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
+        hevc->outputBufferingPeriodSEI = ctx->cbr_padding;
+
+#ifdef NVENC_HAVE_FILLER_DATA
+        hevc->enableFillerDataInsertion = ctx->cbr_padding;
+#endif
     }
 
     hevc->outputPictureTimingSEI = 1;
@@ -1625,7 +1635,7 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
     av1->idrPeriod = cc->gopLength;
 
     if (IS_CBR(cc->rcParams.rateControlMode)) {
-        av1->enableBitstreamPadding = 1;
+        av1->enableBitstreamPadding = ctx->cbr_padding;
     }
 
     if (ctx->tile_cols >= 0)
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index e035e123c6..4b12846ed7 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -61,6 +61,7 @@ typedef void ID3D11Device;
 #define NVENC_HAVE_MULTIPLE_REF_FRAMES
 #define NVENC_HAVE_CUSTREAM_PTR
 #define NVENC_HAVE_GETLASTERRORSTRING
+#define NVENC_HAVE_FILLER_DATA
 #endif
 
 // SDK 10.0 compile time feature checks
@@ -309,6 +310,7 @@ typedef struct NvencContext
     int unidir_b;
     int split_encode_mode;
     int mdm, cll;
+    int cbr_padding;
 } NvencContext;
 
 int ff_nvenc_encode_init(AVCodecContext *avctx);
diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
index 01626113ab..b1b95672f2 100644
--- a/libavcodec/nvenc_av1.c
+++ b/libavcodec/nvenc_av1.c
@@ -156,6 +156,8 @@ static const AVOption options[] = {
                                                             OFFSET(extra_sei),    AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
     { "a53cc",        "Use A53 Closed Captions (if available)", OFFSET(a53_cc),   AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
     { "s12m_tc",      "Use timecode (if available)",        OFFSET(s12m_tc),      AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
+    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
+                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
 #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
     { "tf_level",     "Specifies the strength of the temporal filtering",
                                                             OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index 21d25d643a..4845d0422d 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -231,6 +231,10 @@ static const AVOption options[] = {
                                                             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 },
+#ifdef NVENC_HAVE_FILLER_DATA
+    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
+                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
+#endif
 #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
     { "tf_level",     "Specifies the strength of the temporal filtering",
                                                             OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index c74eca9bb3..8648f4f3a9 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -206,6 +206,10 @@ static const AVOption options[] = {
                                                             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 },
+#ifdef NVENC_HAVE_FILLER_DATA
+    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
+                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
+#endif
 #ifdef NVENC_HAVE_TEMPORAL_FILTER
     { "tf_level",     "Specifies the strength of the temporal filtering",
                                                             OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avcodec/nvenc: Use CBR filler data consistently across codecs
  2025-03-30  0:04 [FFmpeg-devel] [PATCH] avcodec/nvenc: Use CBR filler data consistently across codecs Cameron Gutman
@ 2025-03-30 15:33 ` Kieran Kunhya via ffmpeg-devel
  2025-03-30 15:46   ` Zhao Zhili
  2025-03-30 16:41   ` Timo Rothenpieler
  0 siblings, 2 replies; 7+ messages in thread
From: Kieran Kunhya via ffmpeg-devel @ 2025-03-30 15:33 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Kieran Kunhya, timo

On Sun, Mar 30, 2025 at 12:04 AM Cameron Gutman <aicommander@gmail.com> wrote:
>
> Previously, AV1 used filler data with CBR by default while H.264
> and HEVC did not. Make this consistent by using filler data in
> CBR mode across all codecs.
>
> Since there are valid reasons to use CBR with or without filler,
> also add a cbr_padding option to allow users to opt out.
>
> Signed-off-by: Cameron Gutman <aicommander@gmail.com>
> ---
>  libavcodec/nvenc.c      | 16 +++++++++++++---
>  libavcodec/nvenc.h      |  2 ++
>  libavcodec/nvenc_av1.c  |  2 ++
>  libavcodec/nvenc_h264.c |  4 ++++
>  libavcodec/nvenc_hevc.c |  4 ++++
>  5 files changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
> index 0f5e772b3e..41a4dc55f4 100644
> --- a/libavcodec/nvenc.c
> +++ b/libavcodec/nvenc.c
> @@ -1304,7 +1304,12 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
>      h264->idrPeriod = cc->gopLength;
>
>      if (IS_CBR(cc->rcParams.rateControlMode)) {
> -        h264->outputBufferingPeriodSEI = 1;
> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
> +        h264->outputBufferingPeriodSEI = ctx->cbr_padding;
> +
> +#ifdef NVENC_HAVE_FILLER_DATA
> +        h264->enableFillerDataInsertion = ctx->cbr_padding;
> +#endif
>      }
>
>      h264->outputPictureTimingSEI = 1;
> @@ -1503,7 +1508,12 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
>      hevc->idrPeriod = cc->gopLength;
>
>      if (IS_CBR(cc->rcParams.rateControlMode)) {
> -        hevc->outputBufferingPeriodSEI = 1;
> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
> +        hevc->outputBufferingPeriodSEI = ctx->cbr_padding;
> +
> +#ifdef NVENC_HAVE_FILLER_DATA
> +        hevc->enableFillerDataInsertion = ctx->cbr_padding;
> +#endif
>      }
>
>      hevc->outputPictureTimingSEI = 1;
> @@ -1625,7 +1635,7 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
>      av1->idrPeriod = cc->gopLength;
>
>      if (IS_CBR(cc->rcParams.rateControlMode)) {
> -        av1->enableBitstreamPadding = 1;
> +        av1->enableBitstreamPadding = ctx->cbr_padding;
>      }
>
>      if (ctx->tile_cols >= 0)
> diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
> index e035e123c6..4b12846ed7 100644
> --- a/libavcodec/nvenc.h
> +++ b/libavcodec/nvenc.h
> @@ -61,6 +61,7 @@ typedef void ID3D11Device;
>  #define NVENC_HAVE_MULTIPLE_REF_FRAMES
>  #define NVENC_HAVE_CUSTREAM_PTR
>  #define NVENC_HAVE_GETLASTERRORSTRING
> +#define NVENC_HAVE_FILLER_DATA
>  #endif
>
>  // SDK 10.0 compile time feature checks
> @@ -309,6 +310,7 @@ typedef struct NvencContext
>      int unidir_b;
>      int split_encode_mode;
>      int mdm, cll;
> +    int cbr_padding;
>  } NvencContext;
>
>  int ff_nvenc_encode_init(AVCodecContext *avctx);
> diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
> index 01626113ab..b1b95672f2 100644
> --- a/libavcodec/nvenc_av1.c
> +++ b/libavcodec/nvenc_av1.c
> @@ -156,6 +156,8 @@ static const AVOption options[] = {
>                                                              OFFSET(extra_sei),    AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>      { "a53cc",        "Use A53 Closed Captions (if available)", OFFSET(a53_cc),   AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>      { "s12m_tc",      "Use timecode (if available)",        OFFSET(s12m_tc),      AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>  #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
>      { "tf_level",     "Specifies the strength of the temporal filtering",
>                                                              OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
> diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
> index 21d25d643a..4845d0422d 100644
> --- a/libavcodec/nvenc_h264.c
> +++ b/libavcodec/nvenc_h264.c
> @@ -231,6 +231,10 @@ static const AVOption options[] = {
>                                                              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 },
> +#ifdef NVENC_HAVE_FILLER_DATA
> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> +#endif
>  #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
>      { "tf_level",     "Specifies the strength of the temporal filtering",
>                                                              OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
> diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
> index c74eca9bb3..8648f4f3a9 100644
> --- a/libavcodec/nvenc_hevc.c
> +++ b/libavcodec/nvenc_hevc.c
> @@ -206,6 +206,10 @@ static const AVOption options[] = {
>                                                              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 },
> +#ifdef NVENC_HAVE_FILLER_DATA
> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> +#endif
>  #ifdef NVENC_HAVE_TEMPORAL_FILTER
>      { "tf_level",     "Specifies the strength of the temporal filtering",
>                                                              OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
> --
> 2.49.0


This should be off by default in FFmpeg. We don't do this in any other encoder.

Kieran
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avcodec/nvenc: Use CBR filler data consistently across codecs
  2025-03-30 15:33 ` Kieran Kunhya via ffmpeg-devel
@ 2025-03-30 15:46   ` Zhao Zhili
  2025-03-30 16:35     ` Cameron Gutman
  2025-03-30 16:41   ` Timo Rothenpieler
  1 sibling, 1 reply; 7+ messages in thread
From: Zhao Zhili @ 2025-03-30 15:46 UTC (permalink / raw)
  To: FFmpeg development discussions and patches



> On Mar 30, 2025, at 23:33, Kieran Kunhya via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> wrote:
> 
> On Sun, Mar 30, 2025 at 12:04 AM Cameron Gutman <aicommander@gmail.com <mailto:aicommander@gmail.com>> wrote:
>> 
>> Previously, AV1 used filler data with CBR by default while H.264
>> and HEVC did not. Make this consistent by using filler data in
>> CBR mode across all codecs.
>> 
>> Since there are valid reasons to use CBR with or without filler,
>> also add a cbr_padding option to allow users to opt out.
>> 
>> Signed-off-by: Cameron Gutman <aicommander@gmail.com>
>> ---
>> libavcodec/nvenc.c      | 16 +++++++++++++---
>> libavcodec/nvenc.h      |  2 ++
>> libavcodec/nvenc_av1.c  |  2 ++
>> libavcodec/nvenc_h264.c |  4 ++++
>> libavcodec/nvenc_hevc.c |  4 ++++
>> 5 files changed, 25 insertions(+), 3 deletions(-)
>> 
>> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
>> index 0f5e772b3e..41a4dc55f4 100644
>> --- a/libavcodec/nvenc.c
>> +++ b/libavcodec/nvenc.c
>> @@ -1304,7 +1304,12 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
>>     h264->idrPeriod = cc->gopLength;
>> 
>>     if (IS_CBR(cc->rcParams.rateControlMode)) {
>> -        h264->outputBufferingPeriodSEI = 1;
>> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
>> +        h264->outputBufferingPeriodSEI = ctx->cbr_padding;
>> +
>> +#ifdef NVENC_HAVE_FILLER_DATA
>> +        h264->enableFillerDataInsertion = ctx->cbr_padding;
>> +#endif
>>     }
>> 
>>     h264->outputPictureTimingSEI = 1;
>> @@ -1503,7 +1508,12 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
>>     hevc->idrPeriod = cc->gopLength;
>> 
>>     if (IS_CBR(cc->rcParams.rateControlMode)) {
>> -        hevc->outputBufferingPeriodSEI = 1;
>> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
>> +        hevc->outputBufferingPeriodSEI = ctx->cbr_padding;
>> +
>> +#ifdef NVENC_HAVE_FILLER_DATA
>> +        hevc->enableFillerDataInsertion = ctx->cbr_padding;
>> +#endif
>>     }
>> 
>>     hevc->outputPictureTimingSEI = 1;
>> @@ -1625,7 +1635,7 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
>>     av1->idrPeriod = cc->gopLength;
>> 
>>     if (IS_CBR(cc->rcParams.rateControlMode)) {
>> -        av1->enableBitstreamPadding = 1;
>> +        av1->enableBitstreamPadding = ctx->cbr_padding;
>>     }
>> 
>>     if (ctx->tile_cols >= 0)
>> diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
>> index e035e123c6..4b12846ed7 100644
>> --- a/libavcodec/nvenc.h
>> +++ b/libavcodec/nvenc.h
>> @@ -61,6 +61,7 @@ typedef void ID3D11Device;
>> #define NVENC_HAVE_MULTIPLE_REF_FRAMES
>> #define NVENC_HAVE_CUSTREAM_PTR
>> #define NVENC_HAVE_GETLASTERRORSTRING
>> +#define NVENC_HAVE_FILLER_DATA
>> #endif
>> 
>> // SDK 10.0 compile time feature checks
>> @@ -309,6 +310,7 @@ typedef struct NvencContext
>>     int unidir_b;
>>     int split_encode_mode;
>>     int mdm, cll;
>> +    int cbr_padding;
>> } NvencContext;
>> 
>> int ff_nvenc_encode_init(AVCodecContext *avctx);
>> diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
>> index 01626113ab..b1b95672f2 100644
>> --- a/libavcodec/nvenc_av1.c
>> +++ b/libavcodec/nvenc_av1.c
>> @@ -156,6 +156,8 @@ static const AVOption options[] = {
>>                                                             OFFSET(extra_sei),    AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>     { "a53cc",        "Use A53 Closed Captions (if available)", OFFSET(a53_cc),   AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>     { "s12m_tc",      "Use timecode (if available)",        OFFSET(s12m_tc),      AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
>> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>> #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
>>     { "tf_level",     "Specifies the strength of the temporal filtering",
>>                                                             OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
>> diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
>> index 21d25d643a..4845d0422d 100644
>> --- a/libavcodec/nvenc_h264.c
>> +++ b/libavcodec/nvenc_h264.c
>> @@ -231,6 +231,10 @@ static const AVOption options[] = {
>>                                                             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 },
>> +#ifdef NVENC_HAVE_FILLER_DATA
>> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
>> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>> +#endif
>> #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
>>     { "tf_level",     "Specifies the strength of the temporal filtering",
>>                                                             OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
>> diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
>> index c74eca9bb3..8648f4f3a9 100644
>> --- a/libavcodec/nvenc_hevc.c
>> +++ b/libavcodec/nvenc_hevc.c
>> @@ -206,6 +206,10 @@ static const AVOption options[] = {
>>                                                             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 },
>> +#ifdef NVENC_HAVE_FILLER_DATA
>> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
>> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>> +#endif
>> #ifdef NVENC_HAVE_TEMPORAL_FILTER
>>     { "tf_level",     "Specifies the strength of the temporal filtering",
>>                                                             OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
>> --
>> 2.49.0
> 
> 
> This should be off by default in FFmpeg. We don't do this in any other encoder.

I agree.

> 
> Kieran
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org <mailto:ffmpeg-devel-request@ffmpeg.org> with subject "unsubscribe".

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avcodec/nvenc: Use CBR filler data consistently across codecs
  2025-03-30 15:46   ` Zhao Zhili
@ 2025-03-30 16:35     ` Cameron Gutman
  0 siblings, 0 replies; 7+ messages in thread
From: Cameron Gutman @ 2025-03-30 16:35 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

On Sun, Mar 30, 2025 at 10:46 AM Zhao Zhili
<quinkblack-at-foxmail.com@ffmpeg.org> wrote:
>
>
>
> > On Mar 30, 2025, at 23:33, Kieran Kunhya via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> wrote:
> >
> > On Sun, Mar 30, 2025 at 12:04 AM Cameron Gutman <aicommander@gmail.com <mailto:aicommander@gmail.com>> wrote:
> >>
> >> Previously, AV1 used filler data with CBR by default while H.264
> >> and HEVC did not. Make this consistent by using filler data in
> >> CBR mode across all codecs.
> >>
> >> Since there are valid reasons to use CBR with or without filler,
> >> also add a cbr_padding option to allow users to opt out.
> >>
> >> Signed-off-by: Cameron Gutman <aicommander@gmail.com>
> >> ---
> >> libavcodec/nvenc.c      | 16 +++++++++++++---
> >> libavcodec/nvenc.h      |  2 ++
> >> libavcodec/nvenc_av1.c  |  2 ++
> >> libavcodec/nvenc_h264.c |  4 ++++
> >> libavcodec/nvenc_hevc.c |  4 ++++
> >> 5 files changed, 25 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
> >> index 0f5e772b3e..41a4dc55f4 100644
> >> --- a/libavcodec/nvenc.c
> >> +++ b/libavcodec/nvenc.c
> >> @@ -1304,7 +1304,12 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
> >>     h264->idrPeriod = cc->gopLength;
> >>
> >>     if (IS_CBR(cc->rcParams.rateControlMode)) {
> >> -        h264->outputBufferingPeriodSEI = 1;
> >> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
> >> +        h264->outputBufferingPeriodSEI = ctx->cbr_padding;
> >> +
> >> +#ifdef NVENC_HAVE_FILLER_DATA
> >> +        h264->enableFillerDataInsertion = ctx->cbr_padding;
> >> +#endif
> >>     }
> >>
> >>     h264->outputPictureTimingSEI = 1;
> >> @@ -1503,7 +1508,12 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
> >>     hevc->idrPeriod = cc->gopLength;
> >>
> >>     if (IS_CBR(cc->rcParams.rateControlMode)) {
> >> -        hevc->outputBufferingPeriodSEI = 1;
> >> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
> >> +        hevc->outputBufferingPeriodSEI = ctx->cbr_padding;
> >> +
> >> +#ifdef NVENC_HAVE_FILLER_DATA
> >> +        hevc->enableFillerDataInsertion = ctx->cbr_padding;
> >> +#endif
> >>     }
> >>
> >>     hevc->outputPictureTimingSEI = 1;
> >> @@ -1625,7 +1635,7 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
> >>     av1->idrPeriod = cc->gopLength;
> >>
> >>     if (IS_CBR(cc->rcParams.rateControlMode)) {
> >> -        av1->enableBitstreamPadding = 1;
> >> +        av1->enableBitstreamPadding = ctx->cbr_padding;
> >>     }
> >>
> >>     if (ctx->tile_cols >= 0)
> >> diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
> >> index e035e123c6..4b12846ed7 100644
> >> --- a/libavcodec/nvenc.h
> >> +++ b/libavcodec/nvenc.h
> >> @@ -61,6 +61,7 @@ typedef void ID3D11Device;
> >> #define NVENC_HAVE_MULTIPLE_REF_FRAMES
> >> #define NVENC_HAVE_CUSTREAM_PTR
> >> #define NVENC_HAVE_GETLASTERRORSTRING
> >> +#define NVENC_HAVE_FILLER_DATA
> >> #endif
> >>
> >> // SDK 10.0 compile time feature checks
> >> @@ -309,6 +310,7 @@ typedef struct NvencContext
> >>     int unidir_b;
> >>     int split_encode_mode;
> >>     int mdm, cll;
> >> +    int cbr_padding;
> >> } NvencContext;
> >>
> >> int ff_nvenc_encode_init(AVCodecContext *avctx);
> >> diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
> >> index 01626113ab..b1b95672f2 100644
> >> --- a/libavcodec/nvenc_av1.c
> >> +++ b/libavcodec/nvenc_av1.c
> >> @@ -156,6 +156,8 @@ static const AVOption options[] = {
> >>                                                             OFFSET(extra_sei),    AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >>     { "a53cc",        "Use A53 Closed Captions (if available)", OFFSET(a53_cc),   AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >>     { "s12m_tc",      "Use timecode (if available)",        OFFSET(s12m_tc),      AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
> >> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >> #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
> >>     { "tf_level",     "Specifies the strength of the temporal filtering",
> >>                                                             OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
> >> diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
> >> index 21d25d643a..4845d0422d 100644
> >> --- a/libavcodec/nvenc_h264.c
> >> +++ b/libavcodec/nvenc_h264.c
> >> @@ -231,6 +231,10 @@ static const AVOption options[] = {
> >>                                                             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 },
> >> +#ifdef NVENC_HAVE_FILLER_DATA
> >> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
> >> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >> +#endif
> >> #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
> >>     { "tf_level",     "Specifies the strength of the temporal filtering",
> >>                                                             OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
> >> diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
> >> index c74eca9bb3..8648f4f3a9 100644
> >> --- a/libavcodec/nvenc_hevc.c
> >> +++ b/libavcodec/nvenc_hevc.c
> >> @@ -206,6 +206,10 @@ static const AVOption options[] = {
> >>                                                             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 },
> >> +#ifdef NVENC_HAVE_FILLER_DATA
> >> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
> >> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >> +#endif
> >> #ifdef NVENC_HAVE_TEMPORAL_FILTER
> >>     { "tf_level",     "Specifies the strength of the temporal filtering",
> >>                                                             OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
> >> --
> >> 2.49.0
> >
> >
> > This should be off by default in FFmpeg. We don't do this in any other encoder.
>
> I agree.
>

Timo specifically asked for filler enabled by default, but I don't
mind defaulting disabled either if that's the consensus here.

Will send a v2 shortly.

> >
> > Kieran
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org <mailto:ffmpeg-devel@ffmpeg.org>
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-request@ffmpeg.org <mailto:ffmpeg-devel-request@ffmpeg.org> with subject "unsubscribe".
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avcodec/nvenc: Use CBR filler data consistently across codecs
  2025-03-30 15:33 ` Kieran Kunhya via ffmpeg-devel
  2025-03-30 15:46   ` Zhao Zhili
@ 2025-03-30 16:41   ` Timo Rothenpieler
  2025-03-30 18:12     ` Cameron Gutman
  1 sibling, 1 reply; 7+ messages in thread
From: Timo Rothenpieler @ 2025-03-30 16:41 UTC (permalink / raw)
  To: Kieran Kunhya, FFmpeg development discussions and patches

On 30.03.2025 17:33, Kieran Kunhya wrote:
> On Sun, Mar 30, 2025 at 12:04 AM Cameron Gutman <aicommander@gmail.com> wrote:
>>
>> Previously, AV1 used filler data with CBR by default while H.264
>> and HEVC did not. Make this consistent by using filler data in
>> CBR mode across all codecs.
>>
>> Since there are valid reasons to use CBR with or without filler,
>> also add a cbr_padding option to allow users to opt out.
>>
>> Signed-off-by: Cameron Gutman <aicommander@gmail.com>
>> ---
>>   libavcodec/nvenc.c      | 16 +++++++++++++---
>>   libavcodec/nvenc.h      |  2 ++
>>   libavcodec/nvenc_av1.c  |  2 ++
>>   libavcodec/nvenc_h264.c |  4 ++++
>>   libavcodec/nvenc_hevc.c |  4 ++++
>>   5 files changed, 25 insertions(+), 3 deletions(-)
>>
>> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
>> index 0f5e772b3e..41a4dc55f4 100644
>> --- a/libavcodec/nvenc.c
>> +++ b/libavcodec/nvenc.c
>> @@ -1304,7 +1304,12 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
>>       h264->idrPeriod = cc->gopLength;
>>
>>       if (IS_CBR(cc->rcParams.rateControlMode)) {
>> -        h264->outputBufferingPeriodSEI = 1;
>> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
>> +        h264->outputBufferingPeriodSEI = ctx->cbr_padding;
>> +
>> +#ifdef NVENC_HAVE_FILLER_DATA
>> +        h264->enableFillerDataInsertion = ctx->cbr_padding;
>> +#endif
>>       }
>>
>>       h264->outputPictureTimingSEI = 1;
>> @@ -1503,7 +1508,12 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
>>       hevc->idrPeriod = cc->gopLength;
>>
>>       if (IS_CBR(cc->rcParams.rateControlMode)) {
>> -        hevc->outputBufferingPeriodSEI = 1;
>> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
>> +        hevc->outputBufferingPeriodSEI = ctx->cbr_padding;
>> +
>> +#ifdef NVENC_HAVE_FILLER_DATA
>> +        hevc->enableFillerDataInsertion = ctx->cbr_padding;
>> +#endif
>>       }
>>
>>       hevc->outputPictureTimingSEI = 1;
>> @@ -1625,7 +1635,7 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
>>       av1->idrPeriod = cc->gopLength;
>>
>>       if (IS_CBR(cc->rcParams.rateControlMode)) {
>> -        av1->enableBitstreamPadding = 1;
>> +        av1->enableBitstreamPadding = ctx->cbr_padding;
>>       }
>>
>>       if (ctx->tile_cols >= 0)
>> diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
>> index e035e123c6..4b12846ed7 100644
>> --- a/libavcodec/nvenc.h
>> +++ b/libavcodec/nvenc.h
>> @@ -61,6 +61,7 @@ typedef void ID3D11Device;
>>   #define NVENC_HAVE_MULTIPLE_REF_FRAMES
>>   #define NVENC_HAVE_CUSTREAM_PTR
>>   #define NVENC_HAVE_GETLASTERRORSTRING
>> +#define NVENC_HAVE_FILLER_DATA
>>   #endif
>>
>>   // SDK 10.0 compile time feature checks
>> @@ -309,6 +310,7 @@ typedef struct NvencContext
>>       int unidir_b;
>>       int split_encode_mode;
>>       int mdm, cll;
>> +    int cbr_padding;
>>   } NvencContext;
>>
>>   int ff_nvenc_encode_init(AVCodecContext *avctx);
>> diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
>> index 01626113ab..b1b95672f2 100644
>> --- a/libavcodec/nvenc_av1.c
>> +++ b/libavcodec/nvenc_av1.c
>> @@ -156,6 +156,8 @@ static const AVOption options[] = {
>>                                                               OFFSET(extra_sei),    AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>       { "a53cc",        "Use A53 Closed Captions (if available)", OFFSET(a53_cc),   AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>       { "s12m_tc",      "Use timecode (if available)",        OFFSET(s12m_tc),      AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
>> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>   #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
>>       { "tf_level",     "Specifies the strength of the temporal filtering",
>>                                                               OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
>> diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
>> index 21d25d643a..4845d0422d 100644
>> --- a/libavcodec/nvenc_h264.c
>> +++ b/libavcodec/nvenc_h264.c
>> @@ -231,6 +231,10 @@ static const AVOption options[] = {
>>                                                               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 },
>> +#ifdef NVENC_HAVE_FILLER_DATA
>> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
>> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>> +#endif
>>   #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
>>       { "tf_level",     "Specifies the strength of the temporal filtering",
>>                                                               OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
>> diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
>> index c74eca9bb3..8648f4f3a9 100644
>> --- a/libavcodec/nvenc_hevc.c
>> +++ b/libavcodec/nvenc_hevc.c
>> @@ -206,6 +206,10 @@ static const AVOption options[] = {
>>                                                               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 },
>> +#ifdef NVENC_HAVE_FILLER_DATA
>> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
>> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>> +#endif
>>   #ifdef NVENC_HAVE_TEMPORAL_FILTER
>>       { "tf_level",     "Specifies the strength of the temporal filtering",
>>                                                               OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
>> --
>> 2.49.0
> 
> 
> This should be off by default in FFmpeg. We don't do this in any other encoder.

It's been on by default in nvenc since always, so turning it off now is 
an API break.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avcodec/nvenc: Use CBR filler data consistently across codecs
  2025-03-30 16:41   ` Timo Rothenpieler
@ 2025-03-30 18:12     ` Cameron Gutman
  2025-03-31 12:19       ` Timo Rothenpieler
  0 siblings, 1 reply; 7+ messages in thread
From: Cameron Gutman @ 2025-03-30 18:12 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Kieran Kunhya

On Sun, Mar 30, 2025 at 11:41 AM Timo Rothenpieler
<timo@rothenpieler.org> wrote:
>
> On 30.03.2025 17:33, Kieran Kunhya wrote:
> > On Sun, Mar 30, 2025 at 12:04 AM Cameron Gutman <aicommander@gmail.com> wrote:
> >>
> >> Previously, AV1 used filler data with CBR by default while H.264
> >> and HEVC did not. Make this consistent by using filler data in
> >> CBR mode across all codecs.
> >>
> >> Since there are valid reasons to use CBR with or without filler,
> >> also add a cbr_padding option to allow users to opt out.
> >>
> >> Signed-off-by: Cameron Gutman <aicommander@gmail.com>
> >> ---
> >>   libavcodec/nvenc.c      | 16 +++++++++++++---
> >>   libavcodec/nvenc.h      |  2 ++
> >>   libavcodec/nvenc_av1.c  |  2 ++
> >>   libavcodec/nvenc_h264.c |  4 ++++
> >>   libavcodec/nvenc_hevc.c |  4 ++++
> >>   5 files changed, 25 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
> >> index 0f5e772b3e..41a4dc55f4 100644
> >> --- a/libavcodec/nvenc.c
> >> +++ b/libavcodec/nvenc.c
> >> @@ -1304,7 +1304,12 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
> >>       h264->idrPeriod = cc->gopLength;
> >>
> >>       if (IS_CBR(cc->rcParams.rateControlMode)) {
> >> -        h264->outputBufferingPeriodSEI = 1;
> >> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
> >> +        h264->outputBufferingPeriodSEI = ctx->cbr_padding;
> >> +
> >> +#ifdef NVENC_HAVE_FILLER_DATA
> >> +        h264->enableFillerDataInsertion = ctx->cbr_padding;
> >> +#endif
> >>       }
> >>
> >>       h264->outputPictureTimingSEI = 1;
> >> @@ -1503,7 +1508,12 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
> >>       hevc->idrPeriod = cc->gopLength;
> >>
> >>       if (IS_CBR(cc->rcParams.rateControlMode)) {
> >> -        hevc->outputBufferingPeriodSEI = 1;
> >> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
> >> +        hevc->outputBufferingPeriodSEI = ctx->cbr_padding;
> >> +
> >> +#ifdef NVENC_HAVE_FILLER_DATA
> >> +        hevc->enableFillerDataInsertion = ctx->cbr_padding;
> >> +#endif
> >>       }
> >>
> >>       hevc->outputPictureTimingSEI = 1;
> >> @@ -1625,7 +1635,7 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
> >>       av1->idrPeriod = cc->gopLength;
> >>
> >>       if (IS_CBR(cc->rcParams.rateControlMode)) {
> >> -        av1->enableBitstreamPadding = 1;
> >> +        av1->enableBitstreamPadding = ctx->cbr_padding;
> >>       }
> >>
> >>       if (ctx->tile_cols >= 0)
> >> diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
> >> index e035e123c6..4b12846ed7 100644
> >> --- a/libavcodec/nvenc.h
> >> +++ b/libavcodec/nvenc.h
> >> @@ -61,6 +61,7 @@ typedef void ID3D11Device;
> >>   #define NVENC_HAVE_MULTIPLE_REF_FRAMES
> >>   #define NVENC_HAVE_CUSTREAM_PTR
> >>   #define NVENC_HAVE_GETLASTERRORSTRING
> >> +#define NVENC_HAVE_FILLER_DATA
> >>   #endif
> >>
> >>   // SDK 10.0 compile time feature checks
> >> @@ -309,6 +310,7 @@ typedef struct NvencContext
> >>       int unidir_b;
> >>       int split_encode_mode;
> >>       int mdm, cll;
> >> +    int cbr_padding;
> >>   } NvencContext;
> >>
> >>   int ff_nvenc_encode_init(AVCodecContext *avctx);
> >> diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
> >> index 01626113ab..b1b95672f2 100644
> >> --- a/libavcodec/nvenc_av1.c
> >> +++ b/libavcodec/nvenc_av1.c
> >> @@ -156,6 +156,8 @@ static const AVOption options[] = {
> >>                                                               OFFSET(extra_sei),    AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >>       { "a53cc",        "Use A53 Closed Captions (if available)", OFFSET(a53_cc),   AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >>       { "s12m_tc",      "Use timecode (if available)",        OFFSET(s12m_tc),      AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
> >> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >>   #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
> >>       { "tf_level",     "Specifies the strength of the temporal filtering",
> >>                                                               OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
> >> diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
> >> index 21d25d643a..4845d0422d 100644
> >> --- a/libavcodec/nvenc_h264.c
> >> +++ b/libavcodec/nvenc_h264.c
> >> @@ -231,6 +231,10 @@ static const AVOption options[] = {
> >>                                                               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 },
> >> +#ifdef NVENC_HAVE_FILLER_DATA
> >> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
> >> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >> +#endif
> >>   #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
> >>       { "tf_level",     "Specifies the strength of the temporal filtering",
> >>                                                               OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
> >> diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
> >> index c74eca9bb3..8648f4f3a9 100644
> >> --- a/libavcodec/nvenc_hevc.c
> >> +++ b/libavcodec/nvenc_hevc.c
> >> @@ -206,6 +206,10 @@ static const AVOption options[] = {
> >>                                                               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 },
> >> +#ifdef NVENC_HAVE_FILLER_DATA
> >> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
> >> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
> >> +#endif
> >>   #ifdef NVENC_HAVE_TEMPORAL_FILTER
> >>       { "tf_level",     "Specifies the strength of the temporal filtering",
> >>                                                               OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
> >> --
> >> 2.49.0
> >
> >
> > This should be off by default in FFmpeg. We don't do this in any other encoder.
>
> It's been on by default in nvenc since always, so turning it off now is
> an API break.

That's been the intention, but it doesn't actually consistently work
that way with current drivers (likely due to the change in semantics
of the outputBufferingPeriodSEI field and introduction of
enableFillerDataInsertion field in the Video Codec SDK).

I confirmed with the latest 572.83 drivers the current FFmpeg
nvenc_hevc code does not add filler with CBR. Someone actually
reported this a couple years ago in
https://trac.ffmpeg.org/ticket/10043. With this patch, filler data is
inserted for HEVC as the reporter expected.

Interestingly with nvenc_h264, I do not see any difference in the
output bitrate with or without enableFillerDataInsertion set. It could
be a driver bug or just because I haven't managed to get the encoder
configured in a way that will cause it to need filler to maintain CBR
bitrate.

Not sure if this helps or just makes the situation even more confusing :)

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avcodec/nvenc: Use CBR filler data consistently across codecs
  2025-03-30 18:12     ` Cameron Gutman
@ 2025-03-31 12:19       ` Timo Rothenpieler
  0 siblings, 0 replies; 7+ messages in thread
From: Timo Rothenpieler @ 2025-03-31 12:19 UTC (permalink / raw)
  To: ffmpeg-devel

On 30/03/2025 20:12, Cameron Gutman wrote:
> On Sun, Mar 30, 2025 at 11:41 AM Timo Rothenpieler
> <timo@rothenpieler.org> wrote:
>>
>> On 30.03.2025 17:33, Kieran Kunhya wrote:
>>> On Sun, Mar 30, 2025 at 12:04 AM Cameron Gutman <aicommander@gmail.com> wrote:
>>>>
>>>> Previously, AV1 used filler data with CBR by default while H.264
>>>> and HEVC did not. Make this consistent by using filler data in
>>>> CBR mode across all codecs.
>>>>
>>>> Since there are valid reasons to use CBR with or without filler,
>>>> also add a cbr_padding option to allow users to opt out.
>>>>
>>>> Signed-off-by: Cameron Gutman <aicommander@gmail.com>
>>>> ---
>>>>    libavcodec/nvenc.c      | 16 +++++++++++++---
>>>>    libavcodec/nvenc.h      |  2 ++
>>>>    libavcodec/nvenc_av1.c  |  2 ++
>>>>    libavcodec/nvenc_h264.c |  4 ++++
>>>>    libavcodec/nvenc_hevc.c |  4 ++++
>>>>    5 files changed, 25 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
>>>> index 0f5e772b3e..41a4dc55f4 100644
>>>> --- a/libavcodec/nvenc.c
>>>> +++ b/libavcodec/nvenc.c
>>>> @@ -1304,7 +1304,12 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
>>>>        h264->idrPeriod = cc->gopLength;
>>>>
>>>>        if (IS_CBR(cc->rcParams.rateControlMode)) {
>>>> -        h264->outputBufferingPeriodSEI = 1;
>>>> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
>>>> +        h264->outputBufferingPeriodSEI = ctx->cbr_padding;
>>>> +
>>>> +#ifdef NVENC_HAVE_FILLER_DATA
>>>> +        h264->enableFillerDataInsertion = ctx->cbr_padding;
>>>> +#endif
>>>>        }
>>>>
>>>>        h264->outputPictureTimingSEI = 1;
>>>> @@ -1503,7 +1508,12 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
>>>>        hevc->idrPeriod = cc->gopLength;
>>>>
>>>>        if (IS_CBR(cc->rcParams.rateControlMode)) {
>>>> -        hevc->outputBufferingPeriodSEI = 1;
>>>> +        /* Older SDKs use outputBufferingPeriodSEI to control filler data */
>>>> +        hevc->outputBufferingPeriodSEI = ctx->cbr_padding;
>>>> +
>>>> +#ifdef NVENC_HAVE_FILLER_DATA
>>>> +        hevc->enableFillerDataInsertion = ctx->cbr_padding;
>>>> +#endif
>>>>        }
>>>>
>>>>        hevc->outputPictureTimingSEI = 1;
>>>> @@ -1625,7 +1635,7 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
>>>>        av1->idrPeriod = cc->gopLength;
>>>>
>>>>        if (IS_CBR(cc->rcParams.rateControlMode)) {
>>>> -        av1->enableBitstreamPadding = 1;
>>>> +        av1->enableBitstreamPadding = ctx->cbr_padding;
>>>>        }
>>>>
>>>>        if (ctx->tile_cols >= 0)
>>>> diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
>>>> index e035e123c6..4b12846ed7 100644
>>>> --- a/libavcodec/nvenc.h
>>>> +++ b/libavcodec/nvenc.h
>>>> @@ -61,6 +61,7 @@ typedef void ID3D11Device;
>>>>    #define NVENC_HAVE_MULTIPLE_REF_FRAMES
>>>>    #define NVENC_HAVE_CUSTREAM_PTR
>>>>    #define NVENC_HAVE_GETLASTERRORSTRING
>>>> +#define NVENC_HAVE_FILLER_DATA
>>>>    #endif
>>>>
>>>>    // SDK 10.0 compile time feature checks
>>>> @@ -309,6 +310,7 @@ typedef struct NvencContext
>>>>        int unidir_b;
>>>>        int split_encode_mode;
>>>>        int mdm, cll;
>>>> +    int cbr_padding;
>>>>    } NvencContext;
>>>>
>>>>    int ff_nvenc_encode_init(AVCodecContext *avctx);
>>>> diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
>>>> index 01626113ab..b1b95672f2 100644
>>>> --- a/libavcodec/nvenc_av1.c
>>>> +++ b/libavcodec/nvenc_av1.c
>>>> @@ -156,6 +156,8 @@ static const AVOption options[] = {
>>>>                                                                OFFSET(extra_sei),    AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>>>        { "a53cc",        "Use A53 Closed Captions (if available)", OFFSET(a53_cc),   AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>>>        { "s12m_tc",      "Use timecode (if available)",        OFFSET(s12m_tc),      AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>>> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
>>>> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>>>    #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
>>>>        { "tf_level",     "Specifies the strength of the temporal filtering",
>>>>                                                                OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
>>>> diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
>>>> index 21d25d643a..4845d0422d 100644
>>>> --- a/libavcodec/nvenc_h264.c
>>>> +++ b/libavcodec/nvenc_h264.c
>>>> @@ -231,6 +231,10 @@ static const AVOption options[] = {
>>>>                                                                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 },
>>>> +#ifdef NVENC_HAVE_FILLER_DATA
>>>> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
>>>> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>>> +#endif
>>>>    #ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
>>>>        { "tf_level",     "Specifies the strength of the temporal filtering",
>>>>                                                                OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
>>>> diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
>>>> index c74eca9bb3..8648f4f3a9 100644
>>>> --- a/libavcodec/nvenc_hevc.c
>>>> +++ b/libavcodec/nvenc_hevc.c
>>>> @@ -206,6 +206,10 @@ static const AVOption options[] = {
>>>>                                                                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 },
>>>> +#ifdef NVENC_HAVE_FILLER_DATA
>>>> +    { "cbr_padding",  "Pad the bitstream to ensure bitrate does not drop below the target in CBR mode",
>>>> +                                                            OFFSET(cbr_padding),  AV_OPT_TYPE_BOOL,  { .i64 = 1 }, 0, 1, VE },
>>>> +#endif
>>>>    #ifdef NVENC_HAVE_TEMPORAL_FILTER
>>>>        { "tf_level",     "Specifies the strength of the temporal filtering",
>>>>                                                                OFFSET(tf_level),     AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
>>>> --
>>>> 2.49.0
>>>
>>>
>>> This should be off by default in FFmpeg. We don't do this in any other encoder.
>>
>> It's been on by default in nvenc since always, so turning it off now is
>> an API break.
> 
> That's been the intention, but it doesn't actually consistently work
> that way with current drivers (likely due to the change in semantics
> of the outputBufferingPeriodSEI field and introduction of
> enableFillerDataInsertion field in the Video Codec SDK).
> 
> I confirmed with the latest 572.83 drivers the current FFmpeg
> nvenc_hevc code does not add filler with CBR. Someone actually
> reported this a couple years ago in
> https://trac.ffmpeg.org/ticket/10043. With this patch, filler data is
> inserted for HEVC as the reporter expected.
> 
> Interestingly with nvenc_h264, I do not see any difference in the
> output bitrate with or without enableFillerDataInsertion set. It could
> be a driver bug or just because I haven't managed to get the encoder
> configured in a way that will cause it to need filler to maintain CBR
> bitrate.
> 
> Not sure if this helps or just makes the situation even more confusing :)

If it's been off by default for HEVC and AV1, it can remain like that.

Not sure what's going on with h264, if it makes no difference in 
behaviour I'd also add the option as default-off and then leave it to 
nvidia to figure things out.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2025-03-31 12:18 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-30  0:04 [FFmpeg-devel] [PATCH] avcodec/nvenc: Use CBR filler data consistently across codecs Cameron Gutman
2025-03-30 15:33 ` Kieran Kunhya via ffmpeg-devel
2025-03-30 15:46   ` Zhao Zhili
2025-03-30 16:35     ` Cameron Gutman
2025-03-30 16:41   ` Timo Rothenpieler
2025-03-30 18:12     ` Cameron Gutman
2025-03-31 12:19       ` Timo Rothenpieler

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git