mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 06:16:36 +00:00
glimagesink: implement as a bin
glupload ! glcolorconvert ! sink Some properties are manually forwarded. The rest are available using GstChildProxy. The two signals are forwarded as well.
This commit is contained in:
parent
b0600aca97
commit
8a0017e21d
3 changed files with 185 additions and 105 deletions
|
@ -3,6 +3,7 @@
|
||||||
* Copyright (C) 2003 Julien Moutte <julien@moutte.net>
|
* Copyright (C) 2003 Julien Moutte <julien@moutte.net>
|
||||||
* Copyright (C) 2005,2006,2007 David A. Schleef <ds@schleef.org>
|
* Copyright (C) 2005,2006,2007 David A. Schleef <ds@schleef.org>
|
||||||
* Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
@ -90,6 +91,7 @@
|
||||||
#include <gst/video/navigation.h>
|
#include <gst/video/navigation.h>
|
||||||
|
|
||||||
#include "gstglimagesink.h"
|
#include "gstglimagesink.h"
|
||||||
|
#include "gstglsinkbin.h"
|
||||||
|
|
||||||
#if GST_GL_HAVE_PLATFORM_EGL
|
#if GST_GL_HAVE_PLATFORM_EGL
|
||||||
#include <gst/gl/egl/gsteglimagememory.h>
|
#include <gst/gl/egl/gsteglimagememory.h>
|
||||||
|
@ -98,6 +100,112 @@
|
||||||
GST_DEBUG_CATEGORY (gst_debug_glimage_sink);
|
GST_DEBUG_CATEGORY (gst_debug_glimage_sink);
|
||||||
#define GST_CAT_DEFAULT gst_debug_glimage_sink
|
#define GST_CAT_DEFAULT gst_debug_glimage_sink
|
||||||
|
|
||||||
|
typedef GstGLSinkBin GstGLImageSinkBin;
|
||||||
|
typedef GstGLSinkBinClass GstGLImageSinkBinClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GstGLImageSinkBin, gst_gl_image_sink_bin, GST_TYPE_GL_SINK_BIN);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_BIN_0,
|
||||||
|
PROP_BIN_FORCE_ASPECT_RATIO,
|
||||||
|
PROP_BIN_LAST_SAMPLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SIGNAL_BIN_0,
|
||||||
|
SIGNAL_BIN_CLIENT_DRAW,
|
||||||
|
SIGNAL_BIN_CLIENT_RESHAPE,
|
||||||
|
SIGNAL_BIN_LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint gst_gl_image_sink_bin_signals[SIGNAL_BIN_LAST] = { 0 };
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_gl_image_sink_bin_set_property (GObject * object, guint prop_id,
|
||||||
|
const GValue * value, GParamSpec * param_spec)
|
||||||
|
{
|
||||||
|
g_object_set_property (G_OBJECT (GST_GL_SINK_BIN (object)->sink),
|
||||||
|
param_spec->name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_gl_image_sink_bin_get_property (GObject * object, guint prop_id,
|
||||||
|
GValue * value, GParamSpec * param_spec)
|
||||||
|
{
|
||||||
|
g_object_get_property (G_OBJECT (GST_GL_SINK_BIN (object)->sink),
|
||||||
|
param_spec->name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_on_client_reshape (GstGLImageSink * sink, GstGLContext * context,
|
||||||
|
guint width, guint height, gpointer data)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_signal_emit (data, gst_gl_image_sink_bin_signals[SIGNAL_BIN_CLIENT_RESHAPE],
|
||||||
|
0, context, width, height, &ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_on_client_draw (GstGLImageSink * sink, GstGLContext * context,
|
||||||
|
guint tex_id, guint width, guint height, gpointer data)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_signal_emit (data, gst_gl_image_sink_bin_signals[SIGNAL_BIN_CLIENT_DRAW], 0,
|
||||||
|
context, tex_id, width, height, &ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_gl_image_sink_bin_init (GstGLImageSinkBin * self)
|
||||||
|
{
|
||||||
|
GstGLImageSink *sink = g_object_new (GST_TYPE_GLIMAGE_SINK, NULL);
|
||||||
|
|
||||||
|
g_signal_connect (sink, "client-reshape", (GCallback) _on_client_reshape,
|
||||||
|
self);
|
||||||
|
g_signal_connect (sink, "client-draw", (GCallback) _on_client_draw, self);
|
||||||
|
|
||||||
|
gst_gl_sink_bin_finish_init_with_element (GST_GL_SINK_BIN (self),
|
||||||
|
GST_ELEMENT (sink));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_gl_image_sink_bin_class_init (GstGLImageSinkBinClass * klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->get_property = gst_gl_image_sink_bin_get_property;
|
||||||
|
gobject_class->set_property = gst_gl_image_sink_bin_set_property;
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_BIN_FORCE_ASPECT_RATIO,
|
||||||
|
g_param_spec_boolean ("force-aspect-ratio",
|
||||||
|
"Force aspect ratio",
|
||||||
|
"When enabled, scaling will respect original aspect ratio", TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_BIN_LAST_SAMPLE,
|
||||||
|
g_param_spec_boxed ("last-sample", "Last Sample",
|
||||||
|
"The last sample received in the sink", GST_TYPE_SAMPLE,
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
gst_gl_image_sink_bin_signals[SIGNAL_BIN_CLIENT_DRAW] =
|
||||||
|
g_signal_new ("client-draw", G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
|
||||||
|
G_TYPE_BOOLEAN, 4, GST_GL_TYPE_CONTEXT,
|
||||||
|
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
|
||||||
|
|
||||||
|
gst_gl_image_sink_bin_signals[SIGNAL_BIN_CLIENT_RESHAPE] =
|
||||||
|
g_signal_new ("client-reshape", G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
|
||||||
|
G_TYPE_BOOLEAN, 3, GST_GL_TYPE_CONTEXT, G_TYPE_UINT, G_TYPE_UINT);
|
||||||
|
}
|
||||||
|
|
||||||
#define GST_GLIMAGE_SINK_GET_LOCK(glsink) \
|
#define GST_GLIMAGE_SINK_GET_LOCK(glsink) \
|
||||||
(GST_GLIMAGE_SINK(glsink)->drawing_lock)
|
(GST_GLIMAGE_SINK(glsink)->drawing_lock)
|
||||||
#define GST_GLIMAGE_SINK_LOCK(glsink) \
|
#define GST_GLIMAGE_SINK_LOCK(glsink) \
|
||||||
|
@ -159,19 +267,12 @@ gst_glimage_sink_handle_events (GstVideoOverlay * overlay,
|
||||||
gboolean handle_events);
|
gboolean handle_events);
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_glimage_sink_template =
|
static GstStaticPadTemplate gst_glimage_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
|
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
|
||||||
(GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
|
(GST_CAPS_FEATURE_MEMORY_GL_MEMORY,
|
||||||
"RGBA") "; "
|
"RGBA"))
|
||||||
#if GST_GL_HAVE_PLATFORM_EGL
|
|
||||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES
|
|
||||||
(GST_CAPS_FEATURE_MEMORY_EGL_IMAGE, "RGBA") "; "
|
|
||||||
#endif
|
|
||||||
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))
|
|
||||||
);
|
);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -502,6 +603,46 @@ gst_glimage_sink_mouse_event_cb (GstGLWindow * window, char *event_name,
|
||||||
event_name, button, posx, posy);
|
event_name, button, posx, posy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_find_local_gl_context (GstGLImageSink * gl_sink)
|
||||||
|
{
|
||||||
|
GstQuery *query;
|
||||||
|
GstContext *context;
|
||||||
|
const GstStructure *s;
|
||||||
|
|
||||||
|
if (gl_sink->context)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
query = gst_query_new_context ("gst.gl.local_context");
|
||||||
|
if (!gl_sink->context
|
||||||
|
&& gst_gl_run_query (GST_ELEMENT (gl_sink), 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, &gl_sink->context,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!gl_sink->context
|
||||||
|
&& gst_gl_run_query (GST_ELEMENT (gl_sink), 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, &gl_sink->context,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_ERROR_OBJECT (gl_sink, "found local context %p", gl_sink->context);
|
||||||
|
|
||||||
|
gst_query_unref (query);
|
||||||
|
|
||||||
|
if (gl_sink->context)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_ensure_gl_setup (GstGLImageSink * gl_sink)
|
_ensure_gl_setup (GstGLImageSink * gl_sink)
|
||||||
{
|
{
|
||||||
|
@ -574,6 +715,8 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
|
||||||
} else
|
} else
|
||||||
GST_DEBUG_OBJECT (gl_sink, "Already have a context");
|
GST_DEBUG_OBJECT (gl_sink, "Already have a context");
|
||||||
|
|
||||||
|
_find_local_gl_context (gl_sink);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
context_creation_error:
|
context_creation_error:
|
||||||
|
@ -602,11 +745,39 @@ gst_glimage_sink_query (GstBaseSink * bsink, GstQuery * query)
|
||||||
switch (GST_QUERY_TYPE (query)) {
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
case GST_QUERY_CONTEXT:
|
case GST_QUERY_CONTEXT:
|
||||||
{
|
{
|
||||||
gboolean ret =
|
const gchar *context_type;
|
||||||
|
GstContext *context, *old_context;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
ret =
|
||||||
gst_gl_handle_context_query ((GstElement *) glimage_sink, query,
|
gst_gl_handle_context_query ((GstElement *) glimage_sink, query,
|
||||||
&glimage_sink->display, &glimage_sink->other_context);
|
&glimage_sink->display, &glimage_sink->other_context);
|
||||||
if (glimage_sink->display)
|
if (glimage_sink->display)
|
||||||
gst_gl_display_filter_gl_api (glimage_sink->display, SUPPORTED_GL_APIS);
|
gst_gl_display_filter_gl_api (glimage_sink->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,
|
||||||
|
glimage_sink->context, NULL);
|
||||||
|
gst_query_set_context (query, context);
|
||||||
|
gst_context_unref (context);
|
||||||
|
|
||||||
|
ret = glimage_sink->context != NULL;
|
||||||
|
}
|
||||||
|
GST_DEBUG_OBJECT (glimage_sink, "context query of type %s %i",
|
||||||
|
context_type, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
case GST_QUERY_DRAIN:
|
case GST_QUERY_DRAIN:
|
||||||
|
@ -623,7 +794,6 @@ gst_glimage_sink_query (GstBaseSink * bsink, GstQuery * query)
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
gst_buffer_replace (&glimage_sink->next_buffer, NULL);
|
gst_buffer_replace (&glimage_sink->next_buffer, NULL);
|
||||||
gst_gl_upload_release_buffer (glimage_sink->upload);
|
|
||||||
|
|
||||||
res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
||||||
break;
|
break;
|
||||||
|
@ -646,11 +816,6 @@ gst_glimage_sink_stop (GstBaseSink * bsink)
|
||||||
glimage_sink->pool = NULL;
|
glimage_sink->pool = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glimage_sink->gl_caps) {
|
|
||||||
gst_caps_unref (glimage_sink->gl_caps);
|
|
||||||
glimage_sink->gl_caps = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -711,16 +876,6 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
GST_GLIMAGE_SINK_UNLOCK (glimage_sink);
|
GST_GLIMAGE_SINK_UNLOCK (glimage_sink);
|
||||||
gst_buffer_replace (&glimage_sink->next_buffer, NULL);
|
gst_buffer_replace (&glimage_sink->next_buffer, NULL);
|
||||||
|
|
||||||
if (glimage_sink->upload) {
|
|
||||||
gst_object_unref (glimage_sink->upload);
|
|
||||||
glimage_sink->upload = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glimage_sink->convert) {
|
|
||||||
gst_object_unref (glimage_sink->convert);
|
|
||||||
glimage_sink->convert = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
glimage_sink->window_id = 0;
|
glimage_sink->window_id = 0;
|
||||||
/* but do not reset glimage_sink->new_window_id */
|
/* but do not reset glimage_sink->new_window_id */
|
||||||
|
|
||||||
|
@ -782,25 +937,11 @@ gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_glimage_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
gst_glimage_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
||||||
{
|
{
|
||||||
GstGLImageSink *gl_sink = GST_GLIMAGE_SINK (bsink);
|
|
||||||
GstCaps *tmp = NULL;
|
GstCaps *tmp = NULL;
|
||||||
GstCaps *result = NULL;
|
GstCaps *result = NULL;
|
||||||
|
|
||||||
tmp = gst_caps_from_string ("video/x-raw(memory:GLMemory),format=RGBA");
|
tmp = gst_caps_from_string ("video/x-raw(memory:GLMemory),format=RGBA");
|
||||||
|
|
||||||
result =
|
|
||||||
gst_gl_color_convert_transform_caps (gl_sink->context, GST_PAD_SRC, tmp,
|
|
||||||
NULL);
|
|
||||||
gst_caps_unref (tmp);
|
|
||||||
tmp = result;
|
|
||||||
GST_DEBUG_OBJECT (bsink, "convert returned caps %" GST_PTR_FORMAT, tmp);
|
|
||||||
|
|
||||||
result =
|
|
||||||
gst_gl_upload_transform_caps (gl_sink->context, GST_PAD_SRC, tmp, NULL);
|
|
||||||
gst_caps_unref (tmp);
|
|
||||||
tmp = result;
|
|
||||||
GST_DEBUG_OBJECT (bsink, "transfer returned caps %" GST_PTR_FORMAT, tmp);
|
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
|
result = gst_caps_intersect_full (filter, tmp, GST_CAPS_INTERSECT_FIRST);
|
||||||
gst_caps_unref (tmp);
|
gst_caps_unref (tmp);
|
||||||
|
@ -824,8 +965,6 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
gint display_par_n, display_par_d;
|
gint display_par_n, display_par_d;
|
||||||
guint display_ratio_num, display_ratio_den;
|
guint display_ratio_num, display_ratio_den;
|
||||||
GstVideoInfo vinfo;
|
GstVideoInfo vinfo;
|
||||||
GstCapsFeatures *gl_features;
|
|
||||||
GstCaps *uploaded_caps;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (bsink, "set caps with %" GST_PTR_FORMAT, caps);
|
GST_DEBUG_OBJECT (bsink, "set caps with %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
@ -888,38 +1027,6 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
if (!_ensure_gl_setup (glimage_sink))
|
if (!_ensure_gl_setup (glimage_sink))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (glimage_sink->upload)
|
|
||||||
gst_object_unref (glimage_sink->upload);
|
|
||||||
glimage_sink->upload = gst_gl_upload_new (glimage_sink->context);
|
|
||||||
|
|
||||||
gl_features =
|
|
||||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
|
|
||||||
|
|
||||||
uploaded_caps = gst_caps_copy (caps);
|
|
||||||
gst_caps_set_features (uploaded_caps, 0,
|
|
||||||
gst_caps_features_copy (gl_features));
|
|
||||||
gst_gl_upload_set_caps (glimage_sink->upload, caps, uploaded_caps);
|
|
||||||
|
|
||||||
if (glimage_sink->gl_caps)
|
|
||||||
gst_caps_unref (glimage_sink->gl_caps);
|
|
||||||
glimage_sink->gl_caps = gst_caps_copy (caps);
|
|
||||||
gst_caps_set_simple (glimage_sink->gl_caps, "format", G_TYPE_STRING, "RGBA",
|
|
||||||
NULL);
|
|
||||||
gst_caps_set_features (glimage_sink->gl_caps, 0,
|
|
||||||
gst_caps_features_copy (gl_features));
|
|
||||||
|
|
||||||
if (glimage_sink->convert)
|
|
||||||
gst_object_unref (glimage_sink->convert);
|
|
||||||
glimage_sink->convert = gst_gl_color_convert_new (glimage_sink->context);
|
|
||||||
if (!gst_gl_color_convert_set_caps (glimage_sink->convert, uploaded_caps,
|
|
||||||
glimage_sink->gl_caps)) {
|
|
||||||
gst_caps_unref (uploaded_caps);
|
|
||||||
gst_caps_features_free (gl_features);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
gst_caps_unref (uploaded_caps);
|
|
||||||
gst_caps_features_free (gl_features);
|
|
||||||
|
|
||||||
glimage_sink->caps_change = TRUE;
|
glimage_sink->caps_change = TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -929,9 +1036,7 @@ static GstFlowReturn
|
||||||
gst_glimage_sink_prepare (GstBaseSink * bsink, GstBuffer * buf)
|
gst_glimage_sink_prepare (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstGLImageSink *glimage_sink;
|
GstGLImageSink *glimage_sink;
|
||||||
GstBuffer *uploaded_buffer, *next_buffer = NULL;
|
|
||||||
GstVideoFrame gl_frame;
|
GstVideoFrame gl_frame;
|
||||||
GstVideoInfo gl_info;
|
|
||||||
|
|
||||||
glimage_sink = GST_GLIMAGE_SINK (bsink);
|
glimage_sink = GST_GLIMAGE_SINK (bsink);
|
||||||
|
|
||||||
|
@ -945,31 +1050,14 @@ gst_glimage_sink_prepare (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
if (!_ensure_gl_setup (glimage_sink))
|
if (!_ensure_gl_setup (glimage_sink))
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
|
||||||
if (gst_gl_upload_perform_with_buffer (glimage_sink->upload, buf,
|
if (!gst_video_frame_map (&gl_frame, &glimage_sink->info, buf,
|
||||||
&uploaded_buffer) != GST_GL_UPLOAD_DONE)
|
|
||||||
goto upload_failed;
|
|
||||||
|
|
||||||
if (!(next_buffer =
|
|
||||||
gst_gl_color_convert_perform (glimage_sink->convert,
|
|
||||||
uploaded_buffer))) {
|
|
||||||
gst_buffer_unref (uploaded_buffer);
|
|
||||||
goto upload_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_video_info_from_caps (&gl_info, glimage_sink->gl_caps);
|
|
||||||
|
|
||||||
if (!gst_video_frame_map (&gl_frame, &gl_info, next_buffer,
|
|
||||||
GST_MAP_READ | GST_MAP_GL)) {
|
GST_MAP_READ | GST_MAP_GL)) {
|
||||||
gst_buffer_unref (uploaded_buffer);
|
|
||||||
gst_buffer_unref (next_buffer);
|
|
||||||
goto upload_failed;
|
goto upload_failed;
|
||||||
}
|
}
|
||||||
gst_buffer_unref (uploaded_buffer);
|
|
||||||
|
|
||||||
glimage_sink->next_tex = *(guint *) gl_frame.data[0];
|
glimage_sink->next_tex = *(guint *) gl_frame.data[0];
|
||||||
|
|
||||||
gst_buffer_replace (&glimage_sink->next_buffer, next_buffer);
|
gst_buffer_replace (&glimage_sink->next_buffer, buf);
|
||||||
gst_buffer_unref (next_buffer);
|
|
||||||
|
|
||||||
gst_video_frame_unmap (&gl_frame);
|
gst_video_frame_unmap (&gl_frame);
|
||||||
|
|
||||||
|
@ -1027,7 +1115,6 @@ gst_glimage_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
||||||
if (g_atomic_int_get (&glimage_sink->to_quit) != 0) {
|
if (g_atomic_int_get (&glimage_sink->to_quit) != 0) {
|
||||||
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
|
||||||
("%s", gst_gl_context_get_error ()), (NULL));
|
("%s", gst_gl_context_get_error ()), (NULL));
|
||||||
gst_gl_upload_release_buffer (glimage_sink->upload);
|
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1036,14 +1123,12 @@ gst_glimage_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
redisplay_failed:
|
redisplay_failed:
|
||||||
{
|
{
|
||||||
gst_gl_upload_release_buffer (glimage_sink->upload);
|
|
||||||
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
|
||||||
("%s", gst_gl_context_get_error ()), (NULL));
|
("%s", gst_gl_context_get_error ()), (NULL));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_glimage_sink_video_overlay_init (GstVideoOverlayInterface * iface)
|
gst_glimage_sink_video_overlay_init (GstVideoOverlayInterface * iface)
|
||||||
{
|
{
|
||||||
|
@ -1052,7 +1137,6 @@ gst_glimage_sink_video_overlay_init (GstVideoOverlayInterface * iface)
|
||||||
iface->expose = gst_glimage_sink_expose;
|
iface->expose = gst_glimage_sink_expose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_glimage_sink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
|
gst_glimage_sink_set_window_handle (GstVideoOverlay * overlay, guintptr id)
|
||||||
{
|
{
|
||||||
|
@ -1161,8 +1245,6 @@ gst_glimage_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
|
||||||
gst_query_add_allocation_pool (query, glimage_sink->pool, size, 2, 0);
|
gst_query_add_allocation_pool (query, glimage_sink->pool, size, 2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_gl_upload_propose_allocation (glimage_sink->upload, NULL, query);
|
|
||||||
|
|
||||||
if (glimage_sink->context->gl_vtable->FenceSync)
|
if (glimage_sink->context->gl_vtable->FenceSync)
|
||||||
gst_query_add_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, 0);
|
gst_query_add_allocation_meta (query, GST_GL_SYNC_META_API_TYPE, 0);
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,6 @@ struct _GstGLImageSink
|
||||||
|
|
||||||
//caps
|
//caps
|
||||||
GstVideoInfo info;
|
GstVideoInfo info;
|
||||||
GstCaps *gl_caps;
|
|
||||||
|
|
||||||
GstGLDisplay *display;
|
GstGLDisplay *display;
|
||||||
GstGLContext *context;
|
GstGLContext *context;
|
||||||
|
@ -69,8 +68,6 @@ struct _GstGLImageSink
|
||||||
gboolean handle_events;
|
gboolean handle_events;
|
||||||
gboolean ignore_alpha;
|
gboolean ignore_alpha;
|
||||||
|
|
||||||
GstGLUpload *upload;
|
|
||||||
GstGLColorConvert *convert;
|
|
||||||
guint next_tex;
|
guint next_tex;
|
||||||
GstBuffer *next_buffer;
|
GstBuffer *next_buffer;
|
||||||
|
|
||||||
|
@ -102,6 +99,7 @@ struct _GstGLImageSinkClass
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_glimage_sink_get_type(void);
|
GType gst_glimage_sink_get_type(void);
|
||||||
|
GType gst_gl_image_sink_bin_get_type(void);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ plugin_init (GstPlugin * plugin)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!gst_element_register (plugin, "glimagesink",
|
if (!gst_element_register (plugin, "glimagesink",
|
||||||
GST_RANK_SECONDARY, GST_TYPE_GLIMAGE_SINK)) {
|
GST_RANK_SECONDARY, gst_gl_image_sink_bin_get_type ())) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue