mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 14:36:24 +00:00
caopengllayersink: implement as a bin like glimagesink
This commit is contained in:
parent
35476a4cb4
commit
95756a5413
3 changed files with 150 additions and 165 deletions
|
@ -57,8 +57,6 @@ struct _GstCAOpenGLLayerSink
|
||||||
GstGLContext *other_context;
|
GstGLContext *other_context;
|
||||||
GstGLContext *context;
|
GstGLContext *context;
|
||||||
|
|
||||||
GstGLUpload *upload;
|
|
||||||
GstGLColorConvert *convert;
|
|
||||||
guint next_tex;
|
guint next_tex;
|
||||||
GstBuffer *next_buffer;
|
GstBuffer *next_buffer;
|
||||||
|
|
||||||
|
@ -92,6 +90,7 @@ struct _GstCAOpenGLLayerSinkClass
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_ca_opengl_layer_sink_get_type(void);
|
GType gst_ca_opengl_layer_sink_get_type(void);
|
||||||
|
GType gst_ca_opengl_layer_sink_bin_get_type (void);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,92 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "caopengllayersink.h"
|
#include "caopengllayersink.h"
|
||||||
|
#include "gstglsinkbin.h"
|
||||||
#include <QuartzCore/QuartzCore.h>
|
#include <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY (gst_debug_ca_sink);
|
GST_DEBUG_CATEGORY (gst_debug_ca_sink);
|
||||||
#define GST_CAT_DEFAULT gst_debug_ca_sink
|
#define GST_CAT_DEFAULT gst_debug_ca_sink
|
||||||
|
|
||||||
|
typedef GstGLSinkBin GstCAOpenGLLayerSinkBin;
|
||||||
|
typedef GstGLSinkBinClass GstCAOpenGLLayerSinkBinClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (GstCAOpenGLLayerSinkBin, gst_ca_opengl_layer_sink_bin,
|
||||||
|
GST_TYPE_GL_SINK_BIN);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_BIN_0,
|
||||||
|
PROP_BIN_QOS,
|
||||||
|
PROP_BIN_FORCE_ASPECT_RATIO,
|
||||||
|
PROP_BIN_LAST_SAMPLE,
|
||||||
|
PROP_BIN_LAYER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_on_notify_layer (GObject * object, GParamSpec *pspec, gpointer user_data)
|
||||||
|
{
|
||||||
|
GstCAOpenGLLayerSinkBin *self = user_data;
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (self), "layer");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ca_opengl_layer_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_ca_opengl_layer_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 void
|
||||||
|
gst_ca_opengl_layer_sink_bin_init (GstCAOpenGLLayerSinkBin * self)
|
||||||
|
{
|
||||||
|
GstGLCAOpenGLLayer *sink = g_object_new (GST_TYPE_CA_OPENGL_LAYER_SINK, NULL);
|
||||||
|
|
||||||
|
g_signal_connect (sink, "notify::layer", G_CALLBACK (_on_notify_layer), self);
|
||||||
|
|
||||||
|
gst_gl_sink_bin_finish_init_with_element (GST_GL_SINK_BIN (self),
|
||||||
|
GST_ELEMENT (sink));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_ca_opengl_layer_sink_bin_class_init (GstCAOpenGLLayerSinkBinClass * klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->get_property = gst_ca_opengl_layer_sink_bin_get_property;
|
||||||
|
gobject_class->set_property = gst_ca_opengl_layer_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));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_BIN_LAYER,
|
||||||
|
g_param_spec_pointer ("layer", "CAOpenGLLayer",
|
||||||
|
"OpenGL Core Animation layer",
|
||||||
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
|
g_object_class_install_property (gobject_class, PROP_BIN_QOS,
|
||||||
|
g_param_spec_boolean ("qos", "Quality of Service",
|
||||||
|
"Generate Quality-of-Service events upstream", TRUE,
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
}
|
||||||
|
|
||||||
#define GST_CA_OPENGL_LAYER_SINK_GET_LOCK(glsink) \
|
#define GST_CA_OPENGL_LAYER_SINK_GET_LOCK(glsink) \
|
||||||
(GST_CA_OPENGL_LAYER_SINK(glsink)->drawing_lock)
|
(GST_CA_OPENGL_LAYER_SINK(glsink)->drawing_lock)
|
||||||
#define GST_CA_OPENGL_LAYER_SINK_LOCK(glsink) \
|
#define GST_CA_OPENGL_LAYER_SINK_LOCK(glsink) \
|
||||||
|
@ -88,10 +169,7 @@ static GstStaticPadTemplate gst_ca_opengl_layer_sink_template =
|
||||||
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"))
|
||||||
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
|
||||||
|
@ -320,11 +398,40 @@ gst_ca_opengl_layer_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 *) ca_sink, query,
|
gst_gl_handle_context_query ((GstElement *) ca_sink, query,
|
||||||
&ca_sink->display, &ca_sink->other_context);
|
&ca_sink->display, &ca_sink->other_context);
|
||||||
if (ca_sink->display)
|
if (ca_sink->display)
|
||||||
gst_gl_display_filter_gl_api (ca_sink->display, SUPPORTED_GL_APIS);
|
gst_gl_display_filter_gl_api (ca_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,
|
||||||
|
ca_sink->context, NULL);
|
||||||
|
gst_query_set_context (query, context);
|
||||||
|
gst_context_unref (context);
|
||||||
|
|
||||||
|
ret = ca_sink->context != NULL;
|
||||||
|
}
|
||||||
|
GST_DEBUG_OBJECT (ca_sink, "context query of type %s %i",
|
||||||
|
context_type, ret);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
case GST_QUERY_DRAIN:
|
case GST_QUERY_DRAIN:
|
||||||
|
@ -341,17 +448,15 @@ gst_ca_opengl_layer_sink_query (GstBaseSink * bsink, GstQuery * query)
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
|
||||||
gst_buffer_replace (&ca_sink->next_buffer, NULL);
|
gst_buffer_replace (&ca_sink->next_buffer, NULL);
|
||||||
gst_gl_upload_release_buffer (ca_sink->upload);
|
|
||||||
|
|
||||||
res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
res = GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return GST_BASE_SINK_CLASS (parent_class)->query (bsink, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -430,16 +535,6 @@ gst_ca_opengl_layer_sink_change_state (GstElement * element, GstStateChange tran
|
||||||
GST_CA_OPENGL_LAYER_SINK_UNLOCK (ca_sink);
|
GST_CA_OPENGL_LAYER_SINK_UNLOCK (ca_sink);
|
||||||
gst_buffer_replace (&ca_sink->next_buffer, NULL);
|
gst_buffer_replace (&ca_sink->next_buffer, NULL);
|
||||||
|
|
||||||
if (ca_sink->upload) {
|
|
||||||
gst_object_unref (ca_sink->upload);
|
|
||||||
ca_sink->upload = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ca_sink->convert) {
|
|
||||||
gst_object_unref (ca_sink->convert);
|
|
||||||
ca_sink->convert = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ca_sink->pool) {
|
if (ca_sink->pool) {
|
||||||
gst_buffer_pool_set_active (ca_sink->pool, FALSE);
|
gst_buffer_pool_set_active (ca_sink->pool, FALSE);
|
||||||
gst_object_unref (ca_sink->pool);
|
gst_object_unref (ca_sink->pool);
|
||||||
|
@ -502,10 +597,6 @@ gst_ca_opengl_layer_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;
|
||||||
GstStructure *structure;
|
|
||||||
GstBufferPool *newpool, *oldpool;
|
|
||||||
GstCapsFeatures *gl_features;
|
|
||||||
GstCaps *uploaded_caps;
|
|
||||||
|
|
||||||
GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
|
GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
@ -562,56 +653,6 @@ gst_ca_opengl_layer_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
if (!_ensure_gl_setup (ca_sink))
|
if (!_ensure_gl_setup (ca_sink))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
newpool = gst_gl_buffer_pool_new (ca_sink->context);
|
|
||||||
structure = gst_buffer_pool_get_config (newpool);
|
|
||||||
gst_buffer_pool_config_set_params (structure, caps, vinfo.size, 2, 0);
|
|
||||||
gst_buffer_pool_set_config (newpool, structure);
|
|
||||||
|
|
||||||
oldpool = ca_sink->pool;
|
|
||||||
/* we don't activate the pool yet, this will be done by downstream after it
|
|
||||||
* has configured the pool. If downstream does not want our pool we will
|
|
||||||
* activate it when we render into it */
|
|
||||||
ca_sink->pool = newpool;
|
|
||||||
|
|
||||||
/* unref the old sink */
|
|
||||||
if (oldpool) {
|
|
||||||
/* we don't deactivate, some elements might still be using it, it will
|
|
||||||
* be deactivated when the last ref is gone */
|
|
||||||
gst_object_unref (oldpool);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ca_sink->upload)
|
|
||||||
gst_object_unref (ca_sink->upload);
|
|
||||||
ca_sink->upload = gst_gl_upload_new (ca_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 (ca_sink->upload, caps, uploaded_caps);
|
|
||||||
|
|
||||||
if (ca_sink->gl_caps)
|
|
||||||
gst_caps_unref (ca_sink->gl_caps);
|
|
||||||
ca_sink->gl_caps = gst_caps_copy (caps);
|
|
||||||
gst_caps_set_simple (ca_sink->gl_caps, "format", G_TYPE_STRING, "RGBA",
|
|
||||||
NULL);
|
|
||||||
gst_caps_set_features (ca_sink->gl_caps, 0,
|
|
||||||
gst_caps_features_copy (gl_features));
|
|
||||||
|
|
||||||
if (ca_sink->convert)
|
|
||||||
gst_object_unref (ca_sink->convert);
|
|
||||||
ca_sink->convert = gst_gl_color_convert_new (ca_sink->context);
|
|
||||||
if (!gst_gl_color_convert_set_caps (ca_sink->convert, uploaded_caps,
|
|
||||||
ca_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);
|
|
||||||
|
|
||||||
ca_sink->caps_change = TRUE;
|
ca_sink->caps_change = TRUE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -621,9 +662,7 @@ static GstFlowReturn
|
||||||
gst_ca_opengl_layer_sink_prepare (GstBaseSink * bsink, GstBuffer * buf)
|
gst_ca_opengl_layer_sink_prepare (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstCAOpenGLLayerSink *ca_sink;
|
GstCAOpenGLLayerSink *ca_sink;
|
||||||
GstBuffer *uploaded_buffer, *next_buffer = NULL;
|
|
||||||
GstVideoFrame gl_frame;
|
GstVideoFrame gl_frame;
|
||||||
GstVideoInfo gl_info;
|
|
||||||
|
|
||||||
ca_sink = GST_CA_OPENGL_LAYER_SINK (bsink);
|
ca_sink = GST_CA_OPENGL_LAYER_SINK (bsink);
|
||||||
|
|
||||||
|
@ -637,31 +676,14 @@ gst_ca_opengl_layer_sink_prepare (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
if (!_ensure_gl_setup (ca_sink))
|
if (!_ensure_gl_setup (ca_sink))
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
|
|
||||||
if (gst_gl_upload_perform_with_buffer (ca_sink->upload, buf,
|
if (!gst_video_frame_map (&gl_frame, &ca_sink->info, buf,
|
||||||
&uploaded_buffer) != GST_GL_UPLOAD_DONE)
|
|
||||||
goto upload_failed;
|
|
||||||
|
|
||||||
if (!(next_buffer =
|
|
||||||
gst_gl_color_convert_perform (ca_sink->convert,
|
|
||||||
uploaded_buffer))) {
|
|
||||||
gst_buffer_unref (uploaded_buffer);
|
|
||||||
goto upload_failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_video_info_from_caps (&gl_info, ca_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);
|
|
||||||
|
|
||||||
ca_sink->next_tex = *(guint *) gl_frame.data[0];
|
ca_sink->next_tex = *(guint *) gl_frame.data[0];
|
||||||
|
|
||||||
gst_buffer_replace (&ca_sink->next_buffer, next_buffer);
|
gst_buffer_replace (&ca_sink->next_buffer, buf);
|
||||||
gst_buffer_unref (next_buffer);
|
|
||||||
|
|
||||||
gst_video_frame_unmap (&gl_frame);
|
gst_video_frame_unmap (&gl_frame);
|
||||||
|
|
||||||
|
@ -712,7 +734,6 @@ gst_ca_opengl_layer_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
||||||
if (g_atomic_int_get (&ca_sink->to_quit) != 0) {
|
if (g_atomic_int_get (&ca_sink->to_quit) != 0) {
|
||||||
GST_ELEMENT_ERROR (ca_sink, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (ca_sink, RESOURCE, NOT_FOUND,
|
||||||
("%s", gst_gl_context_get_error ()), (NULL));
|
("%s", gst_gl_context_get_error ()), (NULL));
|
||||||
gst_gl_upload_release_buffer (ca_sink->upload);
|
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,16 +744,10 @@ static gboolean
|
||||||
gst_ca_opengl_layer_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
|
gst_ca_opengl_layer_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
|
||||||
{
|
{
|
||||||
GstCAOpenGLLayerSink *ca_sink = GST_CA_OPENGL_LAYER_SINK (bsink);
|
GstCAOpenGLLayerSink *ca_sink = GST_CA_OPENGL_LAYER_SINK (bsink);
|
||||||
GstBufferPool *pool;
|
|
||||||
GstStructure *config;
|
GstStructure *config;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
guint size;
|
guint size;
|
||||||
gboolean need_pool;
|
gboolean need_pool;
|
||||||
GstStructure *gl_context;
|
|
||||||
gchar *platform, *gl_apis;
|
|
||||||
gpointer handle;
|
|
||||||
GstAllocator *allocator = NULL;
|
|
||||||
GstAllocationParams params;
|
|
||||||
|
|
||||||
if (!_ensure_gl_setup (ca_sink))
|
if (!_ensure_gl_setup (ca_sink))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -742,79 +757,50 @@ gst_ca_opengl_layer_sink_propose_allocation (GstBaseSink * bsink, GstQuery * que
|
||||||
if (caps == NULL)
|
if (caps == NULL)
|
||||||
goto no_caps;
|
goto no_caps;
|
||||||
|
|
||||||
if ((pool = ca_sink->pool))
|
if (need_pool) {
|
||||||
gst_object_ref (pool);
|
|
||||||
|
|
||||||
if (pool != NULL) {
|
|
||||||
GstCaps *pcaps;
|
|
||||||
|
|
||||||
/* we had a pool, check caps */
|
|
||||||
GST_DEBUG_OBJECT (ca_sink, "check existing pool caps");
|
|
||||||
config = gst_buffer_pool_get_config (pool);
|
|
||||||
gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL);
|
|
||||||
|
|
||||||
if (!gst_caps_is_equal (caps, pcaps)) {
|
|
||||||
GST_DEBUG_OBJECT (ca_sink, "pool has different caps");
|
|
||||||
/* different caps, we can't use this pool */
|
|
||||||
gst_object_unref (pool);
|
|
||||||
pool = NULL;
|
|
||||||
}
|
|
||||||
gst_structure_free (config);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pool == NULL && need_pool) {
|
|
||||||
GstVideoInfo info;
|
GstVideoInfo info;
|
||||||
|
|
||||||
if (!gst_video_info_from_caps (&info, caps))
|
if (!gst_video_info_from_caps (&info, caps))
|
||||||
goto invalid_caps;
|
goto invalid_caps;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (ca_sink, "create new pool");
|
|
||||||
pool = gst_gl_buffer_pool_new (ca_sink->context);
|
|
||||||
|
|
||||||
/* the normal size of a frame */
|
/* the normal size of a frame */
|
||||||
size = info.size;
|
size = info.size;
|
||||||
|
|
||||||
config = gst_buffer_pool_get_config (pool);
|
if (ca_sink->pool) {
|
||||||
|
GstCaps *pcaps;
|
||||||
|
|
||||||
|
/* we had a pool, check caps */
|
||||||
|
GST_DEBUG_OBJECT (ca_sink, "check existing pool caps");
|
||||||
|
config = gst_buffer_pool_get_config (ca_sink->pool);
|
||||||
|
gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL);
|
||||||
|
|
||||||
|
if (!gst_caps_is_equal (caps, pcaps)) {
|
||||||
|
GST_DEBUG_OBJECT (ca_sink, "pool has different caps");
|
||||||
|
/* different caps, we can't use this pool */
|
||||||
|
gst_object_unref (ca_sink->pool);
|
||||||
|
ca_sink->pool = NULL;
|
||||||
|
}
|
||||||
|
gst_structure_free (config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ca_sink->pool == NULL) {
|
||||||
|
GST_DEBUG_OBJECT (ca_sink, "create new pool");
|
||||||
|
|
||||||
|
ca_sink->pool = gst_gl_buffer_pool_new (ca_sink->context);
|
||||||
|
config = gst_buffer_pool_get_config (ca_sink->pool);
|
||||||
gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
|
gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
|
||||||
if (!gst_buffer_pool_set_config (pool, config))
|
|
||||||
|
if (!gst_buffer_pool_set_config (ca_sink->pool, config))
|
||||||
goto config_failed;
|
goto config_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we need at least 2 buffer because we hold on to the last one */
|
/* we need at least 2 buffer because we hold on to the last one */
|
||||||
if (pool) {
|
gst_query_add_allocation_pool (query, ca_sink->pool, size, 2, 0);
|
||||||
gst_query_add_allocation_pool (query, pool, size, 2, 0);
|
|
||||||
gst_object_unref (pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we also support various metadata */
|
|
||||||
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, 0);
|
|
||||||
if (ca_sink->context->gl_vtable->FenceSync)
|
if (ca_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);
|
||||||
|
|
||||||
gl_apis =
|
|
||||||
gst_gl_api_to_string (gst_gl_context_get_gl_api (ca_sink->context));
|
|
||||||
platform =
|
|
||||||
gst_gl_platform_to_string (gst_gl_context_get_gl_platform
|
|
||||||
(ca_sink->context));
|
|
||||||
handle = (gpointer) gst_gl_context_get_gl_context (ca_sink->context);
|
|
||||||
|
|
||||||
gl_context =
|
|
||||||
gst_structure_new ("GstVideoGLTextureUploadMeta", "gst.gl.GstGLContext",
|
|
||||||
GST_GL_TYPE_CONTEXT, ca_sink->context, "gst.gl.context.handle",
|
|
||||||
G_TYPE_POINTER, handle, "gst.gl.context.type", G_TYPE_STRING, platform,
|
|
||||||
"gst.gl.context.apis", G_TYPE_STRING, gl_apis, NULL);
|
|
||||||
gst_query_add_allocation_meta (query,
|
|
||||||
GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, gl_context);
|
|
||||||
|
|
||||||
g_free (gl_apis);
|
|
||||||
g_free (platform);
|
|
||||||
gst_structure_free (gl_context);
|
|
||||||
|
|
||||||
gst_allocation_params_init (¶ms);
|
|
||||||
|
|
||||||
allocator = gst_allocator_find (GST_GL_MEMORY_ALLOCATOR);
|
|
||||||
gst_query_add_allocation_param (query, allocator, ¶ms);
|
|
||||||
gst_object_unref (allocator);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
|
|
||||||
#if GST_GL_HAVE_WINDOW_COCOA
|
#if GST_GL_HAVE_WINDOW_COCOA
|
||||||
/* avoid including Cocoa/CoreFoundation from a C file... */
|
/* avoid including Cocoa/CoreFoundation from a C file... */
|
||||||
extern GType gst_ca_opengl_layer_sink_get_type (void);
|
extern GType gst_ca_opengl_layer_sink_bin_get_type (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_EGL_RPI
|
#ifdef USE_EGL_RPI
|
||||||
|
@ -251,7 +251,7 @@ plugin_init (GstPlugin * plugin)
|
||||||
#endif /* GST_GL_HAVE_OPENGL */
|
#endif /* GST_GL_HAVE_OPENGL */
|
||||||
#if GST_GL_HAVE_WINDOW_COCOA
|
#if GST_GL_HAVE_WINDOW_COCOA
|
||||||
if (!gst_element_register (plugin, "caopengllayersink",
|
if (!gst_element_register (plugin, "caopengllayersink",
|
||||||
GST_RANK_NONE, gst_ca_opengl_layer_sink_get_type ())) {
|
GST_RANK_NONE, gst_ca_opengl_layer_sink_bin_get_type ())) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue