[FFmpeg-devel] [PATCH] Fixed problems with QuickSync (QSV) interlaced video encoding

Aaron Levinson alevinsn at aracnet.com
Sun May 7 20:37:59 EEST 2017


Please disregard this patch--I'm submitting two new patches that have 
already been reviewed and applied to libav.

Aaron Levinson

On 4/13/2017 11:36 PM, Aaron Levinson wrote:
> From da3899b24ad89b4788a3b8191d53b26f5eec328e Mon Sep 17 00:00:00 2001
> From: Aaron Levinson <alevinsn at aracnet.com>
> Date: Thu, 13 Apr 2017 23:12:30 -0700
> Subject: [PATCH] Fixed problems with QuickSync (QSV) interlaced video
>  encoding
>
> Purpose: Fixed problems with QuickSync (QSV) interlaced video encoding
> that were introduced in revision 1f26a23 on Oct. 31, 2016 (qsv: Merge
> libav implementation, at
> https://github.com/FFmpeg/FFmpeg/commit/1f26a231bb065276cd80ce02957c759f3197edfa#diff-7d84a34d58597bb7aa4b8239dca1f9f8).
> As a result of the qsv libav merge, when attempting to encode
> interlaced video, it doesn't work and instead results in a bunch of
> incompatible video parameter errors.
>
> Comments:
>
> -- qsvenc.c / .h:
> a) Added code back in to set PicStruct appropriately based on whether
>    or not interlaced or progressive video is being encoded.  Also
>    reintroduced the related code to set the height alignment.  The
>    height alignment code was also enhanced slightly (compared to the
>    version in 3.2.4) to properly handle progressive video when the
>    HEVC encoder is used.  The elimination of this code is the main
>    reason why interlaced video encoding stopped working.
> b) Reintroduced code to call MFXVideoENCODE_Query() after calling
>    init_video_param().  This isn't strictly required to fix the
>    interlaced video encoding issue, but it represents a generally good
>    practice to make sure that one is working with the right parameter
>    values.
> ---
>  libavcodec/qsvenc.c | 33 +++++++++++++++++++++++++++++----
>  libavcodec/qsvenc.h |  1 +
>  2 files changed, 30 insertions(+), 4 deletions(-)
>
> diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
> index 9c385a7..24ac390 100644
> --- a/libavcodec/qsvenc.c
> +++ b/libavcodec/qsvenc.c
> @@ -358,6 +358,9 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
>          return AVERROR_BUG;
>      q->param.mfx.CodecId = ret;
>
> +    // TODO:  detect version of MFX--if the minor version is greater than
> +    // or equal to 19, then can use the same alignment settings as H.264
> +    // for HEVC
>      q->width_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
>
>      if (avctx->level > 0)
> @@ -381,20 +384,34 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
>
>      ff_qsv_map_pixfmt(sw_format, &q->param.mfx.FrameInfo.FourCC);
>
> -    q->param.mfx.FrameInfo.Width          = FFALIGN(avctx->width, q->width_align);
> -    q->param.mfx.FrameInfo.Height         = FFALIGN(avctx->height, 32);
>      q->param.mfx.FrameInfo.CropX          = 0;
>      q->param.mfx.FrameInfo.CropY          = 0;
>      q->param.mfx.FrameInfo.CropW          = avctx->width;
>      q->param.mfx.FrameInfo.CropH          = avctx->height;
>      q->param.mfx.FrameInfo.AspectRatioW   = avctx->sample_aspect_ratio.num;
>      q->param.mfx.FrameInfo.AspectRatioH   = avctx->sample_aspect_ratio.den;
> -    q->param.mfx.FrameInfo.PicStruct      = MFX_PICSTRUCT_PROGRESSIVE;
>      q->param.mfx.FrameInfo.ChromaFormat   = MFX_CHROMAFORMAT_YUV420;
>      q->param.mfx.FrameInfo.BitDepthLuma   = desc->comp[0].depth;
>      q->param.mfx.FrameInfo.BitDepthChroma = desc->comp[0].depth;
>      q->param.mfx.FrameInfo.Shift          = desc->comp[0].depth > 8;
>
> +    q->param.mfx.FrameInfo.Width          = FFALIGN(avctx->width, q->width_align);
> +    if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
> +        // it is important that PicStruct be setup correctly from the
> +        // start--otherwise, encoding doesn't work and results in a bunch
> +        // of incompatible video parameter errors
> +        q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF;
> +        // height alignment always must be 32 for interlaced video
> +        q->height_align = 32;
> +    } else {
> +        q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
> +        // for progressive video, the height should be aligned to 16 for
> +        // H.264.  For HEVC, depending on the version of MFX, it should be
> +        // either 32 or 16.  The lower number is better if possible.
> +        q->height_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16;
> +    }
> +    q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, q->height_align);
> +
>      if (avctx->hw_frames_ctx) {
>          AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
>          AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
> @@ -740,10 +757,18 @@ int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q)
>      if (ret < 0)
>          return ret;
>
> +    ret = MFXVideoENCODE_Query(q->session, &q->param, &q->param);
> +    if (ret == MFX_WRN_PARTIAL_ACCELERATION) {
> +        av_log(avctx, AV_LOG_WARNING, "Encoder will work with partial HW acceleration\n");
> +    } else if (ret < 0) {
> +        return ff_qsv_print_error(avctx, ret,
> +                                  "Error querying encoder params");
> +    }
> +
>      ret = MFXVideoENCODE_QueryIOSurf(q->session, &q->param, &q->req);
>      if (ret < 0)
>          return ff_qsv_print_error(avctx, ret,
> -                                  "Error querying the encoding parameters");
> +                                  "Error querying (IOSurf) the encoding parameters");
>
>      if (opaque_alloc) {
>          ret = qsv_init_opaque_alloc(avctx, q);
> diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
> index 361d933..12e3444 100644
> --- a/libavcodec/qsvenc.h
> +++ b/libavcodec/qsvenc.h
> @@ -84,6 +84,7 @@ typedef struct QSVEncContext {
>
>      int packet_size;
>      int width_align;
> +    int height_align;
>
>      mfxVideoParam param;
>      mfxFrameAllocRequest req;
>


More information about the ffmpeg-devel mailing list