/* * GStreamer * Copyright (C) 2019 Matthew Waters * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ /** * SECTION:element-vulkanimageidentity * @title: vulkanimgeidentity * * vulkanimageidentity produces a vulkan image that is a copy of the input image. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "gstvulkanelements.h" #include "vkimageidentity.h" #include "shaders/identity.vert.h" #include "shaders/identity.frag.h" GST_DEBUG_CATEGORY (gst_debug_vulkan_image_identity); #define GST_CAT_DEFAULT gst_debug_vulkan_image_identity static gboolean gst_vulkan_image_identity_start (GstBaseTransform * bt); static gboolean gst_vulkan_image_identity_stop (GstBaseTransform * bt); static GstFlowReturn gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf, GstBuffer * outbuf); static gboolean gst_vulkan_image_identity_set_caps (GstBaseTransform * bt, GstCaps * in_caps, GstCaps * out_caps); #define IMAGE_FORMATS " { BGRA }" static GstStaticPadTemplate gst_vulkan_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VULKAN_IMAGE, IMAGE_FORMATS))); static GstStaticPadTemplate gst_vulkan_src_template = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VULKAN_IMAGE, IMAGE_FORMATS))); enum { PROP_0, }; enum { SIGNAL_0, LAST_SIGNAL }; /* static guint gst_vulkan_image_identity_signals[LAST_SIGNAL] = { 0 }; */ #define gst_vulkan_image_identity_parent_class parent_class G_DEFINE_TYPE_WITH_CODE (GstVulkanImageIdentity, gst_vulkan_image_identity, GST_TYPE_VULKAN_VIDEO_FILTER, GST_DEBUG_CATEGORY_INIT (gst_debug_vulkan_image_identity, "vulkanimageidentity", 0, "Vulkan Image identity")); GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (vulkanimageidentity, "vulkanimageidentity", GST_RANK_NONE, GST_TYPE_VULKAN_IMAGE_IDENTITY, vulkan_element_init (plugin)); static void gst_vulkan_image_identity_class_init (GstVulkanImageIdentityClass * klass) { GstElementClass *gstelement_class; GstBaseTransformClass *gstbasetransform_class; gstelement_class = (GstElementClass *) klass; gstbasetransform_class = (GstBaseTransformClass *) klass; gst_element_class_set_metadata (gstelement_class, "Vulkan Image Identity", "Filter/Video", "A Vulkan image copier", "Matthew Waters "); gst_element_class_add_static_pad_template (gstelement_class, &gst_vulkan_sink_template); gst_element_class_add_static_pad_template (gstelement_class, &gst_vulkan_src_template); gstbasetransform_class->start = GST_DEBUG_FUNCPTR (gst_vulkan_image_identity_start); gstbasetransform_class->stop = GST_DEBUG_FUNCPTR (gst_vulkan_image_identity_stop); gstbasetransform_class->set_caps = gst_vulkan_image_identity_set_caps; gstbasetransform_class->transform = gst_vulkan_image_identity_transform; } static void gst_vulkan_image_identity_init (GstVulkanImageIdentity * vk_identity) { } static gboolean gst_vulkan_image_identity_set_caps (GstBaseTransform * bt, GstCaps * in_caps, GstCaps * out_caps) { GstVulkanVideoFilter *vfilter = GST_VULKAN_VIDEO_FILTER (bt); GstVulkanImageIdentity *vk_identity = GST_VULKAN_IMAGE_IDENTITY (bt); if (!GST_BASE_TRANSFORM_CLASS (parent_class)->set_caps (bt, in_caps, out_caps)) return FALSE; if (!gst_vulkan_full_screen_quad_set_info (vk_identity->quad, &vfilter->in_info, &vfilter->out_info)) return FALSE; return TRUE; } static gboolean gst_vulkan_image_identity_start (GstBaseTransform * bt) { GstVulkanImageIdentity *vk_identity = GST_VULKAN_IMAGE_IDENTITY (bt); GstVulkanVideoFilter *vfilter = GST_VULKAN_VIDEO_FILTER (vk_identity); GstVulkanHandle *vert, *frag; GError *error = NULL; if (!GST_BASE_TRANSFORM_CLASS (parent_class)->start (bt)) return FALSE; vk_identity->quad = gst_vulkan_full_screen_quad_new (vfilter->queue); if (!(vert = gst_vulkan_create_shader (vfilter->device, identity_vert, identity_vert_size, &error))) goto error; if (!(frag = gst_vulkan_create_shader (vfilter->device, identity_frag, identity_frag_size, &error))) { gst_vulkan_handle_unref (vert); goto error; } gst_vulkan_full_screen_quad_set_shaders (vk_identity->quad, vert, frag); gst_vulkan_handle_unref (vert); gst_vulkan_handle_unref (frag); return TRUE; error: GST_ELEMENT_ERROR (bt, RESOURCE, NOT_FOUND, ("%s", error->message), (NULL)); return FALSE; } static gboolean gst_vulkan_image_identity_stop (GstBaseTransform * bt) { GstVulkanImageIdentity *vk_identity = GST_VULKAN_IMAGE_IDENTITY (bt); gst_clear_object (&vk_identity->quad); return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (bt); } static GstFlowReturn gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf, GstBuffer * outbuf) { GstVulkanImageIdentity *vk_identity = GST_VULKAN_IMAGE_IDENTITY (bt); GError *error = NULL; if (!gst_vulkan_full_screen_quad_set_input_buffer (vk_identity->quad, inbuf, &error)) goto error; if (!gst_vulkan_full_screen_quad_set_output_buffer (vk_identity->quad, outbuf, &error)) goto error; if (!gst_vulkan_full_screen_quad_draw (vk_identity->quad, &error)) goto error; return GST_FLOW_OK; error: GST_ELEMENT_ERROR (bt, LIBRARY, FAILED, ("%s", error->message), (NULL)); g_clear_error (&error); return GST_FLOW_ERROR; }