#define GST_CAT_DEFAULT gst_vulkan_device_debug
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT);
#define gst_vulkan_device_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstVulkanDevice, gst_vulkan_device, GST_TYPE_OBJECT,
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "vulkandevice", 0,
- "Vulkan Device"));
+ "Vulkan Device");
+ GST_DEBUG_CATEGORY_GET (GST_CAT_CONTEXT, "GST_CONTEXT"));
static void gst_vulkan_device_finalize (GObject * object);
return TRUE;
}
+
+/**
+ * gst_context_set_vulkan_device:
+ * @context: a #GstContext
+ * @device: a #GstVulkanDevice
+ *
+ * Sets @device on @context
+ *
+ * Since: 1.10
+ */
+void
+gst_context_set_vulkan_device (GstContext * context, GstVulkanDevice * device)
+{
+ GstStructure *s;
+
+ g_return_if_fail (context != NULL);
+ g_return_if_fail (gst_context_is_writable (context));
+
+ if (device)
+ GST_CAT_LOG (GST_CAT_CONTEXT,
+ "setting GstVulkanDevice(%" GST_PTR_FORMAT ") on context(%"
+ GST_PTR_FORMAT ")", device, context);
+
+ s = gst_context_writable_structure (context);
+ gst_structure_set (s, GST_VULKAN_DEVICE_CONTEXT_TYPE_STR,
+ GST_TYPE_VULKAN_DEVICE, device, NULL);
+}
+
+/**
+ * gst_context_get_vulkan_device:
+ * @context: a #GstContext
+ * @device: resulting #GstVulkanDevice
+ *
+ * Returns: Whether @device was in @context
+ *
+ * Since: 1.10
+ */
+gboolean
+gst_context_get_vulkan_device (GstContext * context, GstVulkanDevice ** device)
+{
+ const GstStructure *s;
+ gboolean ret;
+
+ g_return_val_if_fail (device != NULL, FALSE);
+ g_return_val_if_fail (context != NULL, FALSE);
+
+ s = gst_context_get_structure (context);
+ ret = gst_structure_get (s, GST_VULKAN_DEVICE_CONTEXT_TYPE_STR,
+ GST_TYPE_VULKAN_DEVICE, device, NULL);
+
+ GST_CAT_LOG (GST_CAT_CONTEXT, "got GstVulkanDevice(%" GST_PTR_FORMAT
+ ") from context(%" GST_PTR_FORMAT ")", *device, context);
+
+ return ret;
+}
+
+gboolean
+gst_vulkan_device_handle_context_query (GstElement * element, GstQuery * query,
+ GstVulkanDevice ** device)
+{
+ gboolean res = FALSE;
+ const gchar *context_type;
+ GstContext *context, *old_context;
+
+ g_return_val_if_fail (element != NULL, FALSE);
+ g_return_val_if_fail (query != NULL, FALSE);
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE);
+ g_return_val_if_fail (device != NULL, FALSE);
+
+ gst_query_parse_context_type (query, &context_type);
+
+ if (g_strcmp0 (context_type, GST_VULKAN_DEVICE_CONTEXT_TYPE_STR) == 0) {
+ gst_query_parse_context (query, &old_context);
+
+ if (old_context)
+ context = gst_context_copy (old_context);
+ else
+ context = gst_context_new (GST_VULKAN_DEVICE_CONTEXT_TYPE_STR, TRUE);
+
+ gst_context_set_vulkan_device (context, *device);
+ gst_query_set_context (query, context);
+ gst_context_unref (context);
+
+ res = *device != NULL;
+ }
+
+ return res;
+}
+
+gboolean
+gst_vulkan_device_run_context_query (GstElement * element,
+ GstVulkanDevice ** device)
+{
+ GstQuery *query;
+
+ g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
+ g_return_val_if_fail (device != NULL, FALSE);
+
+ if (*device && GST_IS_VULKAN_DEVICE (*device))
+ return TRUE;
+
+ if ((query =
+ gst_vulkan_local_context_query (element,
+ GST_VULKAN_DEVICE_CONTEXT_TYPE_STR, FALSE))) {
+ GstContext *context;
+
+ gst_query_parse_context (query, &context);
+ if (context)
+ gst_context_get_vulkan_device (context, device);
+ }
+
+ GST_DEBUG_OBJECT (element, "found device %p", *device);
+
+ gst_query_unref (query);
+
+ if (*device)
+ return TRUE;
+
+ return FALSE;
+}
#define GST_VULKAN_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_DEVICE, GstVulkanDeviceClass))
GType gst_vulkan_device_get_type (void);
+#define GST_VULKAN_DEVICE_CONTEXT_TYPE_STR "gst.vulkan.device"
+
struct _GstVulkanDevice
{
GstObject parent;
VkCommandBuffer * cmd,
GError ** error);
+void gst_context_set_vulkan_device (GstContext * context,
+ GstVulkanDevice * device);
+gboolean gst_context_get_vulkan_device (GstContext * context,
+ GstVulkanDevice ** device);
+gboolean gst_vulkan_device_handle_context_query (GstElement * element,
+ GstQuery * query,
+ GstVulkanDevice ** device);
+gboolean gst_vulkan_device_run_context_query (GstElement * element,
+ GstVulkanDevice ** device);
+
G_END_DECLS
#endif /* _VK_DEVICE_H_ */
return NULL;
}
+
+gboolean
+gst_vulkan_display_handle_context_query (GstElement * element, GstQuery * query,
+ GstVulkanDisplay ** display)
+{
+ gboolean res = FALSE;
+ const gchar *context_type;
+ GstContext *context, *old_context;
+
+ g_return_val_if_fail (element != NULL, FALSE);
+ g_return_val_if_fail (query != NULL, FALSE);
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE);
+ g_return_val_if_fail (display != NULL, FALSE);
+
+ gst_query_parse_context_type (query, &context_type);
+
+ if (g_strcmp0 (context_type, GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR) == 0) {
+ gst_query_parse_context (query, &old_context);
+
+ if (old_context)
+ context = gst_context_copy (old_context);
+ else
+ context = gst_context_new (GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR, TRUE);
+
+ gst_context_set_vulkan_display (context, *display);
+ gst_query_set_context (query, context);
+ gst_context_unref (context);
+
+ res = *display != NULL;
+ }
+
+ return res;
+}
+
+gboolean
+gst_vulkan_display_run_context_query (GstElement * element,
+ GstVulkanDisplay ** display)
+{
+ g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
+ g_return_val_if_fail (display != NULL, FALSE);
+
+ if (*display && GST_IS_VULKAN_DISPLAY (*display))
+ return TRUE;
+
+ gst_vulkan_global_context_query (element,
+ GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR);
+
+ GST_DEBUG_OBJECT (element, "found display %p", *display);
+
+ if (*display)
+ return TRUE;
+
+ return FALSE;
+}
GstVulkanDisplay ** display);
void gst_context_set_vulkan_display (GstContext * context,
GstVulkanDisplay * display);
+gboolean gst_vulkan_display_handle_context_query (GstElement * element,
+ GstQuery * query,
+ GstVulkanDisplay ** display);
+gboolean gst_vulkan_display_run_context_query (GstElement * element,
+ GstVulkanDisplay ** display);
/* GstVulkanWindow usage only */
gboolean gst_vulkan_display_remove_window (GstVulkanDisplay * display, GstVulkanWindow * window);
#define GST_CAT_DEFAULT gst_vulkan_instance_debug
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
GST_DEBUG_CATEGORY (GST_VULKAN_DEBUG_CAT);
-GST_DEBUG_CATEGORY (GST_CAT_CONTEXT);
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT);
enum
{
return ret;
}
+
+gboolean
+gst_vulkan_instance_handle_context_query (GstElement * element,
+ GstQuery * query, GstVulkanInstance ** instance)
+{
+ gboolean res = FALSE;
+ const gchar *context_type;
+ GstContext *context, *old_context;
+
+ g_return_val_if_fail (element != NULL, FALSE);
+ g_return_val_if_fail (query != NULL, FALSE);
+ g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE);
+ g_return_val_if_fail (instance != NULL, FALSE);
+
+ gst_query_parse_context_type (query, &context_type);
+
+ if (g_strcmp0 (context_type, GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR) == 0) {
+ gst_query_parse_context (query, &old_context);
+
+ if (old_context)
+ context = gst_context_copy (old_context);
+ else
+ context = gst_context_new (GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR, TRUE);
+
+ gst_context_set_vulkan_instance (context, *instance);
+ gst_query_set_context (query, context);
+ gst_context_unref (context);
+
+ res = *instance != NULL;
+ }
+
+ return res;
+}
+
+gboolean
+gst_vulkan_instance_run_context_query (GstElement * element,
+ GstVulkanInstance ** instance)
+{
+ g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
+ g_return_val_if_fail (instance != NULL, FALSE);
+
+ if (*instance && GST_IS_VULKAN_INSTANCE (*instance))
+ return TRUE;
+
+ gst_vulkan_global_context_query (element,
+ GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR);
+
+ GST_DEBUG_OBJECT (element, "found instance %p", *instance);
+
+ if (*instance)
+ return TRUE;
+
+ return FALSE;
+}
GstObjectClass parent_class;
};
-GstVulkanInstance * gst_vulkan_instance_new (void);
-gboolean gst_vulkan_instance_open (GstVulkanInstance * instance,
- GError ** error);
-
-gpointer gst_vulkan_instance_get_proc_address (GstVulkanInstance * instance,
- const gchar * name);
-
-GstVulkanDevice * gst_vulkan_instance_create_device (GstVulkanInstance * instance,
- GError ** error);
-
-void gst_context_set_vulkan_instance (GstContext * context,
- GstVulkanInstance * instance);
-gboolean gst_context_get_vulkan_instance (GstContext * context,
- GstVulkanInstance ** instance);
+GstVulkanInstance * gst_vulkan_instance_new (void);
+gboolean gst_vulkan_instance_open (GstVulkanInstance * instance,
+ GError ** error);
+
+gpointer gst_vulkan_instance_get_proc_address (GstVulkanInstance * instance,
+ const gchar * name);
+
+GstVulkanDevice * gst_vulkan_instance_create_device (GstVulkanInstance * instance,
+ GError ** error);
+
+void gst_context_set_vulkan_instance (GstContext * context,
+ GstVulkanInstance * instance);
+gboolean gst_context_get_vulkan_instance (GstContext * context,
+ GstVulkanInstance ** instance);
+gboolean gst_vulkan_instance_handle_context_query (GstElement * element,
+ GstQuery * query,
+ GstVulkanInstance ** instance);
+gboolean gst_vulkan_instance_run_context_query (GstElement * element,
+ GstVulkanInstance ** instance);
G_END_DECLS
gst_vulkan_sink_query (GstBaseSink * bsink, GstQuery * query)
{
GstVulkanSink *vk_sink = GST_VULKAN_SINK (bsink);
- gboolean res = FALSE;
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONTEXT:{
- res = gst_vulkan_handle_context_query (GST_ELEMENT (vk_sink), query,
- &vk_sink->display, &vk_sink->instance, &vk_sink->device);
+ if (gst_vulkan_handle_context_query (GST_ELEMENT (vk_sink), query,
+ &vk_sink->display, &vk_sink->instance, &vk_sink->device))
+ return TRUE;
- if (res)
- return res;
break;
}
default:
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
-static gboolean
-_find_vulkan_device (GstVulkanUpload * upload)
-{
- /* Requires the instance to exist */
- GstQuery *query;
- GstContext *context;
- const GstStructure *s;
-
- if (upload->device)
- return TRUE;
-
- query = gst_query_new_context ("gst.vulkan.device");
- if (!upload->device
- && gst_vulkan_run_query (GST_ELEMENT (upload), query, GST_PAD_SRC)) {
- gst_query_parse_context (query, &context);
- if (context) {
- s = gst_context_get_structure (context);
- gst_structure_get (s, "device", GST_TYPE_VULKAN_DEVICE, &upload->device,
- NULL);
- }
- }
- if (!upload->device
- && gst_vulkan_run_query (GST_ELEMENT (upload), query, GST_PAD_SINK)) {
- gst_query_parse_context (query, &context);
- if (context) {
- s = gst_context_get_structure (context);
- gst_structure_get (s, "device", GST_TYPE_VULKAN_DEVICE, &upload->device,
- NULL);
- }
- }
-
- GST_DEBUG_OBJECT (upload, "found device %p", upload->device);
-
- gst_query_unref (query);
-
- if (upload->device)
- return TRUE;
-
- return FALSE;
-}
-
static GstStateChangeReturn
gst_vulkan_upload_change_state (GstElement * element, GstStateChange transition)
{
("Failed to retreive vulkan instance/display"), (NULL));
return GST_STATE_CHANGE_FAILURE;
}
- if (!_find_vulkan_device (vk_upload)) {
+ if (!gst_vulkan_device_run_context_query (GST_ELEMENT (vk_upload),
+ &vk_upload->device)) {
GST_ELEMENT_ERROR (vk_upload, RESOURCE, NOT_FOUND,
("Failed to retreive vulkan device"), (NULL));
return GST_STATE_CHANGE_FAILURE;
return g_value_get_boolean (&res);
}
-static void
-_vk_gst_context_query (GstElement * element, const gchar * display_type)
+void
+gst_vulkan_global_context_query (GstElement * element,
+ const gchar * context_type)
+{
+ GstQuery *query;
+ GstMessage *msg;
+
+ if ((query = gst_vulkan_local_context_query (element, context_type, TRUE))) {
+ gst_query_unref (query);
+ return;
+ }
+
+ /* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with
+ * the required context type and afterwards check if a
+ * usable context was set now as in 1). The message could
+ * be handled by the parent bins of the element and the
+ * application.
+ */
+ GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
+ "posting need context message");
+ msg = gst_message_new_need_context (GST_OBJECT_CAST (element), context_type);
+ gst_element_post_message (element, msg);
+
+ /*
+ * Whomever responds to the need-context message performs a
+ * GstElement::set_context() with the required context in which the element
+ * is required to update the display_ptr or call gst_vulkan_handle_set_context().
+ */
+}
+
+GstQuery *
+gst_vulkan_local_context_query (GstElement * element,
+ const gchar * context_type, gboolean set_context)
{
GstQuery *query;
GstContext *ctxt;
* check if downstream already has a context of the specific type
* 2b) Query upstream as above.
*/
- query = gst_query_new_context (display_type);
+ query = gst_query_new_context (context_type);
if (gst_vulkan_run_query (element, query, GST_PAD_SRC)) {
gst_query_parse_context (query, &ctxt);
GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
"found context (%p) in downstream query", ctxt);
- gst_element_set_context (element, ctxt);
+ if (set_context)
+ gst_element_set_context (element, ctxt);
} else if (gst_vulkan_run_query (element, query, GST_PAD_SINK)) {
gst_query_parse_context (query, &ctxt);
GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
"found context (%p) in upstream query", ctxt);
- gst_element_set_context (element, ctxt);
+ if (set_context)
+ gst_element_set_context (element, ctxt);
} else {
- /* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with
- * the required context type and afterwards check if a
- * usable context was set now as in 1). The message could
- * be handled by the parent bins of the element and the
- * application.
- */
- GstMessage *msg;
-
- GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element,
- "posting need context message");
- msg = gst_message_new_need_context (GST_OBJECT_CAST (element),
- display_type);
- gst_element_post_message (element, msg);
+ gst_query_unref (query);
+ query = NULL;
}
- /*
- * Whomever responds to the need-context message performs a
- * GstElement::set_context() with the required context in which the element
- * is required to update the display_ptr or call gst_vulkan_handle_set_context().
- */
-
- gst_query_unref (query);
+ return query;
}
static void
_vk_display_context_query (GstElement * element,
GstVulkanDisplay ** display_ptr)
{
- _vk_gst_context_query (element, GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR);
+ gst_vulkan_global_context_query (element,
+ GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR);
}
/* 4) Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT
if (!*instance_ptr) {
GError *error = NULL;
- _vk_gst_context_query (element, GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR);
+ gst_vulkan_global_context_query (element,
+ GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR);
/* Neighbour found and it updated the display */
if (!*instance_ptr) {
GstVulkanDisplay ** display, GstVulkanInstance ** instance,
GstVulkanDevice ** device)
{
- gboolean res = FALSE;
- const gchar *context_type;
- GstContext *context, *old_context;
-
- g_return_val_if_fail (element != NULL, FALSE);
- g_return_val_if_fail (query != NULL, FALSE);
- g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONTEXT, FALSE);
- g_return_val_if_fail (display != NULL, FALSE);
- g_return_val_if_fail (instance != NULL, FALSE);
- g_return_val_if_fail (device != NULL, FALSE);
-
- gst_query_parse_context_type (query, &context_type);
-
- if (g_strcmp0 (context_type, GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR) == 0) {
- gst_query_parse_context (query, &old_context);
-
- if (old_context)
- context = gst_context_copy (old_context);
- else
- context = gst_context_new (GST_VULKAN_DISPLAY_CONTEXT_TYPE_STR, TRUE);
-
- gst_context_set_vulkan_display (context, *display);
- gst_query_set_context (query, context);
- gst_context_unref (context);
-
- res = *display != NULL;
- } else if (g_strcmp0 (context_type,
- GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR) == 0) {
- gst_query_parse_context (query, &old_context);
-
- if (old_context)
- context = gst_context_copy (old_context);
- else
- context = gst_context_new (GST_VULKAN_INSTANCE_CONTEXT_TYPE_STR, TRUE);
-
- gst_context_set_vulkan_instance (context, *instance);
- gst_query_set_context (query, context);
- gst_context_unref (context);
-
- res = *instance != NULL;
- } else if (g_strcmp0 (context_type, "gst.vulkan.device") == 0) {
- GstStructure *s;
-
- gst_query_parse_context (query, &old_context);
-
- if (old_context)
- context = gst_context_copy (old_context);
- else
- context = gst_context_new ("gst.vulkan.device", TRUE);
-
- s = gst_context_writable_structure (context);
- gst_structure_set (s, "device", GST_TYPE_VULKAN_DEVICE, *device, NULL);
- gst_query_set_context (query, context);
- gst_context_unref (context);
-
- res = *instance != NULL;
- }
-
- return res;
+ if (gst_vulkan_display_handle_context_query (element, query, display))
+ return TRUE;
+ if (gst_vulkan_instance_handle_context_query (element, query, instance))
+ return TRUE;
+ if (gst_vulkan_device_handle_context_query (element, query, device))
+ return TRUE;
+
+ return FALSE;
}
gboolean gst_vulkan_handle_context_query (GstElement * element, GstQuery * query,
GstVulkanDisplay ** display, GstVulkanInstance ** instance, GstVulkanDevice ** device);
+void gst_vulkan_global_context_query (GstElement * element, const gchar * context_type);
+GstQuery * gst_vulkan_local_context_query (GstElement * element, const gchar * context_type, gboolean set_context);
gboolean gst_vulkan_run_query (GstElement * element,
GstQuery * query, GstPadDirection direction);