From patchwork Fri Apr 14 06:36:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Levinson X-Patchwork-Id: 3412 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.3.129 with SMTP id 123csp118606vsd; Thu, 13 Apr 2017 23:36:35 -0700 (PDT) X-Received: by 10.223.165.130 with SMTP id g2mr5673627wrc.183.1492151794980; Thu, 13 Apr 2017 23:36:34 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 136si1983521wms.126.2017.04.13.23.36.34; Thu, 13 Apr 2017 23:36:34 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D70C6689A73; Fri, 14 Apr 2017 09:36:24 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from white.spiritone.com (white.spiritone.com [216.99.193.38]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 53C67689923 for ; Fri, 14 Apr 2017 09:36:17 +0300 (EEST) Received: from [192.168.3.100] (184-100-162-109.ptld.qwest.net [184.100.162.109]) by white.spiritone.com (Postfix) with ESMTPSA id C1B01734033B for ; Thu, 13 Apr 2017 23:36:22 -0700 (PDT) To: FFmpeg development discussions and patches From: Aaron Levinson Message-ID: <332b9d84-a63a-e0b5-f911-74fcca201103@aracnet.com> Date: Thu, 13 Apr 2017 23:36:21 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] Fixed problems with QuickSync (QSV) interlaced video encoding X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From da3899b24ad89b4788a3b8191d53b26f5eec328e Mon Sep 17 00:00:00 2001 From: Aaron Levinson 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;