[FFmpeg-devel] [PATCH v3] lavc/qsvenc: add forced_idr opiton

Mark Thompson sw at jkqxz.net
Tue Nov 13 23:47:01 EET 2018


On 13/11/18 11:58, Zhong Li wrote:
> This option can be used to repect original input I/IDR frame type.
> 
> Signed-off-by: Zhong Li <zhong.li at intel.com>
> ---
>  libavcodec/qsvenc.c | 7 +++++++
>  libavcodec/qsvenc.h | 2 ++
>  2 files changed, 9 insertions(+)
> 
> diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
> index 948751d..63d0939 100644
> --- a/libavcodec/qsvenc.c
> +++ b/libavcodec/qsvenc.c
> @@ -1192,6 +1192,13 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
>      if (qsv_frame) {
>          surf = &qsv_frame->surface;
>          enc_ctrl = &qsv_frame->enc_ctrl;
> +        memset(enc_ctrl, 0, sizeof(mfxEncodeCtrl));
> +
> +        if (frame->pict_type == AV_PICTURE_TYPE_I) {
> +            enc_ctrl->FrameType = MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF;
> +            if (q->forced_idr || frame->key_frame)
> +                enc_ctrl->FrameType |= MFX_FRAMETYPE_IDR;
> +        }
>      }
>  
>      ret = av_new_packet(&new_pkt, q->packet_size);
> diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
> index 055b4a6..fbdc199 100644
> --- a/libavcodec/qsvenc.h
> +++ b/libavcodec/qsvenc.h
> @@ -87,6 +87,7 @@
>  { "adaptive_i",     "Adaptive I-frame placement",             OFFSET(qsv.adaptive_i),     AV_OPT_TYPE_INT, { .i64 = -1 }, -1,          1, VE },                         \
>  { "adaptive_b",     "Adaptive B-frame placement",             OFFSET(qsv.adaptive_b),     AV_OPT_TYPE_INT, { .i64 = -1 }, -1,          1, VE },                         \
>  { "b_strategy",     "Strategy to choose between I/P/B-frames", OFFSET(qsv.b_strategy),    AV_OPT_TYPE_INT, { .i64 = -1 }, -1,          1, VE },                         \
> +{ "forced_idr",     "Forcing I frames as IDR frames",         OFFSET(qsv.forced_idr),     AV_OPT_TYPE_BOOL,{ .i64 = 0  },  0,          1, VE },                         \
>  
>  typedef int SetEncodeCtrlCB (AVCodecContext *avctx,
>                               const AVFrame *frame, mfxEncodeCtrl* enc_ctrl);
> @@ -168,6 +169,7 @@ typedef struct QSVEncContext {
>  #endif
>      char *load_plugins;
>      SetEncodeCtrlCB *set_encode_ctrl_cb;
> +    int forced_idr;
>  } QSVEncContext;
>  
>  int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
> 

Testing this, I think the reason not to look at key_frame in an encoder is that it isn't usually written by the user.  Rather, it gets copied (including through copy_props) from whatever the original source of the frame was.

You can see that it results in surprising behaviour in ffmpeg (which doesn't touch that field) with your patch as-is:

$ ffprobe h264.mp4
...
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 11244 kb/s, 60 fps, 60 tbr, 15360 tbn, 120 tbc (default)
...
$ ffprobe jpeg.mp4
...
    Stream #0:0(und): Video: mjpeg (Baseline) (mp4v / 0x7634706D), yuvj420p(pc, bt470bg/unknown/unknown, progressive), 1920x1080, 92213 kb/s, SAR 1:1 DAR 16:9, 60 fps, 60 tbr, 15360 tbn, 15360 tbc (default)
...
$ LIBVA_DRIVER_NAME=iHD ./ffmpeg_g -y -i h264.mp4 -an -c:v h264_qsv -force_key_frames expr:1 -b:v 1M -frames:v 10 -bsf:v trace_headers -f null - 2>&1 | grep 'nal_unit_type.*\(1\|5\)$' 
[AVBSFContext @ 0x55dd71352700] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x55dd71352700] 3           nal_unit_type                                           00001 = 1
[AVBSFContext @ 0x55dd71352700] 3           nal_unit_type                                           00001 = 1
[AVBSFContext @ 0x55dd71352700] 3           nal_unit_type                                           00001 = 1
[AVBSFContext @ 0x55dd71352700] 3           nal_unit_type                                           00001 = 1
[AVBSFContext @ 0x55dd71352700] 3           nal_unit_type                                           00001 = 1
[AVBSFContext @ 0x55dd71352700] 3           nal_unit_type                                           00001 = 1
[AVBSFContext @ 0x55dd71352700] 3           nal_unit_type                                           00001 = 1
[AVBSFContext @ 0x55dd71352700] 3           nal_unit_type                                           00001 = 1
[AVBSFContext @ 0x55dd71352700] 3           nal_unit_type                                           00001 = 1
$ LIBVA_DRIVER_NAME=iHD ./ffmpeg_g -y -i jpeg.mp4 -an -c:v h264_qsv -force_key_frames expr:1 -b:v 1M -frames:v 10 -bsf:v trace_headers -f null - 2>&1 | grep 'nal_unit_type.*\(1\|5\)$' 
[AVBSFContext @ 0x55989b59b540] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x55989b59b540] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x55989b59b540] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x55989b59b540] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x55989b59b540] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x55989b59b540] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x55989b59b540] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x55989b59b540] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x55989b59b540] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x55989b59b540] 3           nal_unit_type                                           00101 = 5
$ LIBVA_DRIVER_NAME=iHD ./ffmpeg_g -y -i h264.mp4 -an -c:v h264_qsv -force_key_frames expr:1 -b:v 1M -forced_idr 1 -frames:v 10 -bsf:v trace_headers -f null - 2>&1 | grep 'nal_unit_type.*\(1\|5\)$' 
[AVBSFContext @ 0x560d28291180] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x560d28291180] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x560d28291180] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x560d28291180] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x560d28291180] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x560d28291180] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x560d28291180] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x560d28291180] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x560d28291180] 3           nal_unit_type                                           00101 = 5
[AVBSFContext @ 0x560d28291180] 3           nal_unit_type                                           00101 = 5

So, LGTM with the reference to key_frame dropped and the title typo fixed.

Thanks,

- Mark


More information about the ffmpeg-devel mailing list