diff mbox

[FFmpeg-devel,v2,16/36] vaapi_encode: Clean up rate control configuration

Message ID 5540c08e-fd41-0138-fea0-c7a33da66621@jkqxz.net
State Superseded
Headers show

Commit Message

Mark Thompson June 25, 2018, 9:30 p.m. UTC
On 21/06/18 18:03, Michael Niedermayer wrote:
> On Thu, Jun 21, 2018 at 12:10:04AM +0100, Mark Thompson wrote:
>> On 20/06/18 10:44, Li, Zhong wrote:
>>>> -----Original Message-----
>>>> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf
>>>> Of Mark Thompson
>>>> Sent: Sunday, June 17, 2018 9:51 PM
>>>> To: ffmpeg-devel@ffmpeg.org
>>>> Subject: Re: [FFmpeg-devel] [PATCH v2 16/36] vaapi_encode: Clean up rate
>>>> control configuration
>>>>
>>>> On 14/06/18 08:22, Li, Zhong wrote:
>>>>>> -----Original Message-----
>>>>>> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On
>>>> Behalf
>>>>>> Of Xiang, Haihao
>>>>>> Sent: Thursday, June 14, 2018 2:08 PM
>>>>>> To: ffmpeg-devel@ffmpeg.org
>>>>>> Subject: Re: [FFmpeg-devel] [PATCH v2 16/36] vaapi_encode: Clean up
>>>>>> rate control configuration
>>>>>>
>>>>>> On Wed, 2018-06-13 at 23:42 +0100, Mark Thompson wrote:
>>>>>>> On 13/06/18 08:03, Xiang, Haihao wrote:
>>>>>>>> On Fri, 2018-06-08 at 00:43 +0100, Mark Thompson wrote:
>>>>>>>>> Query which modes are supported and select between VBR and CBR
>>>>>>>>> based on that - this removes all of the codec-specific rate
>>>>>>>>> control mode selection code.
>>>>>>>>> ---
>>>>>>>>>  doc/encoders.texi               |   2 -
>>>>>>>>>  libavcodec/vaapi_encode.c       | 173
>>>>>> ++++++++++++++++++++++++++++-------
>>>>>>>>> ----
>>>>>>>>> -
>>>>>>>>>  libavcodec/vaapi_encode.h       |   6 +-
>>>>>>>>>  libavcodec/vaapi_encode_h264.c  |  18 +----
>>>>>>>>> libavcodec/vaapi_encode_h265.c  |  14 +---
>>>>>>>>>  libavcodec/vaapi_encode_mjpeg.c |   3 +-
>>>>>>>>>  libavcodec/vaapi_encode_mpeg2.c |   9 +--
>>>>>>>>>  libavcodec/vaapi_encode_vp8.c   |  13 +--
>>>>>>>>>  libavcodec/vaapi_encode_vp9.c   |  13 +--
>>>>>>>>>  9 files changed, 137 insertions(+), 114 deletions(-)
>>>>>>>>>
>>>>>>>>> ...
>>>>>>>>> diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
>>>>>>>>> index f4c063734c..5de5483454 100644
>>>>>>>>> --- a/libavcodec/vaapi_encode.c
>>>>>>>>> +++ b/libavcodec/vaapi_encode.c
>>>>>>>>> ...
>>>>>>>>> +    if (avctx->flags & AV_CODEC_FLAG_QSCALE ||
>>>>>>>>> +        avctx->bit_rate <= 0) {
>>>>
>>>> This condition ^
>>>>
>>>>>>>>> +        if (rc_attr.value & VA_RC_CQP) {
>>>>>>>>> +            av_log(avctx, AV_LOG_VERBOSE, "Using
>>>>>> constant-quality
>>>>>>>>> mode.\n");
>>>>>>>>> +            ctx->va_rc_mode = VA_RC_CQP;
>>>>>>>>> +            return 0;
>>>>>>>>> +        } else {
>>>>>>>>> +            av_log(avctx, AV_LOG_ERROR, "Driver does not
>>>>>> support "
>>>>>>>>> +                   "constant-quality mode (%#x).\n",
>>>>>> rc_attr.value);
>>>>>>>>> +            return AVERROR(EINVAL);
>>>>>>>>> +        }
>>>>>>>>> +    }
>>>>>>>>> ...
>>>>>>>>> +    } else if (avctx->rc_max_rate == avctx->bit_rate) {
>>>>>>>>> +        if (!(rc_attr.value & VA_RC_CBR)) {
>>>>>>>>> +            av_log(avctx, AV_LOG_WARNING, "Driver does not
>>>>>> support "
>>>>>>>>> +                   "CBR mode (%#x), using VBR mode
>>>>>> instead.\n",
>>>>>>>>> +                   rc_attr.value);
>>>>>>>>> +            ctx->va_rc_mode = VA_RC_VBR;
>>>>>>>>> +        } else {
>>>>>>>>> +            ctx->va_rc_mode = VA_RC_CBR;
>>>>>>>>> +        }
>>>>>>>>>
>>>>>>>>> -    if (ctx->va_rc_mode == VA_RC_CBR) {
>>>>>>>>>          rc_bits_per_second   = avctx->bit_rate;
>>>>>>>>>          rc_target_percentage = 100;
>>>>>>>>> -        rc_window_size       = 1000;
>>>>>>>>> +
>>>>>>>>>      } else {
>>>>>>>>> -        if (avctx->rc_max_rate < avctx->bit_rate) {
>>>>>>>>> -            // Max rate is unset or invalid, just use the normal
>>>>>> bitrate.
>>>>>>>>> +        if (rc_attr.value & VA_RC_VBR) {
>>>>>>>>> +            ctx->va_rc_mode = VA_RC_VBR;
>>>>>>>>
>>>>>>>> Is it better to take it as CBR when avctx->rc_max_rate is 0 and CBR
>>>>>>>> is supported by driver?
>>>>>>>
>>>>>>> I don't think so?  VBR with the specified target is probably what
>>>>>>> you want in most cases, and I think anyone with specific constraints
>>>>>>> that want constant bitrate should expect to set maxrate to achieve that.
>>>>>>>
>>>>>>
>>>>>> I agree VBR is probably what an user wants in most case, however
>>>>>> target percent set to 50% is not suitable for most case. To get a
>>>>>> specific target percent, user should set both target bitrate and max
>>>>>> bitrate, so it is reasonable to ask user must set both target bitrate
>>>>>> and max bitrate for VBR cases, and for CBR user may set target bitrate
>>>> only.
>>>>>
>>>>> How about set the max_rate to be a very larger number such as INT_MAX
>>>> if user hasn't set it?
>>>>> User may don't set max_rate on purpose, expecting better quality with
>>>> unlimited bitrate fluctuation (common requirement for local video files).
>>>>> Double of target_bit_rate is too strict IMHO. And I haven't such a
>>>> limitation in x264 ABR mode.
>>>>
>>>> This unconstrained setup you describe was my intent (as you say, it's usually
>>>> what you want for local files), but unfortunately the API doesn't really let us
>>>> do it - the target bitrate is specified as an integer percentage of the max
>>>> bitrate.  50% was an arbitrary value picked to not have a strong constraint
>>>> but also not be small enough that we need to think about rounding/overflow
>>>> problems.
>>>>
>>>> We could try to pick a large value with the right properties (for example: if
>>>> target < 2^32 / 100 then choose maxrate = target * 100, percentage = 1;
>>>> otherwise choose percentage = 2^32 * 100 / bitrate, maxrate = bitrate * 100
>>>> / percentage), but that would be complex to test and I don't think the drivers
>>>> handle this sort of setup very well.
>>>>
>>>>>> I just saw it is also VBR in QSV when max bitrate is not set so I'm
>>>>>> fine to keep consistency with QSV for this case.
>>>>>
>>>>> What will happen if user set a max_rate but without a setting for
>>>> target_bitrate?
>>>>> The mode will be VBR (if driver support) with target_bitrate=0.
>>>>> Tried this on qsv, MSDK returns an error of invalid video parameters.
>>>>> Is it ok for vaapi? And also with iHD driver?
>>>>
>>>> If AVCodecContext.bit_rate isn't set then we use constant-quality mode
>>>> instead - see the block I've pointed out above.
>>>>
>>>> There isn't currently any constant-quality with max-rate constraint mode in
>>>> VAAPI.
>>>
>>> Then the problem I see is that -max_rate hasn't been respected well if user set it (he may don't care about the target bitrate except the peak value). 
>>> Maybe we can add a warning at least? 
>>
>> Given that it's really CQP, I don't think anyone would ever expect this to work?  Encoders generally don't warn about ignoring extra irrelevant options in AVCodecContext.
>>
>> (Is there any encoder at all which supports that combination?  E.g. libx264 supports maxrate in CRF but not CQP mode.) 
> 
> if i understand correctly, then yes, see vbv_ignore_qmax. If max rate
> cannot be achievied the mpegvideo encoders should attempt to encode the frame
> again without qmax and at lower quality

Ok, fair enough.

I've added a warning as below so that it's clear this case isn't supported.


Thanks,

- Mark

Comments

Zhong Li July 3, 2018, 5:14 a.m. UTC | #1
> -----Original Message-----

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> Of Mark Thompson

> Sent: Tuesday, June 26, 2018 5:30 AM

> To: ffmpeg-devel@ffmpeg.org

> Subject: Re: [FFmpeg-devel] [PATCH v2 16/36] vaapi_encode: Clean up rate

> control configuration

> 

> On 21/06/18 18:03, Michael Niedermayer wrote:

> > On Thu, Jun 21, 2018 at 12:10:04AM +0100, Mark Thompson wrote:

> >> On 20/06/18 10:44, Li, Zhong wrote:

> >>>> -----Original Message-----

> >>>> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On

> >>>> Behalf Of Mark Thompson

> >>>> Sent: Sunday, June 17, 2018 9:51 PM

> >>>> To: ffmpeg-devel@ffmpeg.org

> >>>> Subject: Re: [FFmpeg-devel] [PATCH v2 16/36] vaapi_encode: Clean up

> >>>> rate control configuration

> >>>>

> >>>> On 14/06/18 08:22, Li, Zhong wrote:

> >>>>>> -----Original Message-----

> >>>>>> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On

> >>>> Behalf

> >>>>>> Of Xiang, Haihao

> >>>>>> Sent: Thursday, June 14, 2018 2:08 PM

> >>>>>> To: ffmpeg-devel@ffmpeg.org

> >>>>>> Subject: Re: [FFmpeg-devel] [PATCH v2 16/36] vaapi_encode: Clean

> >>>>>> up rate control configuration

> >>>>>>

> >>>>>> On Wed, 2018-06-13 at 23:42 +0100, Mark Thompson wrote:

> >>>>>>> On 13/06/18 08:03, Xiang, Haihao wrote:

> >>>>>>>> On Fri, 2018-06-08 at 00:43 +0100, Mark Thompson wrote:

> >>>>>>>>> Query which modes are supported and select between VBR and

> CBR

> >>>>>>>>> based on that - this removes all of the codec-specific rate

> >>>>>>>>> control mode selection code.

> >>>>>>>>> ---

> >>>>>>>>>  doc/encoders.texi               |   2 -

> >>>>>>>>>  libavcodec/vaapi_encode.c       | 173

> >>>>>> ++++++++++++++++++++++++++++-------

> >>>>>>>>> ----

> >>>>>>>>> -

> >>>>>>>>>  libavcodec/vaapi_encode.h       |   6 +-

> >>>>>>>>>  libavcodec/vaapi_encode_h264.c  |  18 +----

> >>>>>>>>> libavcodec/vaapi_encode_h265.c  |  14 +---

> >>>>>>>>>  libavcodec/vaapi_encode_mjpeg.c |   3 +-

> >>>>>>>>>  libavcodec/vaapi_encode_mpeg2.c |   9 +--

> >>>>>>>>>  libavcodec/vaapi_encode_vp8.c   |  13 +--

> >>>>>>>>>  libavcodec/vaapi_encode_vp9.c   |  13 +--

> >>>>>>>>>  9 files changed, 137 insertions(+), 114 deletions(-)

> >>>>>>>>>

> >>>>>>>>> ...

> >>>>>>>>> diff --git a/libavcodec/vaapi_encode.c

> >>>>>>>>> b/libavcodec/vaapi_encode.c index f4c063734c..5de5483454

> >>>>>>>>> 100644

> >>>>>>>>> --- a/libavcodec/vaapi_encode.c

> >>>>>>>>> +++ b/libavcodec/vaapi_encode.c

> >>>>>>>>> ...

> >>>>>>>>> +    if (avctx->flags & AV_CODEC_FLAG_QSCALE ||

> >>>>>>>>> +        avctx->bit_rate <= 0) {

> >>>>

> >>>> This condition ^

> >>>>

> >>>>>>>>> +        if (rc_attr.value & VA_RC_CQP) {

> >>>>>>>>> +            av_log(avctx, AV_LOG_VERBOSE, "Using

> >>>>>> constant-quality

> >>>>>>>>> mode.\n");

> >>>>>>>>> +            ctx->va_rc_mode = VA_RC_CQP;

> >>>>>>>>> +            return 0;

> >>>>>>>>> +        } else {

> >>>>>>>>> +            av_log(avctx, AV_LOG_ERROR, "Driver does not

> >>>>>> support "

> >>>>>>>>> +                   "constant-quality mode (%#x).\n",

> >>>>>> rc_attr.value);

> >>>>>>>>> +            return AVERROR(EINVAL);

> >>>>>>>>> +        }

> >>>>>>>>> +    }

> >>>>>>>>> ...

> >>>>>>>>> +    } else if (avctx->rc_max_rate == avctx->bit_rate) {

> >>>>>>>>> +        if (!(rc_attr.value & VA_RC_CBR)) {

> >>>>>>>>> +            av_log(avctx, AV_LOG_WARNING, "Driver does

> not

> >>>>>> support "

> >>>>>>>>> +                   "CBR mode (%#x), using VBR mode

> >>>>>> instead.\n",

> >>>>>>>>> +                   rc_attr.value);

> >>>>>>>>> +            ctx->va_rc_mode = VA_RC_VBR;

> >>>>>>>>> +        } else {

> >>>>>>>>> +            ctx->va_rc_mode = VA_RC_CBR;

> >>>>>>>>> +        }

> >>>>>>>>>

> >>>>>>>>> -    if (ctx->va_rc_mode == VA_RC_CBR) {

> >>>>>>>>>          rc_bits_per_second   = avctx->bit_rate;

> >>>>>>>>>          rc_target_percentage = 100;

> >>>>>>>>> -        rc_window_size       = 1000;

> >>>>>>>>> +

> >>>>>>>>>      } else {

> >>>>>>>>> -        if (avctx->rc_max_rate < avctx->bit_rate) {

> >>>>>>>>> -            // Max rate is unset or invalid, just use the normal

> >>>>>> bitrate.

> >>>>>>>>> +        if (rc_attr.value & VA_RC_VBR) {

> >>>>>>>>> +            ctx->va_rc_mode = VA_RC_VBR;

> >>>>>>>>

> >>>>>>>> Is it better to take it as CBR when avctx->rc_max_rate is 0 and

> >>>>>>>> CBR is supported by driver?

> >>>>>>>

> >>>>>>> I don't think so?  VBR with the specified target is probably

> >>>>>>> what you want in most cases, and I think anyone with specific

> >>>>>>> constraints that want constant bitrate should expect to set maxrate

> to achieve that.

> >>>>>>>

> >>>>>>

> >>>>>> I agree VBR is probably what an user wants in most case, however

> >>>>>> target percent set to 50% is not suitable for most case. To get a

> >>>>>> specific target percent, user should set both target bitrate and

> >>>>>> max bitrate, so it is reasonable to ask user must set both target

> >>>>>> bitrate and max bitrate for VBR cases, and for CBR user may set

> >>>>>> target bitrate

> >>>> only.

> >>>>>

> >>>>> How about set the max_rate to be a very larger number such as

> >>>>> INT_MAX

> >>>> if user hasn't set it?

> >>>>> User may don't set max_rate on purpose, expecting better quality

> >>>>> with

> >>>> unlimited bitrate fluctuation (common requirement for local video

> files).

> >>>>> Double of target_bit_rate is too strict IMHO. And I haven't such a

> >>>> limitation in x264 ABR mode.

> >>>>

> >>>> This unconstrained setup you describe was my intent (as you say,

> >>>> it's usually what you want for local files), but unfortunately the

> >>>> API doesn't really let us do it - the target bitrate is specified

> >>>> as an integer percentage of the max bitrate.  50% was an arbitrary

> >>>> value picked to not have a strong constraint but also not be small

> >>>> enough that we need to think about rounding/overflow problems.

> >>>>

> >>>> We could try to pick a large value with the right properties (for

> >>>> example: if target < 2^32 / 100 then choose maxrate = target * 100,

> >>>> percentage = 1; otherwise choose percentage = 2^32 * 100 / bitrate,

> >>>> maxrate = bitrate * 100 / percentage), but that would be complex to

> >>>> test and I don't think the drivers handle this sort of setup very well.

> >>>>

> >>>>>> I just saw it is also VBR in QSV when max bitrate is not set so

> >>>>>> I'm fine to keep consistency with QSV for this case.

> >>>>>

> >>>>> What will happen if user set a max_rate but without a setting for

> >>>> target_bitrate?

> >>>>> The mode will be VBR (if driver support) with target_bitrate=0.

> >>>>> Tried this on qsv, MSDK returns an error of invalid video parameters.

> >>>>> Is it ok for vaapi? And also with iHD driver?

> >>>>

> >>>> If AVCodecContext.bit_rate isn't set then we use constant-quality

> >>>> mode instead - see the block I've pointed out above.

> >>>>

> >>>> There isn't currently any constant-quality with max-rate constraint

> >>>> mode in VAAPI.

> >>>

> >>> Then the problem I see is that -max_rate hasn't been respected well if

> user set it (he may don't care about the target bitrate except the peak value).

> >>> Maybe we can add a warning at least?

> >>

> >> Given that it's really CQP, I don't think anyone would ever expect this to

> work?  Encoders generally don't warn about ignoring extra irrelevant

> options in AVCodecContext.

> >>

> >> (Is there any encoder at all which supports that combination?  E.g.

> >> libx264 supports maxrate in CRF but not CQP mode.)

> >

> > if i understand correctly, then yes, see vbv_ignore_qmax. If max rate

> > cannot be achievied the mpegvideo encoders should attempt to encode

> > the frame again without qmax and at lower quality

> 

> Ok, fair enough.

> 

> I've added a warning as below so that it's clear this case isn't supported.

> 

> diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index

> 53c3a2132a..25d89c65c9 100644

> --- a/libavcodec/vaapi_encode.c

> +++ b/libavcodec/vaapi_encode.c

> @@ -1311,6 +1311,10 @@ static av_cold int

> vaapi_encode_init_rate_control(AVCodecContext *avctx)

>          if (rc_attr.value & VA_RC_CQP) {

>              av_log(avctx, AV_LOG_VERBOSE, "Using constant-quality

> mode.\n");

>              ctx->va_rc_mode = VA_RC_CQP;

> +            if (avctx->bit_rate > 0 || avctx->rc_max_rate > 0) {

> +                av_log(avctx, AV_LOG_WARNING, "Bitrate target

> parameters "

> +                       "ignored in constant-quality mode.\n");

> +            }

>              return 0;

>          } else {

>              av_log(avctx, AV_LOG_ERROR, "Driver does not support "

> 

> Thanks,

> 

> - Mark


I have another idea: if rc_max_rate is set, then set rc_mode to be VBR (align with amfenc). Target bitrate can be set to a half (or anther value) of rc_max_rate if necessary.
CQP is not as good as CRF and should be low priority mode especially when max_rate is set.
diff mbox

Patch

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index 53c3a2132a..25d89c65c9 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -1311,6 +1311,10 @@  static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
         if (rc_attr.value & VA_RC_CQP) {
             av_log(avctx, AV_LOG_VERBOSE, "Using constant-quality mode.\n");
             ctx->va_rc_mode = VA_RC_CQP;
+            if (avctx->bit_rate > 0 || avctx->rc_max_rate > 0) {
+                av_log(avctx, AV_LOG_WARNING, "Bitrate target parameters "
+                       "ignored in constant-quality mode.\n");
+            }
             return 0;
         } else {
             av_log(avctx, AV_LOG_ERROR, "Driver does not support "