From patchwork Thu Sep 7 21:56:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 5046 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.15.201 with SMTP id 70csp696982jao; Thu, 7 Sep 2017 14:56:47 -0700 (PDT) X-Received: by 10.28.130.130 with SMTP id e124mr167199wmd.75.1504821407409; Thu, 07 Sep 2017 14:56:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504821407; cv=none; d=google.com; s=arc-20160816; b=HRp5gjuOJcHVx9KB4zpZQG6XmkGv4nwrrYrbHPjbv1BAFZqQ0L/utVDBgM4Ill0R0G R1iET36bPVslJDAgeDWG3dYHohFBr4lEPCMCjKKGWPthN+uvuEzSmajdzlzGRArKmvp3 bySBJH1Bh53KZfBnD74kykjQJdcVAo30HJiQcLn1LmUPTYDjicd8zPP2G8h/6dz4bwtg sOY/wfAY5rVC9eZP0Fba7R9ENRRPfhTWKw+mxvFbOTSgkcbMAMua9UqQUfXQZ/dj719W N3Ya1Tm3skVJH9Qczj2mH/h/3bizOBdiYP41nZ0+iK7li6YRkvlVjE2NT+DBuB/x+Ccf 16oQ== 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=vfyFrpqSNoCoQEelA+3obrYtN/jVStr5sGOp8iUUTOY=; b=to4Su+7BwF0iYo106kvwlGL4NeWrCxawfrm5h3puQAfGpHjYqj/sOH1rA7RPTMaq0M 1E92REErgfdXtVeJ30vRMbXQgnCapjeZIo5PMhQuWywk+MuWSoap48jMrFSjX/jj+B/C PIBmbA8XbJkBYy3vFhAB2mzursbsaPlSQHvusFLyrHfj8vTwkCq8nbyM7tXQpuvwP/yr gTLTL3QrhdnPJzmbfW/5sXQtt6I3gZKAPFsXEMWZbiyqQjq8DrBC1+rwu//fL9Kq9i9L 8Y+Qll331Y7EMas/jAVlvkKPEZ67T8bIZkl4kMlO5iyaCcuvciDYLNIOjyE15OwY39sm SYUw== 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=QPbf5uTu; 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 94si227629wri.287.2017.09.07.14.56.47; Thu, 07 Sep 2017 14:56:47 -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=QPbf5uTu; 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 72F54689DAC; Fri, 8 Sep 2017 00:56:28 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f171.google.com (mail-wr0-f171.google.com [209.85.128.171]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 72424689D6B for ; Fri, 8 Sep 2017 00:56:22 +0300 (EEST) Received: by mail-wr0-f171.google.com with SMTP id v109so1664922wrc.1 for ; Thu, 07 Sep 2017 14:56:26 -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=/mAF4FpmVyE9qnDdQYan0izn50M7ikt8vaaiIHkY8bs=; b=QPbf5uTu95DZvku9cRBj5VPEtnECvGwaFr4CpcLOHAk7edMADI1D6fI6tbcPOuVXjZ eE8lnjR3lWb1EJNc6MPT/PtNLuz6BxMTjfGISPaiL5XeGvFpedzEu4eOUqO4ifm4xBVP /sT9Ce2Icy7aJnua+5YDy7HXbXkg55TUJQ4+y/E3jC9RrgCsYGy+Ci+mGFnW6hBRNg30 3MyR6HOmR2LFib+hk5PRNBLfNzClw49gn7BTFC82epjnC9vtm2RTUFP5zpI5S8GLRDgu oLAP2bmUvrqP5af/zHHKI4jhNl2wp9NnXseF5oFWF8f5KIYzL20yivzP6AxLghUrWHlT z3Zg== 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=/mAF4FpmVyE9qnDdQYan0izn50M7ikt8vaaiIHkY8bs=; b=aCwwhRwTqmHoL60zlyRoXftyAHP2tcxgvUr9jc17eSNOxdqLu5IVDnfRzSQ5YC2/Wp P+HFBWOOvpnMzcHAjd2PjOXa7HvQm0WAcmX+C6yhQlU0nvhQcC+SqKS498yD1NzDcp+q vNNslwxlxLdfkmJ5dvc9+NNFs+8+IB8rnYjJjQ/GSnJAkJyAwDgrFvpsFqf6god+kkpR L8I3wifuC8UgEuVK3X73j9z8WRf9HBmTIjqk4SUuTiMOZ22GlFj0NQ+/Sb5R0YwMSOlV MJap3LSMktSet+S/m1TpkzyItzqgEavA/u4xumOPIWMQTyhdk6MW5yVjifoXj9HKFQC+ /i9w== X-Gm-Message-State: AHPjjUhB2YbOJARrftLtzskH4W7F12xf6OY+NzJgoTe85ebFfLshy4pW XcRvj9lRe13DNhbuPVg= X-Google-Smtp-Source: ADKCNb6IBfKEAC7N1ZU29rs0537e0Z4N9qsTOEA508TVFsnLpuwMrAoi+YH11IkjsbDLvmQzLuYOsA== X-Received: by 10.223.157.3 with SMTP id k3mr446394wre.122.1504821385769; Thu, 07 Sep 2017 14:56:25 -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 z51sm577870wrb.22.2017.09.07.14.56.24 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Sep 2017 14:56:24 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Thu, 7 Sep 2017 22:56:16 +0100 Message-Id: <20170907215619.3182-2-sw@jkqxz.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170907215619.3182-1-sw@jkqxz.net> References: <20170907215619.3182-1-sw@jkqxz.net> Subject: [FFmpeg-devel] [PATCH 2/5] hwcontext_vaapi: Add DRM to VAAPI 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" --- Unchanged. libavutil/hwcontext_vaapi.c | 215 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 214 insertions(+), 1 deletion(-) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 3970726d30..c69db39238 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -25,6 +25,11 @@ # include #endif +#if CONFIG_LIBDRM +# include +# include +#endif + #include #if HAVE_UNISTD_H # include @@ -41,6 +46,10 @@ #include "pixdesc.h" #include "pixfmt.h" +#if CONFIG_LIBDRM +# include "hwcontext_drm.h" +#endif + typedef struct VAAPIDevicePriv { #if HAVE_VAAPI_X11 Display *x11_display; @@ -897,6 +906,170 @@ static int vaapi_map_from(AVHWFramesContext *hwfc, AVFrame *dst, return 0; } +#if CONFIG_LIBDRM + +#define DRM_MAP(va, layers, ...) { \ + VA_FOURCC_ ## va, \ + layers, \ + { __VA_ARGS__ } \ + } +static const struct { + uint32_t va_fourcc; + int nb_layer_formats; + uint32_t layer_formats[AV_DRM_MAX_PLANES]; +} vaapi_drm_format_map[] = { + DRM_MAP(NV12, 2, DRM_FORMAT_R8, DRM_FORMAT_RG88), + DRM_MAP(NV12, 1, DRM_FORMAT_NV12), +#ifdef VA_FOURCC_P010 + DRM_MAP(P010, 2, DRM_FORMAT_R16, DRM_FORMAT_RG1616), +#endif + DRM_MAP(BGRA, 1, DRM_FORMAT_BGRA8888), + DRM_MAP(BGRX, 1, DRM_FORMAT_BGRX8888), + DRM_MAP(RGBA, 1, DRM_FORMAT_RGBA8888), + DRM_MAP(RGBX, 1, DRM_FORMAT_RGBX8888), +#ifdef VA_FOURCC_ABGR + DRM_MAP(ABGR, 1, DRM_FORMAT_ABGR8888), + DRM_MAP(XBGR, 1, DRM_FORMAT_XBGR8888), +#endif + DRM_MAP(ARGB, 1, DRM_FORMAT_ARGB8888), + DRM_MAP(XRGB, 1, DRM_FORMAT_XRGB8888), +}; +#undef DRM_MAP + +static void vaapi_unmap_from_drm(AVHWFramesContext *dst_fc, + HWMapDescriptor *hwmap) +{ + AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + + VASurfaceID surface_id = (VASurfaceID)(uintptr_t)hwmap->priv; + + vaDestroySurfaces(dst_dev->display, &surface_id, 1); +} + +static int vaapi_map_from_drm(AVHWFramesContext *src_fc, AVFrame *dst, + const AVFrame *src, int flags) +{ + AVHWFramesContext *dst_fc = + (AVHWFramesContext*)dst->hw_frames_ctx->data; + AVVAAPIDeviceContext *dst_dev = dst_fc->device_ctx->hwctx; + const AVDRMFrameDescriptor *desc; + VASurfaceID surface_id; + VAStatus vas; + uint32_t va_fourcc, va_rt_format; + int err, i, j, k; + + unsigned long buffer_handle; + VASurfaceAttribExternalBuffers buffer_desc; + VASurfaceAttrib attrs[2] = { + { + .type = VASurfaceAttribMemoryType, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypeInteger, + .value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME, + }, + { + .type = VASurfaceAttribExternalBufferDescriptor, + .flags = VA_SURFACE_ATTRIB_SETTABLE, + .value.type = VAGenericValueTypePointer, + .value.value.p = &buffer_desc, + } + }; + + desc = (AVDRMFrameDescriptor*)src->data[0]; + + if (desc->nb_objects != 1) { + av_log(dst_fc, AV_LOG_ERROR, "VAAPI can only map frames " + "made from a single DRM object.\n"); + return AVERROR(EINVAL); + } + + va_fourcc = 0; + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_drm_format_map); i++) { + if (desc->nb_layers != vaapi_drm_format_map[i].nb_layer_formats) + continue; + for (j = 0; j < desc->nb_layers; j++) { + if (desc->layers[j].format != + vaapi_drm_format_map[i].layer_formats[j]) + break; + } + if (j != desc->nb_layers) + continue; + va_fourcc = vaapi_drm_format_map[i].va_fourcc; + break; + } + if (!va_fourcc) { + av_log(dst_fc, AV_LOG_ERROR, "DRM format not supported " + "by VAAPI.\n"); + return AVERROR(EINVAL); + } + + av_log(dst_fc, AV_LOG_DEBUG, "Map DRM object %d to VAAPI as " + "%08x.\n", desc->objects[0].fd, va_fourcc); + + for (i = 0; i < FF_ARRAY_ELEMS(vaapi_format_map); i++) { + if (vaapi_format_map[i].fourcc == va_fourcc) + va_rt_format = vaapi_format_map[i].rt_format; + } + + buffer_handle = desc->objects[0].fd; + buffer_desc.pixel_format = va_fourcc; + buffer_desc.width = src_fc->width; + buffer_desc.height = src_fc->height; + buffer_desc.data_size = desc->objects[0].size; + buffer_desc.buffers = &buffer_handle; + buffer_desc.num_buffers = 1; + buffer_desc.flags = 0; + + k = 0; + for (i = 0; i < desc->nb_layers; i++) { + for (j = 0; j < desc->layers[i].nb_planes; j++) { + buffer_desc.pitches[k] = desc->layers[i].planes[j].pitch; + buffer_desc.offsets[k] = desc->layers[i].planes[j].offset; + ++k; + } + } + buffer_desc.num_planes = k; + + vas = vaCreateSurfaces(dst_dev->display, va_rt_format, + src->width, src->height, + &surface_id, 1, + attrs, FF_ARRAY_ELEMS(attrs)); + if (vas != VA_STATUS_SUCCESS) { + av_log(dst_fc, AV_LOG_ERROR, "Failed to create surface from DRM " + "object: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + + err = ff_hwframe_map_create(dst->hw_frames_ctx, dst, src, + &vaapi_unmap_from_drm, + (void*)(uintptr_t)surface_id); + if (err < 0) + return err; + + dst->width = src->width; + dst->height = src->height; + dst->data[3] = (uint8_t*)(uintptr_t)surface_id; + + av_log(dst_fc, AV_LOG_DEBUG, "Mapped DRM object %d to " + "surface %#x.\n", desc->objects[0].fd, surface_id); + + return 0; +} +#endif + +static int vaapi_map_to(AVHWFramesContext *hwfc, AVFrame *dst, + const AVFrame *src, int flags) +{ + switch (src->format) { +#if CONFIG_LIBDRM + case AV_PIX_FMT_DRM_PRIME: + return vaapi_map_from_drm(hwfc, dst, src, flags); +#endif + default: + return AVERROR(ENOSYS); + } +} + static void vaapi_device_free(AVHWDeviceContext *ctx) { AVVAAPIDeviceContext *hwctx = ctx->hwctx; @@ -999,6 +1172,45 @@ static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, return 0; } +static int vaapi_device_derive(AVHWDeviceContext *ctx, + AVHWDeviceContext *src_ctx, int flags) +{ +#if CONFIG_LIBDRM + if (src_ctx->type == AV_HWDEVICE_TYPE_DRM) { + AVDRMDeviceContext *src_hwctx = src_ctx->hwctx; + AVVAAPIDeviceContext *hwctx = ctx->hwctx; + VADisplay *display; + VAStatus vas; + int major, minor; + + if (src_hwctx->fd < 0) { + av_log(ctx, AV_LOG_ERROR, "DRM instance requires an associated " + "device to derive a VA display from.\n"); + return AVERROR(EINVAL); + } + + display = vaGetDisplayDRM(src_hwctx->fd); + if (!display) { + av_log(ctx, AV_LOG_ERROR, "Failed to open a VA display from " + "DRM device.\n"); + return AVERROR(EIO); + } + + vas = vaInitialize(display, &major, &minor); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI " + "connection: %d (%s).\n", vas, vaErrorStr(vas)); + vaTerminate(display); + return AVERROR(EIO); + } + + hwctx->display = display; + return 0; + } +#endif + return AVERROR(ENOSYS); +} + const HWContextType ff_hwcontext_type_vaapi = { .type = AV_HWDEVICE_TYPE_VAAPI, .name = "VAAPI", @@ -1010,6 +1222,7 @@ const HWContextType ff_hwcontext_type_vaapi = { .frames_priv_size = sizeof(VAAPIFramesContext), .device_create = &vaapi_device_create, + .device_derive = &vaapi_device_derive, .device_init = &vaapi_device_init, .device_uninit = &vaapi_device_uninit, .frames_get_constraints = &vaapi_frames_get_constraints, @@ -1019,7 +1232,7 @@ const HWContextType ff_hwcontext_type_vaapi = { .transfer_get_formats = &vaapi_transfer_get_formats, .transfer_data_to = &vaapi_transfer_data_to, .transfer_data_from = &vaapi_transfer_data_from, - .map_to = NULL, + .map_to = &vaapi_map_to, .map_from = &vaapi_map_from, .pix_fmts = (const enum AVPixelFormat[]) {