[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