[FFmpeg-devel] [PATCH 3/5] lavc/libkvazaar: export encoded frame stats

Mark Thompson sw at jkqxz.net
Fri Aug 21 02:02:48 EEST 2020


On 15/08/2020 09:48, mypopy at gmail.com wrote:
> On Sun, Aug 9, 2020 at 6:07 AM Mark Thompson <sw at jkqxz.net> wrote:
>>
>> On 26/07/2020 13:26, Jun Zhao wrote:
>>> From: Jun Zhao <barryjzhao at tencent.com>
>>>
>>> Export choosen pict_type and qp.
>>>
>>> Signed-off-by: Jun Zhao <barryjzhao at tencent.com>
>>> ---
>>>    libavcodec/libkvazaar.c | 30 ++++++++++++++++++++++++++++++
>>>    1 file changed, 30 insertions(+)
>>>
>>> diff --git a/libavcodec/libkvazaar.c b/libavcodec/libkvazaar.c
>>> index 71c9c8f..9032547 100644
>>> --- a/libavcodec/libkvazaar.c
>>> +++ b/libavcodec/libkvazaar.c
>>> @@ -37,6 +37,7 @@
>>>
>>>    #include "avcodec.h"
>>>    #include "internal.h"
>>> +#include "packet_internal.h"
>>>
>>>    typedef struct LibkvazaarContext {
>>>        const AVClass *class;
>>> @@ -170,6 +171,7 @@ static int libkvazaar_encode(AVCodecContext *avctx,
>>>        kvz_data_chunk *data_out = NULL;
>>>        uint32_t len_out = 0;
>>>        int retval = 0;
>>> +    int pict_type;
>>>
>>>        *got_packet_ptr = 0;
>>>
>>> @@ -257,6 +259,34 @@ static int libkvazaar_encode(AVCodecContext *avctx,
>>>                avpkt->flags |= AV_PKT_FLAG_KEY;
>>>            }
>>>
>>> +        switch (frame_info.slice_type) {
>>> +        case KVZ_SLICE_I:
>>> +            pict_type = AV_PICTURE_TYPE_I;
>>> +            break;
>>> +        case KVZ_SLICE_P:
>>> +            pict_type = AV_PICTURE_TYPE_P;
>>> +            break;
>>> +        case KVZ_SLICE_B:
>>> +            pict_type = AV_PICTURE_TYPE_B;
>>> +            break;
>>> +        default:
>>> +            av_log(avctx, AV_LOG_ERROR, "Unknown picture type encountered.\n");
>>> +            return AVERROR_EXTERNAL;
>>> +        }
>>> +#if FF_API_CODED_FRAME
>>> +FF_DISABLE_DEPRECATION_WARNINGS
>>> +        avctx->coded_frame->pict_type = pict_type;
>>> +FF_ENABLE_DEPRECATION_WARNINGS
>>> +#endif
>>
>> Is there some value to setting the deprecated fields?  They will disappear on the next version bump, which probably isn't very far away.
>>
> I think we can keep this part, if we want to remove the
> avctx->coded_frame->pict_type from next version bump, we can drop this
> part from all codec one-time
>>> +
>>> +        ff_side_data_set_encoder_stats(avpkt, frame_info.qp * FF_QP2LAMBDA, NULL, 0, pict_type);
>>
>> I'm not familiar with kvazaar - is the QP value here actually reflective of the global quality in a useful way?  The documentation is not very good...
>>
> Yes, it's a global quality based on Frame in kvazaar
> 
>> (Your following patch for OpenH264 uses a field "AverageFrameQP", which has an much more usefully-suggestive name.)
>>
>> Zero is a valid QP value, but you shouldn't be passing it here.  Possibly it needs some more scaling to get the range to [1, FF_LAMDBA_MAX].
>>
> I know vpx encoder wrapper used the zero QP value in side data, maybe
> we can keep the same action

So the libvpx wrapper is also broken?  This all seems very inconsistent - the documentation requires that the number be in [1, FF_LAMBDA_MAX], but codecs are using random numbers which include zero.

libx264 is applying some sort of offset so that the returned qpplus1 field is actually qpplussomewherebetween1and30 (with 10-bit input qp == -12 gives qpplus1 == 1 and qp == 51 gives qpplus1 == 81), but we still subtract 1 so the result includes zero.

libx265 doesn't seem to support negative QPs so it's always in the 8-bit range, but that still includes zero.

nvenc has frameAvgQP - 1, which seems bizarre.  I guess it would work if it doesn't support QP < 2, but given that it allows 12-bit inputs (range -24 to 51) that seems unlikely.

Scaling to match what the documentation actually says seems like the sanest way to fix this - we can't change the range because zero is the "unused" value.

- Mark


More information about the ffmpeg-devel mailing list