From patchwork Tue Jun 18 14:51:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fu, Linjie" X-Patchwork-Id: 13594 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id BB873448E8C for ; Tue, 18 Jun 2019 09:52:08 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7189868A905; Tue, 18 Jun 2019 09:52:08 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8D16A68A148 for ; Tue, 18 Jun 2019 09:52:01 +0300 (EEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jun 2019 23:51:59 -0700 X-ExtLoop1: 1 Received: from media_lj_kbl.sh.intel.com ([10.239.13.115]) by fmsmga008.fm.intel.com with ESMTP; 17 Jun 2019 23:51:58 -0700 From: Linjie Fu To: ffmpeg-devel@ffmpeg.org Date: Tue, 18 Jun 2019 22:51:44 +0800 Message-Id: <20190618145144.11949-1-linjie.fu@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH, v4 1/2] lavf/qsvvpp:allocate continuous memory 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 Cc: Linjie Fu MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Mediasdk calls CMRT to copy from video to system memory and requires memory to be continuously allocated across Y and UV. Add a new path to allocate continuous memory when using system out. Use get_continuous_buffer to arrange data according to pixfmt. Signed-off-by: Linjie Fu --- libavfilter/qsvvpp.c | 67 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/libavfilter/qsvvpp.c b/libavfilter/qsvvpp.c index 8d5ff2eb65..07fe53573d 100644 --- a/libavfilter/qsvvpp.c +++ b/libavfilter/qsvvpp.c @@ -27,6 +27,7 @@ #include "libavutil/hwcontext_qsv.h" #include "libavutil/time.h" #include "libavutil/pixdesc.h" +#include "libavutil/imgutils.h" #include "internal.h" #include "qsvvpp.h" @@ -346,6 +347,57 @@ static QSVFrame *submit_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *p return qsv_frame; } +static int get_continuous_buffer(AVFrame *frame, int align) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); + int ret, i, padded_height; + + if (!desc) + return AVERROR(EINVAL); + + if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0) + return ret; + + if (!frame->linesize[0]) { + if (align <= 0) + align = 32; /* STRIDE_ALIGN. Should be av_cpu_max_align() */ + + for (i=1; i<=align; i+=i) { + ret = av_image_fill_linesizes(frame->linesize, frame->format, + FFALIGN(frame->width, i)); + if (ret < 0) + return ret; + if (!(frame->linesize[0] & (align-1))) + break; + } + + for (i = 0; i < 4 && frame->linesize[i]; i++) + frame->linesize[i] = FFALIGN(frame->linesize[i], align); + } + + padded_height = FFALIGN(frame->height, 64); + if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, + NULL, frame->linesize)) < 0) + return ret; + + frame->buf[0] = av_buffer_alloc(ret); + if (!frame->buf[0]) { + ret = AVERROR(ENOMEM); + goto fail; + } + + if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, + frame->buf[0]->data, frame->linesize)) < 0) + goto fail; + + frame->extended_data = frame->data; + + return 0; +fail: + av_frame_unref(frame); + return ret; +} + /* get the output surface */ static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink *outlink) { @@ -375,15 +427,20 @@ static QSVFrame *query_frame(QSVVPPContext *s, AVFilterLink *outlink) out_frame->surface = (mfxFrameSurface1 *)out_frame->frame->data[3]; } else { /* Get a frame with aligned dimensions. - * Libmfx need system memory being 128x64 aligned */ - out_frame->frame = ff_get_video_buffer(outlink, - FFALIGN(outlink->w, 128), - FFALIGN(outlink->h, 64)); - if (!out_frame->frame) + * Libmfx need system memory being 128x64 aligned + * and continuously allocated across Y and UV */ + out_frame->frame = av_frame_alloc(); + if (!out_frame->frame) { return NULL; + } out_frame->frame->width = outlink->w; out_frame->frame->height = outlink->h; + out_frame->frame->format = outlink->format; + + ret = get_continuous_buffer(out_frame->frame, 128); + if (ret < 0) + return NULL; ret = map_frame_to_surface(out_frame->frame, &out_frame->surface_internal);