summaryrefslogtreecommitdiff
path: root/ext/eglgles/gsteglglessink.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/eglgles/gsteglglessink.c')
-rw-r--r--ext/eglgles/gsteglglessink.c136
1 files changed, 131 insertions, 5 deletions
diff --git a/ext/eglgles/gsteglglessink.c b/ext/eglgles/gsteglglessink.c
index 5eed2fd16..e8f966e56 100644
--- a/ext/eglgles/gsteglglessink.c
+++ b/ext/eglgles/gsteglglessink.c
@@ -356,6 +356,8 @@ static void gst_eglglessink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static GstStateChangeReturn gst_eglglessink_change_state (GstElement * element,
GstStateChange transition);
+static void gst_eglglessink_set_context (GstElement * element,
+ GstContext * context);
static GstFlowReturn gst_eglglessink_prepare (GstBaseSink * bsink,
GstBuffer * buf);
static GstFlowReturn gst_eglglessink_show_frame (GstVideoSink * vsink,
@@ -364,6 +366,8 @@ static gboolean gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps);
static GstCaps *gst_eglglessink_getcaps (GstBaseSink * bsink, GstCaps * filter);
static gboolean gst_eglglessink_propose_allocation (GstBaseSink * bsink,
GstQuery * query);
+static gboolean gst_eglglessink_query (GstBaseSink * bsink, GstQuery * query);
+static gboolean gst_eglglessink_event (GstBaseSink * bsink, GstEvent * event);
/* VideoOverlay interface cruft */
static void gst_eglglessink_videooverlay_init (GstVideoOverlayInterface *
@@ -1518,6 +1522,7 @@ HANDLE_ERROR:
static gboolean
gst_eglglessink_init_egl_display (GstEglGlesSink * eglglessink)
{
+ GstMessage *msg;
EGLDisplay display;
GST_DEBUG_OBJECT (eglglessink, "Enter EGL initial configuration");
@@ -1531,12 +1536,33 @@ gst_eglglessink_init_egl_display (GstEglGlesSink * eglglessink)
}
#endif
- display = eglGetDisplay (EGL_DEFAULT_DISPLAY);
- if (display == EGL_NO_DISPLAY) {
- GST_ERROR_OBJECT (eglglessink, "Could not get EGL display connection");
- goto HANDLE_ERROR; /* No EGL error is set by eglGetDisplay() */
+ msg = gst_message_new_need_context (GST_OBJECT_CAST (eglglessink));
+ gst_message_add_context_type (msg, GST_EGL_DISPLAY_CONTEXT_TYPE);
+ gst_element_post_message (GST_ELEMENT_CAST (eglglessink), msg);
+
+ GST_OBJECT_LOCK (eglglessink);
+ if (eglglessink->eglglesctx.set_display) {
+ eglglessink->eglglesctx.display =
+ gst_egl_display_ref (eglglessink->eglglesctx.set_display);
+ GST_OBJECT_UNLOCK (eglglessink);
+ } else {
+ GstContext *context;
+
+ GST_OBJECT_UNLOCK (eglglessink);
+
+ display = eglGetDisplay (EGL_DEFAULT_DISPLAY);
+ if (display == EGL_NO_DISPLAY) {
+ GST_ERROR_OBJECT (eglglessink, "Could not get EGL display connection");
+ goto HANDLE_ERROR; /* No EGL error is set by eglGetDisplay() */
+ }
+ eglglessink->eglglesctx.display = gst_egl_display_new (display);
+
+ context = gst_context_new ();
+ gst_context_set_egl_display (context, eglglessink->eglglesctx.display);
+
+ msg = gst_message_new_have_context (GST_OBJECT (eglglessink), context);
+ gst_element_post_message (GST_ELEMENT_CAST (eglglessink), msg);
}
- eglglessink->eglglesctx.display = gst_egl_display_new (display);
if (!eglInitialize (gst_egl_display_get (eglglessink->eglglesctx.display),
&eglglessink->eglglesctx.egl_major,
@@ -2512,6 +2538,103 @@ gst_eglglessink_getcaps (GstBaseSink * bsink, GstCaps * filter)
}
static gboolean
+gst_eglglessink_event (GstBaseSink * bsink, GstEvent * event)
+{
+ GstEglGlesSink *eglglessink;
+
+ eglglessink = GST_EGLGLESSINK (bsink);
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_CONTEXT:{
+ GstContext *context;
+ GstEGLDisplay *display;
+
+ gst_event_parse_context (event, &context);
+
+ if (gst_context_get_egl_display (context, &display)) {
+ GST_OBJECT_LOCK (eglglessink);
+ if (eglglessink->eglglesctx.set_display)
+ gst_egl_display_unref (eglglessink->eglglesctx.set_display);
+ eglglessink->eglglesctx.set_display = display;
+ GST_OBJECT_UNLOCK (eglglessink);
+ }
+
+ return GST_BASE_SINK_CLASS (gst_eglglessink_parent_class)->event (bsink,
+ event);
+ break;
+ }
+ default:
+ return GST_BASE_SINK_CLASS (gst_eglglessink_parent_class)->event (bsink,
+ event);
+ break;
+ }
+}
+
+static gboolean
+gst_eglglessink_query (GstBaseSink * bsink, GstQuery * query)
+{
+ GstEglGlesSink *eglglessink;
+
+ eglglessink = GST_EGLGLESSINK (bsink);
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_CONTEXT:{
+ guint i, n;
+
+ GST_BASE_SINK_CLASS (gst_eglglessink_parent_class)->query (bsink, query);
+
+ n = gst_query_get_n_context_types (query);
+ for (i = 0; i < n; i++) {
+ const gchar *context_type = NULL;
+
+ gst_query_parse_nth_context_type (query, i, &context_type);
+ if (g_strcmp0 (context_type, GST_EGL_DISPLAY_CONTEXT_TYPE) == 0) {
+ GstContext *context, *old_context;
+
+ gst_query_parse_context (query, &old_context);
+ if (old_context)
+ context = gst_context_copy (old_context);
+ else
+ context = gst_context_new ();
+
+ gst_context_set_egl_display (context,
+ eglglessink->eglglesctx.display);
+ gst_query_set_context (query, context);
+ break;
+ }
+ }
+
+ return TRUE;
+ break;
+ }
+ default:
+ return GST_BASE_SINK_CLASS (gst_eglglessink_parent_class)->query (bsink,
+ query);
+ break;
+ }
+}
+
+static void
+gst_eglglessink_set_context (GstElement * element, GstContext * context)
+{
+ GstEglGlesSink *eglglessink;
+ GstStructure *s;
+ GstEGLDisplay *display = NULL;
+
+ eglglessink = GST_EGLGLESSINK (element);
+
+ s = (GstStructure *) gst_context_get_structure (context);
+ if (gst_structure_get (s, GST_EGL_DISPLAY_CONTEXT_TYPE, GST_TYPE_EGL_DISPLAY,
+ &display, NULL)) {
+ GST_OBJECT_LOCK (eglglessink);
+ if (eglglessink->eglglesctx.set_display)
+ gst_egl_display_unref (eglglessink->eglglesctx.set_display);
+ eglglessink->eglglesctx.set_display = display;
+ GST_OBJECT_UNLOCK (eglglessink);
+ }
+}
+
+static gboolean
gst_eglglessink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
{
GstEglGlesSink *eglglessink;
@@ -2914,12 +3037,15 @@ gst_eglglessink_class_init (GstEglGlesSinkClass * klass)
gobject_class->finalize = gst_eglglessink_finalize;
gstelement_class->change_state = gst_eglglessink_change_state;
+ gstelement_class->set_context = gst_eglglessink_set_context;
gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_eglglessink_setcaps);
gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_eglglessink_getcaps);
gstbasesink_class->propose_allocation =
GST_DEBUG_FUNCPTR (gst_eglglessink_propose_allocation);
gstbasesink_class->prepare = GST_DEBUG_FUNCPTR (gst_eglglessink_prepare);
+ gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_eglglessink_query);
+ gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_eglglessink_event);
gstvideosink_class->show_frame =
GST_DEBUG_FUNCPTR (gst_eglglessink_show_frame);