From patchwork Mon Jun 12 22:40:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 3945 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.22.4 with SMTP id 4csp78308vsw; Mon, 12 Jun 2017 15:43:56 -0700 (PDT) X-Received: by 10.223.163.27 with SMTP id c27mr658254wrb.85.1497307436928; Mon, 12 Jun 2017 15:43:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497307436; cv=none; d=google.com; s=arc-20160816; b=ZNnzcuX3uGakPkComfhkMh4OxjbiBogC6vwrzqJ8RhkTxbAiZcFGYbery9ydd9YGL7 yUJc4oomZR7jYFUKnt4Jl27sc51GDk0KwXkBDku+ymxSl47Bqt9OkqGF0WnHh+u3JinW vxLRx5ZwLMaOYIkUx7w+0Wt3mnAKfDIBwMu9XncsDaHQV1OUk2UaqutBF3gqX63AtXIj wR9x5OS7hf3FvBOu7f/JJxxGB1pdxU6SqqctDCG3PKChK7YnYSLatCoyKKfo7Ag3G6TV 0m8cf4+3s5egjDFo1Z20M979e+RV8cuokKz58c3aaT+IRr3jKaooD8t0TULEMszg0+ja rcZw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=8TXYlwW1RI2jgEy9265JFRohB5J+3AvhrIM1xhA0/jk=; b=DkrP1Y7s31omcZOAEAgby7Nu5PtUfPeloH3ZWlGj7H/CDli+P1f9RRd9TXn9dQlsBA OCnuC0KynR1xDL4oIvEI9iB8jgVeINQS7neQfvgwhbbJKJfaR47B0Lf+SFL9QypL0rND RBH55DdthHJ1S6SGkONGxL87VekcPc88Uul9a/u7iQlBHx0JeVDLosfaNsO4zXkiXGu9 uBMypUQQSpxFo+pCM0btH0X7uHAvmjcRrDfIHzNNP7KvimnWE/feuqZRcwWdAZjiBvsb Wn+R+aFuIWl2pmrrhEQqVzxSJ/tkxJV9dDPpXR3LwIdpWWpuOxtI3Xmz00XjyVIJauwx C/dw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id d4si10813370wra.285.2017.06.12.15.43.56; Mon, 12 Jun 2017 15:43:56 -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; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.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 5AB1568A0BA; Tue, 13 Jun 2017 01:41:17 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f180.google.com (mail-wr0-f180.google.com [209.85.128.180]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D7A6968A03E for ; Tue, 13 Jun 2017 01:41:13 +0300 (EEST) Received: by mail-wr0-f180.google.com with SMTP id g76so113430960wrd.1 for ; Mon, 12 Jun 2017 15:41:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=j/0958BBiGeQiPrIm8w83N1hxebQbi0X2p03KRw21/E=; b=moY2c/DXnonS4jOqHmkqVwj8MvN7pHEcxpGu3w1RUF78Cdzk0vbjDkjnx6anshINFr c6z1PwPDO0JGyProPBASdD7Y5zvSMkyyz6KKOBvJI9iwVDCnNp81FZMLAhxpn+Dulqaf nV0EBnybuafrFqV/mh7H6eQ9R1Kb0x3+6QUgB7L+mE+AI7Mef6m7W28GcSb6qmYGrglL IB5GNMYb5Sp0IPsI4Ln+4wEelIlWpTyVm1YPXJgs5NGs07VkpYh7JJHSO2VXfrC0Knzo e5vWQ/VsIMr9TAYKcBL0sDNTLK836EXvZKA4P8KmXlMBmqlzMCmMzfAp/sY9eMEO6JMf kWRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=j/0958BBiGeQiPrIm8w83N1hxebQbi0X2p03KRw21/E=; b=Jcq9Fh7kOZvoDO1LCcUzro2Hm4Ce6zrkLQE02Lfkj4XOTtVNTdZ7q5POdaEiGoLysw 9mkEG4AdusSFlubgdPeLDWywMs/kHca9tdNJEyqxiY5r0XfrMZT5Aj8/vggaUs8X/qbn JjYhRGpIZqggapYWTGLeYzj9cqxfrFWtEHRsGWQIKswbr2PhSYzLrVeKWKw8eKAKQaq4 w7AynG8nnfENBvL9+FSTPnogmMdTT8Q/ZHoRrQ/KUvnD83eOHi8ZLvbsvjltaK9u72iy ZCrCHF19PbvcIF7JMKL5Dfa8bHbSJGOEKLxsvbO7spWRqgZOXjZEs5YlgPvOsqj4714H wE9A== X-Gm-Message-State: AKS2vOzDRa99N3GAi1BmijqKaSYH8H2SbeCpbrkW2vysB8vuGHDWawJi 7iU3SIVMAwmXIc95qBs= X-Received: by 10.223.131.66 with SMTP id 60mr696920wrd.169.1497307275292; Mon, 12 Jun 2017 15:41:15 -0700 (PDT) Received: from rywe.jkqxz.net (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id m191sm13098233wmg.30.2017.06.12.15.41.14 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Jun 2017 15:41:14 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Mon, 12 Jun 2017 23:40:36 +0100 Message-Id: <20170612224041.6750-20-sw@jkqxz.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170612224041.6750-1-sw@jkqxz.net> References: <20170612224041.6750-1-sw@jkqxz.net> Subject: [FFmpeg-devel] [PATCH 19/24] hwcontext_qsv: Implement mapping frames from the child device type 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Factorises out existing surface initialisation code to reuse. (cherry picked from commit eaa5e0710496db50fc164806e5f49eaaccc83bb5) --- libavutil/hwcontext_qsv.c | 174 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 142 insertions(+), 32 deletions(-) diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c index 505a8e709d..8dbff88b0a 100644 --- a/libavutil/hwcontext_qsv.c +++ b/libavutil/hwcontext_qsv.c @@ -94,6 +94,16 @@ static const struct { { AV_PIX_FMT_PAL8, MFX_FOURCC_P8 }, }; +static uint32_t qsv_fourcc_from_pix_fmt(enum AVPixelFormat pix_fmt) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) { + if (supported_pixel_formats[i].pix_fmt == pix_fmt) + return supported_pixel_formats[i].fourcc; + } + return 0; +} + static int qsv_device_init(AVHWDeviceContext *ctx) { AVQSVDeviceContext *hwctx = ctx->hwctx; @@ -272,18 +282,48 @@ fail: return ret; } +static int qsv_init_surface(AVHWFramesContext *ctx, mfxFrameSurface1 *surf) +{ + const AVPixFmtDescriptor *desc; + uint32_t fourcc; + + desc = av_pix_fmt_desc_get(ctx->sw_format); + if (!desc) + return AVERROR(EINVAL); + + fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format); + if (!fourcc) + return AVERROR(EINVAL); + + surf->Info.BitDepthLuma = desc->comp[0].depth; + surf->Info.BitDepthChroma = desc->comp[0].depth; + surf->Info.Shift = desc->comp[0].depth > 8; + + if (desc->log2_chroma_w && desc->log2_chroma_h) + surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420; + else if (desc->log2_chroma_w) + surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV422; + else + surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV444; + + surf->Info.FourCC = fourcc; + surf->Info.Width = ctx->width; + surf->Info.CropW = ctx->width; + surf->Info.Height = ctx->height; + surf->Info.CropH = ctx->height; + surf->Info.FrameRateExtN = 25; + surf->Info.FrameRateExtD = 1; + + return 0; +} + static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc) { QSVFramesContext *s = ctx->internal->priv; AVQSVFramesContext *frames_hwctx = ctx->hwctx; - const AVPixFmtDescriptor *desc; int i, ret = 0; - desc = av_pix_fmt_desc_get(ctx->sw_format); - if (!desc) - return AVERROR_BUG; - if (ctx->initial_pool_size <= 0) { av_log(ctx, AV_LOG_ERROR, "QSV requires a fixed frame pool size\n"); return AVERROR(EINVAL); @@ -295,26 +335,9 @@ static int qsv_init_pool(AVHWFramesContext *ctx, uint32_t fourcc) return AVERROR(ENOMEM); for (i = 0; i < ctx->initial_pool_size; i++) { - mfxFrameSurface1 *surf = &s->surfaces_internal[i]; - - surf->Info.BitDepthLuma = desc->comp[0].depth; - surf->Info.BitDepthChroma = desc->comp[0].depth; - surf->Info.Shift = desc->comp[0].depth > 8; - - if (desc->log2_chroma_w && desc->log2_chroma_h) - surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV420; - else if (desc->log2_chroma_w) - surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV422; - else - surf->Info.ChromaFormat = MFX_CHROMAFORMAT_YUV444; - - surf->Info.FourCC = fourcc; - surf->Info.Width = ctx->width; - surf->Info.CropW = ctx->width; - surf->Info.Height = ctx->height; - surf->Info.CropH = ctx->height; - surf->Info.FrameRateExtN = 25; - surf->Info.FrameRateExtD = 1; + ret = qsv_init_surface(ctx, &s->surfaces_internal[i]); + if (ret < 0) + return ret; } if (!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME)) { @@ -466,15 +489,10 @@ static int qsv_frames_init(AVHWFramesContext *ctx) int opaque = !!(frames_hwctx->frame_type & MFX_MEMTYPE_OPAQUE_FRAME); - uint32_t fourcc = 0; + uint32_t fourcc; int i, ret; - for (i = 0; i < FF_ARRAY_ELEMS(supported_pixel_formats); i++) { - if (supported_pixel_formats[i].pix_fmt == ctx->sw_format) { - fourcc = supported_pixel_formats[i].fourcc; - break; - } - } + fourcc = qsv_fourcc_from_pix_fmt(ctx->sw_format); if (!fourcc) { av_log(ctx, AV_LOG_ERROR, "Unsupported pixel format\n"); return AVERROR(ENOSYS); @@ -723,6 +741,96 @@ static int qsv_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, return 0; } +static int qsv_frames_derive_to(AVHWFramesContext *dst_ctx, + AVHWFramesContext *src_ctx, int flags) +{ + QSVFramesContext *s = dst_ctx->internal->priv; + AVQSVFramesContext *dst_hwctx = dst_ctx->hwctx; + int i; + + switch (src_ctx->device_ctx->type) { +#if CONFIG_VAAPI + case AV_HWDEVICE_TYPE_VAAPI: + { + AVVAAPIFramesContext *src_hwctx = src_ctx->hwctx; + s->surfaces_internal = av_mallocz_array(src_hwctx->nb_surfaces, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + qsv_init_surface(dst_ctx, &s->surfaces_internal[i]); + s->surfaces_internal[i].Data.MemId = src_hwctx->surface_ids + i; + } + dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; + dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } + break; +#endif +#if CONFIG_DXVA2 + case AV_HWDEVICE_TYPE_DXVA2: + { + AVDXVA2FramesContext *src_hwctx = src_ctx->hwctx; + s->surfaces_internal = av_mallocz_array(src_hwctx->nb_surfaces, + sizeof(*s->surfaces_internal)); + if (!s->surfaces_internal) + return AVERROR(ENOMEM); + for (i = 0; i < src_hwctx->nb_surfaces; i++) { + qsv_init_surface(dst_ctx, &s->surfaces_internal[i]); + s->surfaces_internal[i].Data.MemId = (mfxMemId)src_hwctx->surfaces[i]; + } + dst_hwctx->nb_surfaces = src_hwctx->nb_surfaces; + if (src_hwctx->surface_type == DXVA2_VideoProcessorRenderTarget) + dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; + else + dst_hwctx->frame_type = MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET; + } + break; +#endif + default: + return AVERROR(ENOSYS); + } + + dst_hwctx->surfaces = s->surfaces_internal; + + return 0; +} + +static int qsv_map_to(AVHWFramesContext *dst_ctx, + AVFrame *dst, const AVFrame *src, int flags) +{ + AVQSVFramesContext *hwctx = dst_ctx->hwctx; + int i, err; + + for (i = 0; i < hwctx->nb_surfaces; i++) { +#if CONFIG_VAAPI + if (*(VASurfaceID*)hwctx->surfaces[i].Data.MemId == + (VASurfaceID)(uintptr_t)src->data[3]) + break; +#endif +#if CONFIG_DXVA2 + if ((IDirect3DSurface9*)hwctx->surfaces[i].Data.MemId == + (IDirect3DSurface9*)(uintptr_t)src->data[3]) + break; +#endif + } + if (i >= hwctx->nb_surfaces) { + av_log(dst_ctx, AV_LOG_ERROR, "Trying to map from a surface which " + "is not in the mapped frames context.\n"); + return AVERROR(EINVAL); + } + + err = ff_hwframe_map_create(dst->hw_frames_ctx, + dst, src, NULL, NULL); + if (err) + return err; + + dst->width = src->width; + dst->height = src->height; + dst->data[3] = (uint8_t*)&hwctx->surfaces[i]; + + return 0; +} + static int qsv_frames_get_constraints(AVHWDeviceContext *ctx, const void *hwconfig, AVHWFramesConstraints *constraints) @@ -931,7 +1039,9 @@ const HWContextType ff_hwcontext_type_qsv = { .transfer_get_formats = qsv_transfer_get_formats, .transfer_data_to = qsv_transfer_data_to, .transfer_data_from = qsv_transfer_data_from, + .map_to = qsv_map_to, .map_from = qsv_map_from, + .frames_derive_to = qsv_frames_derive_to, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_QSV, AV_PIX_FMT_NONE }, };