* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
* Copyright (C) 2002,2007 David A. Schleef <ds@schleef.org>
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
+ * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
#include "gltestsrc.h"
#include <gst/gst-i18n-plugin.h>
-#if GST_GL_HAVE_PLATFORM_EGL
-#include <gst/gl/egl/gsteglimagememory.h>
-#endif
-
#define USE_PEER_BUFFERALLOC
#define SUPPORTED_GL_APIS GST_GL_API_OPENGL
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
(GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
- "RGBA") "; "
- GST_VIDEO_CAPS_MAKE_WITH_FEATURES
- (GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META,
- "RGBA") "; " GST_VIDEO_CAPS_MAKE (GST_GL_COLOR_CONVERT_FORMATS))
+ "RGBA"))
);
#define gst_gl_test_src_parent_class parent_class
}
static GstCaps *
-gst_gl_test_src_set_caps_features (const GstCaps * caps,
- const gchar * feature_name)
-{
- GstCaps *ret = gst_gl_caps_replace_all_caps_features (caps, feature_name);
- gst_caps_set_simple (ret, "format", G_TYPE_STRING, "RGBA", NULL);
- return ret;
-}
-
-static GstCaps *
gst_gl_test_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
{
- GstGLTestSrc *src = GST_GL_TEST_SRC (bsrc);
- GstCaps *tmp;
- GstCaps *result = NULL;
- GstCaps *gl_caps;
- GstCaps *caps =
+ GstCaps *tmp = NULL;
+ GstCaps *result =
gst_caps_from_string ("video/x-raw(memory:GLMemory),format=RGBA");
- gl_caps =
- gst_caps_merge (gst_gl_test_src_set_caps_features (caps,
- GST_CAPS_FEATURE_MEMORY_GL_MEMORY),
- gst_gl_test_src_set_caps_features (caps,
- GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META));
- result =
- gst_gl_download_transform_caps (src->context, GST_PAD_SINK, caps, NULL);
- result = gst_caps_merge (gl_caps, result);
-
- GST_DEBUG_OBJECT (bsrc, "transfer returned caps %" GST_PTR_FORMAT, result);
-
if (filter) {
tmp = gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
gst_caps_unref (result);
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_CONTEXT:
{
+ const gchar *context_type;
+ GstContext *context, *old_context;
+
res = gst_gl_handle_context_query ((GstElement *) src, query,
&src->display, &src->other_context);
if (src->display)
gst_gl_display_filter_gl_api (src->display, SUPPORTED_GL_APIS);
+
+ gst_query_parse_context_type (query, &context_type);
+
+ if (g_strcmp0 (context_type, "gst.gl.local_context") == 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.gl.local_context", FALSE);
+
+ s = gst_context_writable_structure (context);
+ gst_structure_set (s, "context", GST_GL_TYPE_CONTEXT, src->context,
+ NULL);
+ gst_query_set_context (query, context);
+ gst_context_unref (context);
+
+ res = src->context != NULL;
+ }
+ GST_LOG_OBJECT (src, "context query of type %s %i", context_type, res);
+
+ if (res)
+ return res;
+
break;
}
case GST_QUERY_CONVERT:
gst_video_info_convert (&src->out_info, src_fmt, src_val, dest_fmt,
&dest_val);
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
- break;
+
+ return res;
}
default:
- res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
+ break;
}
- return res;
+ return GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
}
static void
gint width, height;
GstVideoFrame out_frame;
GstGLSyncMeta *sync_meta;
- guint out_tex, out_tex_target;
- gboolean to_download =
- gst_caps_features_is_equal (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY,
- gst_caps_get_features (src->out_caps, 0));
- GstMapFlags out_map_flags = GST_MAP_WRITE;
-
- to_download |= !gst_is_gl_memory (gst_buffer_peek_memory (buffer, 0));
-
- if (!to_download)
- out_map_flags |= GST_MAP_GL;
+ guint out_tex;
if (G_UNLIKELY (!src->negotiated || !src->context))
goto not_negotiated;
src->make_image = gst_gl_test_src_black;
}
- if (!gst_video_frame_map (&out_frame, &src->out_info, buffer, out_map_flags)) {
+ if (!gst_video_frame_map (&out_frame, &src->out_info, buffer,
+ GST_MAP_WRITE | GST_MAP_GL)) {
return GST_FLOW_NOT_NEGOTIATED;
}
- if (!to_download) {
- out_tex = *(guint *) out_frame.data[0];
- out_tex_target =
- ((GstGLMemory *) gst_buffer_peek_memory (buffer, 0))->tex_target;
- } else {
- GST_INFO ("Output Buffer does not contain correct meta, "
- "attempting to wrap for download");
-
- if (!src->download)
- src->download = gst_gl_download_new (src->context);
-
- gst_gl_download_set_format (src->download, &out_frame.info);
-
- if (!src->out_tex_id) {
- gst_gl_context_gen_texture (src->context, &src->out_tex_id,
- GST_VIDEO_FORMAT_RGBA, GST_VIDEO_FRAME_WIDTH (&out_frame),
- GST_VIDEO_FRAME_HEIGHT (&out_frame));
- }
- out_tex = src->out_tex_id;
- out_tex_target = GL_TEXTURE_2D;
- }
+ out_tex = *(guint *) out_frame.data[0];
gst_buffer_replace (&src->buffer, buffer);
- //blocking call, generate a FBO
if (!gst_gl_context_use_fbo_v2 (src->context, width, height, src->fbo,
src->depthbuffer, out_tex, gst_gl_test_src_callback,
(gpointer) src)) {
goto not_negotiated;
}
- if (to_download) {
- if (!gst_gl_download_perform_with_data (src->download,
- out_tex, out_tex_target, out_frame.data)) {
- GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s",
- "Failed to init upload format"), (NULL));
- return FALSE;
- }
- }
gst_video_frame_unmap (&out_frame);
sync_meta = gst_buffer_get_gl_sync_meta (buffer);
gst_object_unref (src->shader);
src->shader = NULL;
}
-
- if (src->out_tex_id) {
- gst_gl_context_del_texture (src->context, &src->out_tex_id);
- }
-
- if (src->download) {
- gst_object_unref (src->download);
- src->download = NULL;
- }
//blocking call, delete the FBO
gst_gl_context_del_fbo (src->context, src->fbo, src->depthbuffer);
gst_object_unref (src->context);
}
static gboolean
+_find_local_gl_context (GstGLTestSrc * src)
+{
+ GstQuery *query;
+ GstContext *context;
+ const GstStructure *s;
+
+ if (src->context)
+ return TRUE;
+
+ query = gst_query_new_context ("gst.gl.local_context");
+ if (!src->context && gst_gl_run_query (GST_ELEMENT (src), query, GST_PAD_SRC)) {
+ gst_query_parse_context (query, &context);
+ if (context) {
+ s = gst_context_get_structure (context);
+ gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &src->context,
+ NULL);
+ }
+ }
+ if (!src->context
+ && gst_gl_run_query (GST_ELEMENT (src), query, GST_PAD_SINK)) {
+ gst_query_parse_context (query, &context);
+ if (context) {
+ s = gst_context_get_structure (context);
+ gst_structure_get (s, "context", GST_GL_TYPE_CONTEXT, &src->context,
+ NULL);
+ }
+ }
+
+ GST_DEBUG_OBJECT (src, "found local context %p", src->context);
+
+ gst_query_unref (query);
+
+ if (src->context)
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean
gst_gl_test_src_decide_allocation (GstBaseSrc * basesrc, GstQuery * query)
{
GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc);
gst_gl_display_filter_gl_api (src->display, SUPPORTED_GL_APIS);
+ _find_local_gl_context (src);
+
if (gst_query_find_allocation_meta (query,
GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, &idx)) {
GstGLContext *context;