From patchwork Sun Mar 11 22:41:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 7918 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.1.70 with SMTP id c67csp974064jad; Sun, 11 Mar 2018 15:42:22 -0700 (PDT) X-Google-Smtp-Source: AG47ELtqOJGcYEZFK4eqaB8D2bGFRp9Lu8WKy+Gq4U31DMCTtQqLPf5jBtomC1YrA8X8MIEw/WwP X-Received: by 10.223.190.17 with SMTP id n17mr4178737wrh.189.1520808142763; Sun, 11 Mar 2018 15:42:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1520808142; cv=none; d=google.com; s=arc-20160816; b=SQu4b7hShUHK7PJOQXO4zbmrTQ+QT3qc0isaVz1c2hToOv9AEeffJsWZq0kByqoQDs vTp+uSczVlHU1rOtcNOtO43nC6k1AMAZOPcFrvEW+cCg0nePpiDT1AiiUTRMUtL/3a9E 4umbKflp4p3T8VMgCRocdMHmuuO6qyuQvRo6MwyLxw4cDz+KXs7QcAib/J515S/1ClNj ofWNbCaosb43p7ITFpZqZ932wpQIUfTWWrVC4l8F5AWg1pqu9S5SkfI67rd9UsqMsfeC L1eYSaofG5jkUn3+BDU/Bx9ruIupRw087JoQ0iJx7yZCk7eq3bq1X22E1xBUNOJN+dLW j7dg== 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=m4SnxPPnWwEnCrQYc3IYaAY9JFabdYKh7ySopyjQsZA=; b=JjAoKmqJkB+dOIkCATN0FeTURGQbMci9ww1DnNfaUGdH/BZ4cbiEitLwEc4oFVSixX qpXEvJhejYdzBg68hLYksu5r/I6wnZFioWYgI52mLoxsZil62trzmmuk3FQK4ci2uxY0 Ew1tlhh0qEFx9J7AYw94AEUspifmefvqYM8Q+gL5ytqZT81fQBOYzi1cy8phpiPuEVJN Fx9KMW6WxL6f4eo8i/rwJGTAuleCKYvUxO8r8yWCCkTBBVLXmxJRdQCfjGq8HxPqMn7r xEq0azkeOkJ/DzwKB0YyL5/nVZoq0Hpb/xua3Umkt7w4UFpAe8z7lTj4VyNscJDbRAPL 0Jgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com header.s=20150623 header.b=iRZso/O9; 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 32si4234003wru.526.2018.03.11.15.42.22; Sun, 11 Mar 2018 15:42:22 -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 header.s=20150623 header.b=iRZso/O9; 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 D7B6B689F61; Mon, 12 Mar 2018 00:42:03 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm0-f42.google.com (mail-wm0-f42.google.com [74.125.82.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4AF60689C50 for ; Mon, 12 Mar 2018 00:41:55 +0200 (EET) Received: by mail-wm0-f42.google.com with SMTP id 188so12716927wme.1 for ; Sun, 11 Mar 2018 15:42:05 -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=RduxhnhGMfoFeUHInvBj4xRumHUDnJf9Elu/KVDycxY=; b=iRZso/O9ic+dE11P61DLA+lZx8uBVIHRHQdTv7SONPuvOgG47QDkWi/q0BnETK133F Hmy5wlMlRU1xT7S6VJsRYBbYvyeRC4JkGN/7qPmZK5l/AljC98QzphEKQvPWZdx320Hz atYgjFFtSv/OMFYIqwb7UluA9eaoWvpUz0Z8VK9SQwTFXJCf7GmrYtjcU6I//9KRR1Nc DfxgDfKarfsC8GtxDQUUVwlr7Wrjh1D8krSbUQ0sXwOpvdSX82o+8ioMz1xTFy41crHD 7/o87o6+MXppVY86YCJAXrwMJkXDfP5JceLy0NpC6AeQdJ3LNXIeC3tQR2Mpg8lgIdk0 y96Q== 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=RduxhnhGMfoFeUHInvBj4xRumHUDnJf9Elu/KVDycxY=; b=Z3SGE63StgFE5i5fqPL2CdYY5SDnkT2gqJoDNMRfWQDkwkGpeboQpfo47XHMJEQ3+T u7Kl4524j0A7PBxBBeEGx3Mv7GRBqQ684/llQzOwlJAX7LVENR5i0hqiCfmUnDOfNNzi BLtKSvCNWfhS0RECo3tw5BtJPzGGJi1tkE7aNuKqG+D1f89W46JUxW8YJaQNQmqlJ6+M skTKuZrdPWzbUe2rSJ2Gv17e3S+M/0hjrLFLQMLrURWfoaLiVZSHOnWs0tSbCYH9/B6X Iocs7xmPp64BerCwvRuG2dfmApbiy484RVKxyLSmL5npnHtZnv87wJ5X9cWF7Bl+KBen BeFg== X-Gm-Message-State: AElRT7EdKSGfnYTz3SeHWniF5rThXYC14atajo0vi/5vEv0nIWLG6fL6 9kZBQlTELUs47OOig2pHc2Uhs1mc X-Received: by 10.28.51.67 with SMTP id z64mr925505wmz.59.1520808124872; Sun, 11 Mar 2018 15:42:04 -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 d5sm5317163wma.18.2018.03.11.15.42.04 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 11 Mar 2018 15:42:04 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 11 Mar 2018 22:41:51 +0000 Message-Id: <20180311224156.23986-2-sw@jkqxz.net> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180311224156.23986-1-sw@jkqxz.net> References: <20180311224156.23986-1-sw@jkqxz.net> Subject: [FFmpeg-devel] [PATCH 2/7] hwcontext_vaapi: Add support for legacy DRM mapping 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" The old vaAcquireBufferHandle() API works in fewer cases and provides less information than the current vaExportSurfaceHandle(), but it exists on older versions and is already used by the OpenCL code. This probably doesn't have much use directly, but it will be used to replace the ad-hoc OpenCL code in a following patch. --- libavutil/hwcontext_vaapi.c | 191 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 179 insertions(+), 12 deletions(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 99f76b9169..15f1c4d1c0 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -1073,8 +1073,9 @@ static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst, return 0; } -static void vaapi_unmap_to_drm(AVHWFramesContext *dst_fc, - HWMapDescriptor *hwmap) +#if VA_CHECK_VERSION(1, 1, 0) +static void vaapi_unmap_to_drm_esh(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) { AVDRMFrameDescriptor *drm_desc = hwmap->priv; int i; @@ -1085,10 +1086,9 @@ static void vaapi_unmap_to_drm(AVHWFramesContext *dst_fc, av_freep(&drm_desc); } -static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, - const AVFrame *src, int flags) +static int vaapi_map_to_drm_esh(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) { -#if VA_CHECK_VERSION(1, 1, 0) AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; VASurfaceID surface_id; VAStatus vas; @@ -1140,7 +1140,7 @@ static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, } err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src, - &vaapi_unmap_to_drm, drm_desc); + &vaapi_unmap_to_drm_esh, drm_desc); if (err < 0) goto fail; @@ -1155,15 +1155,182 @@ fail: close(va_desc.objects[i].fd); av_freep(&drm_desc); return err; -#else - // Older versions without vaExportSurfaceHandle() are not supported - - // in theory this is possible with a combination of vaDeriveImage() - // and vaAcquireBufferHandle(), but it doesn't carry enough metadata - // to actually use the result in a generic way. - return AVERROR(ENOSYS); +} #endif + +typedef struct VAAPIDRMImageBufferMapping { + VAImage image; + VABufferInfo buffer_info; + + AVDRMFrameDescriptor drm_desc; +} VAAPIDRMImageBufferMapping; + +static void vaapi_unmap_to_drm_abh(AVHWFramesContext *hwfc, + HWMapDescriptor *hwmap) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIDRMImageBufferMapping *mapping = hwmap->priv; + VASurfaceID surface_id; + VAStatus vas; + + surface_id = (VASurfaceID)(uintptr_t)hwmap->source->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Unmap VAAPI surface %#x from DRM.\n", + surface_id); + + // DRM PRIME file descriptors are closed by vaReleaseBufferHandle(), + // so we shouldn't close them separately. + + vas = vaReleaseBufferHandle(hwctx->display, mapping->image.buf); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to release buffer " + "handle of image %#x (derived from surface %#x): " + "%d (%s).\n", mapping->image.buf, surface_id, + vas, vaErrorStr(vas)); + } + + vas = vaDestroyImage(hwctx->display, mapping->image.image_id); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to destroy image " + "derived from surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + } + + av_free(mapping); } + +static int vaapi_map_to_drm_abh(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVVAAPIDeviceContext *hwctx = hwfc->device_ctx->hwctx; + VAAPIDRMImageBufferMapping *mapping = NULL; + VASurfaceID surface_id; + VAStatus vas; + int err, i, p; + + surface_id = (VASurfaceID)(uintptr_t)src->data[3]; + av_log(hwfc, AV_LOG_DEBUG, "Map VAAPI surface %#x to DRM.\n", + surface_id); + + mapping = av_mallocz(sizeof(*mapping)); + if (!mapping) + return AVERROR(ENOMEM); + + vas = vaDeriveImage(hwctx->display, surface_id, + &mapping->image); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to derive image from " + "surface %#x: %d (%s).\n", + surface_id, vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail; + } + + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { + if (vaapi_drm_format_map[i].va_fourcc == + mapping->image.format.fourcc) + break; + } + if (i >= FF_ARRAY_ELEMS(vaapi_drm_format_map)) { + av_log(hwfc, AV_LOG_ERROR, "No matching DRM format for " + "VAAPI format %#x.\n", mapping->image.format.fourcc); + err = AVERROR(EINVAL); + goto fail_derived; + } + + mapping->buffer_info.mem_type = + VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME; + + mapping->drm_desc.nb_layers = + vaapi_drm_format_map[i].nb_layer_formats; + if (mapping->drm_desc.nb_layers > 1) { + if (mapping->drm_desc.nb_layers != mapping->image.num_planes) { + av_log(hwfc, AV_LOG_ERROR, "Image properties do not match " + "expected format: got %d planes, but expected %d.\n", + mapping->image.num_planes, mapping->drm_desc.nb_layers); + err = AVERROR(EINVAL); + goto fail_derived; + } + + for(p = 0; p < mapping->drm_desc.nb_layers; p++) { + mapping->drm_desc.layers[p] = (AVDRMLayerDescriptor) { + .format = vaapi_drm_format_map[i].layer_formats[p], + .nb_planes = 1, + .planes[0] = { + .object_index = 0, + .offset = mapping->image.offsets[p], + .pitch = mapping->image.pitches[p], + }, + }; + } + } else { + mapping->drm_desc.layers[0].format = + vaapi_drm_format_map[i].layer_formats[0]; + mapping->drm_desc.layers[0].nb_planes = mapping->image.num_planes; + for (p = 0; p < mapping->image.num_planes; p++) { + mapping->drm_desc.layers[0].planes[p] = (AVDRMPlaneDescriptor) { + .object_index = 0, + .offset = mapping->image.offsets[p], + .pitch = mapping->image.pitches[p], + }; + } + } + + vas = vaAcquireBufferHandle(hwctx->display, mapping->image.buf, + &mapping->buffer_info); + if (vas != VA_STATUS_SUCCESS) { + av_log(hwfc, AV_LOG_ERROR, "Failed to get buffer " + "handle from image %#x (derived from surface %#x): " + "%d (%s).\n", mapping->image.buf, surface_id, + vas, vaErrorStr(vas)); + err = AVERROR(EIO); + goto fail_derived; + } + + av_log(hwfc, AV_LOG_DEBUG, "DRM PRIME fd is %ld.\n", + mapping->buffer_info.handle); + + mapping->drm_desc.nb_objects = 1; + mapping->drm_desc.objects[0] = (AVDRMObjectDescriptor) { + .fd = mapping->buffer_info.handle, + .size = mapping->image.data_size, + // There is no way to get the format modifier with this API. + .format_modifier = DRM_FORMAT_MOD_NONE, + }; + + err = ff_hwframe_map_create(src->hw_frames_ctx, + dst, src, &vaapi_unmap_to_drm_abh, + mapping); + if (err < 0) + goto fail_mapped; + + dst->data[0] = (uint8_t*)&mapping->drm_desc; + dst->width = src->width; + dst->height = src->height; + + return 0; + +fail_mapped: + vaReleaseBufferHandle(hwctx->display, mapping->image.buf); +fail_derived: + vaDestroyImage(hwctx->display, mapping->image.image_id); +fail: + av_freep(&mapping); + return err; +} + +static int vaapi_map_to_drm(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ +#if VA_CHECK_VERSION(1, 1, 0) + int err; + err = vaapi_map_to_drm_esh(hwfc, dst, src, flags); + if (err != AVERROR(ENOSYS)) + return err; #endif + return vaapi_map_to_drm_abh(hwfc, dst, src, flags); +} + +#endif /* CONFIG_LIBDRM */ static int vaapi_map_to(AVHWFramesContext *hwfc, AVFrame *dst, const AVFrame *src, int flags)