diff mbox series

[FFmpeg-devel,v4,3/9] lavc/libopenh264enc: add bit rate control select support

Message ID 1586926427-20170-4-git-send-email-linjie.fu@intel.com
State Superseded
Headers show
Series Enhancement for libopenh264 encoder
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Fu, Linjie April 15, 2020, 4:53 a.m. UTC
RC_BITRATE_MODE:
    set BITS_EXCEEDED to iCurrentBitsLevel and allows QP adjust
    in RcCalculatePictureQp().

RC_BUFFERBASED_MODE:
    use buffer status to adjust the video quality.

RC_TIMESTAMP_MODE:
    bit rate control based on timestamp.

Default to use RC_QUALITY_MODE.

Signed-off-by: Linjie Fu <linjie.fu@intel.com>
---
 libavcodec/libopenh264enc.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

Martin Storsjö April 27, 2020, 7:35 p.m. UTC | #1
On Wed, 15 Apr 2020, Linjie Fu wrote:

> RC_BITRATE_MODE:
>    set BITS_EXCEEDED to iCurrentBitsLevel and allows QP adjust
>    in RcCalculatePictureQp().
>
> RC_BUFFERBASED_MODE:
>    use buffer status to adjust the video quality.
>
> RC_TIMESTAMP_MODE:
>    bit rate control based on timestamp.
>
> Default to use RC_QUALITY_MODE.
>
> Signed-off-by: Linjie Fu <linjie.fu@intel.com>
> ---
> libavcodec/libopenh264enc.c | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/libopenh264enc.c b/libavcodec/libopenh264enc.c
> index 57313b1..f994f95 100644
> --- a/libavcodec/libopenh264enc.c
> +++ b/libavcodec/libopenh264enc.c
> @@ -47,6 +47,9 @@ typedef struct SVCContext {
>     int skip_frames;
>     int skipped;
>     int cabac;
> +
> +    // rate control mode
> +    int rc_mode;
> } SVCContext;
> 
> #define OFFSET(x) offsetof(SVCContext, x)
> @@ -71,6 +74,13 @@ static const AVOption options[] = {
>     { "max_nal_size", "set maximum NAL size in bytes", OFFSET(max_nal_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
>     { "allow_skip_frames", "allow skipping frames to hit the target bitrate", OFFSET(skip_frames), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
>     { "cabac", "Enable cabac", OFFSET(cabac), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
> +
> +    { "rc_mode", "Select rate control mode", OFFSET(rc_mode), AV_OPT_TYPE_INT, { .i64 = RC_QUALITY_MODE }, RC_OFF_MODE, RC_TIMESTAMP_MODE, VE, "rc_mode" },
> +        { "off",       "bit rate control off",                                                 0, AV_OPT_TYPE_CONST, { .i64 = RC_OFF_MODE },         0, 0, VE, "rc_mode" },
> +        { "quality",   "quality mode",                                                         0, AV_OPT_TYPE_CONST, { .i64 = RC_QUALITY_MODE },     0, 0, VE, "rc_mode" },
> +        { "bitrate",   "bitrate mode",                                                         0, AV_OPT_TYPE_CONST, { .i64 = RC_BITRATE_MODE },     0, 0, VE, "rc_mode" },
> +        { "buffer",    "using buffer status to adjust the video quality (no bitrate control)", 0, AV_OPT_TYPE_CONST, { .i64 = RC_BUFFERBASED_MODE }, 0, 0, VE, "rc_mode" },
> +        { "timestamp", "bit rate control based on timestamp",                                  0, AV_OPT_TYPE_CONST, { .i64 = RC_TIMESTAMP_MODE },   0, 0, VE, "rc_mode" },
>     { NULL }
> };
> 
> @@ -134,7 +144,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
>     param.iPicHeight                 = avctx->height;
>     param.iTargetBitrate             = avctx->bit_rate > 0 ? avctx->bit_rate : 2*1000*1000;
>     param.iMaxBitrate                = FFMAX(avctx->rc_max_rate, avctx->bit_rate);
> -    param.iRCMode                    = RC_QUALITY_MODE;
> +    param.iRCMode                    = s->rc_mode;
>     // QP = 0 is not well supported, so default to (1, 51)
>     param.iMaxQp                     = avctx->qmax >= 0 ? av_clip(avctx->qmax, 1, 51) : 51;
>     param.iMinQp                     = avctx->qmin >= 0 ? av_clip(avctx->qmin, 1, param.iMaxQp) : 1;
> -- 
> 2.7.4

This looks ok, but I don't think all of these have been available since 
the beginning. We do support building with a few older versions of the 
library, so I think at least RC_TIMESTAMP_MODE appeared later. The lowest 
version that was supported originally was OpenH264 1.3, so for things that 
have appeared later, please add ifdefs (or consistently bump the minimum 
version somewhere and remove redundant checks for lower versions).

// Martin
Fu, Linjie April 28, 2020, 7:36 a.m. UTC | #2
> From: Martin Storsjö <martin@martin.st>
> Sent: Tuesday, April 28, 2020 03:35
> To: FFmpeg development discussions and patches <ffmpeg-
> devel@ffmpeg.org>
> Cc: Fu, Linjie <linjie.fu@intel.com>
> Subject: Re: [FFmpeg-devel] [PATCH v4 3/9] lavc/libopenh264enc: add bit
> rate control select support
> 
> On Wed, 15 Apr 2020, Linjie Fu wrote:
> 
> > RC_BITRATE_MODE:
> >    set BITS_EXCEEDED to iCurrentBitsLevel and allows QP adjust
> >    in RcCalculatePictureQp().
> >
> > RC_BUFFERBASED_MODE:
> >    use buffer status to adjust the video quality.
> >
> > RC_TIMESTAMP_MODE:
> >    bit rate control based on timestamp.
> >
> > Default to use RC_QUALITY_MODE.
> >
> > Signed-off-by: Linjie Fu <linjie.fu@intel.com>
> > ---
> > libavcodec/libopenh264enc.c | 12 +++++++++++-
> > 1 file changed, 11 insertions(+), 1 deletion(-)
> 
> This looks ok, but I don't think all of these have been available since
> the beginning. We do support building with a few older versions of the
> library, so I think at least RC_TIMESTAMP_MODE appeared later. The lowest
> version that was supported originally was OpenH264 1.3, so for things that
> have appeared later, please add ifdefs (or consistently bump the minimum
> version somewhere and remove redundant checks for lower versions).
> 

Double checked this in the release history:
RC_BUFFERBASED_MODE was introduced since release 1.2;
RC_TIMESTAMP_MODE was introduced since release 1.4.

Updated.

- Linjie
diff mbox series

Patch

diff --git a/libavcodec/libopenh264enc.c b/libavcodec/libopenh264enc.c
index 57313b1..f994f95 100644
--- a/libavcodec/libopenh264enc.c
+++ b/libavcodec/libopenh264enc.c
@@ -47,6 +47,9 @@  typedef struct SVCContext {
     int skip_frames;
     int skipped;
     int cabac;
+
+    // rate control mode
+    int rc_mode;
 } SVCContext;
 
 #define OFFSET(x) offsetof(SVCContext, x)
@@ -71,6 +74,13 @@  static const AVOption options[] = {
     { "max_nal_size", "set maximum NAL size in bytes", OFFSET(max_nal_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
     { "allow_skip_frames", "allow skipping frames to hit the target bitrate", OFFSET(skip_frames), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
     { "cabac", "Enable cabac", OFFSET(cabac), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+
+    { "rc_mode", "Select rate control mode", OFFSET(rc_mode), AV_OPT_TYPE_INT, { .i64 = RC_QUALITY_MODE }, RC_OFF_MODE, RC_TIMESTAMP_MODE, VE, "rc_mode" },
+        { "off",       "bit rate control off",                                                 0, AV_OPT_TYPE_CONST, { .i64 = RC_OFF_MODE },         0, 0, VE, "rc_mode" },
+        { "quality",   "quality mode",                                                         0, AV_OPT_TYPE_CONST, { .i64 = RC_QUALITY_MODE },     0, 0, VE, "rc_mode" },
+        { "bitrate",   "bitrate mode",                                                         0, AV_OPT_TYPE_CONST, { .i64 = RC_BITRATE_MODE },     0, 0, VE, "rc_mode" },
+        { "buffer",    "using buffer status to adjust the video quality (no bitrate control)", 0, AV_OPT_TYPE_CONST, { .i64 = RC_BUFFERBASED_MODE }, 0, 0, VE, "rc_mode" },
+        { "timestamp", "bit rate control based on timestamp",                                  0, AV_OPT_TYPE_CONST, { .i64 = RC_TIMESTAMP_MODE },   0, 0, VE, "rc_mode" },
     { NULL }
 };
 
@@ -134,7 +144,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
     param.iPicHeight                 = avctx->height;
     param.iTargetBitrate             = avctx->bit_rate > 0 ? avctx->bit_rate : 2*1000*1000;
     param.iMaxBitrate                = FFMAX(avctx->rc_max_rate, avctx->bit_rate);
-    param.iRCMode                    = RC_QUALITY_MODE;
+    param.iRCMode                    = s->rc_mode;
     // QP = 0 is not well supported, so default to (1, 51)
     param.iMaxQp                     = avctx->qmax >= 0 ? av_clip(avctx->qmax, 1, 51) : 51;
     param.iMinQp                     = avctx->qmin >= 0 ? av_clip(avctx->qmin, 1, param.iMaxQp) : 1;