mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-08 03:32:18 +00:00
[542/906] GstGLMixer: add allocation and bufferpool methods
based off GstBaseTransform
This commit is contained in:
parent
3f174671ec
commit
83401761eb
2 changed files with 201 additions and 8 deletions
|
@ -66,6 +66,20 @@ enum
|
||||||
PROP_PAD_0
|
PROP_PAD_0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define GST_GL_MIXER_GET_PRIVATE(obj) \
|
||||||
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_GL_MIXER, GstGLMixerPrivate))
|
||||||
|
|
||||||
|
struct _GstGLMixerPrivate
|
||||||
|
{
|
||||||
|
gboolean negotiated;
|
||||||
|
|
||||||
|
GstBufferPool *pool;
|
||||||
|
gboolean pool_active;
|
||||||
|
GstAllocator *allocator;
|
||||||
|
GstAllocationParams params;
|
||||||
|
GstQuery *query;
|
||||||
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstGLMixerPad, gst_gl_mixer_pad, GST_TYPE_PAD);
|
G_DEFINE_TYPE (GstGLMixerPad, gst_gl_mixer_pad, GST_TYPE_PAD);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -207,6 +221,7 @@ gst_gl_mixer_update_src_caps (GstGLMixer * mix)
|
||||||
|
|
||||||
GST_GL_MIXER_UNLOCK (mix);
|
GST_GL_MIXER_UNLOCK (mix);
|
||||||
ret = gst_gl_mixer_src_setcaps (mix->srcpad, mix, caps);
|
ret = gst_gl_mixer_src_setcaps (mix->srcpad, mix, caps);
|
||||||
|
// ret = gst_pad_set_caps (mix->srcpad, caps);
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
} else {
|
} else {
|
||||||
GST_GL_MIXER_UNLOCK (mix);
|
GST_GL_MIXER_UNLOCK (mix);
|
||||||
|
@ -334,6 +349,8 @@ gst_gl_mixer_pad_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
GST_TRACE ("QUERY %d", GST_QUERY_TYPE (query));
|
||||||
|
|
||||||
switch (GST_QUERY_TYPE (query)) {
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
case GST_QUERY_CAPS:
|
case GST_QUERY_CAPS:
|
||||||
{
|
{
|
||||||
|
@ -360,6 +377,7 @@ gst_gl_mixer_pad_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
||||||
ret = gst_pad_query_default (pad, parent, query);
|
ret = gst_pad_query_default (pad, parent, query);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,6 +440,14 @@ static gboolean gst_gl_mixer_query_duration (GstGLMixer * mix,
|
||||||
GstQuery * query);
|
GstQuery * query);
|
||||||
static gboolean gst_gl_mixer_query_latency (GstGLMixer * mix, GstQuery * query);
|
static gboolean gst_gl_mixer_query_latency (GstGLMixer * mix, GstQuery * query);
|
||||||
|
|
||||||
|
static gboolean gst_gl_mixer_do_bufferpool (GstGLMixer * mix,
|
||||||
|
GstCaps * outcaps);
|
||||||
|
static gboolean gst_gl_mixer_decide_allocation (GstGLMixer * mix,
|
||||||
|
GstQuery * query);
|
||||||
|
static gboolean gst_gl_mixer_set_allocation (GstGLMixer * mix,
|
||||||
|
GstBufferPool * pool, GstAllocator * allocator,
|
||||||
|
GstAllocationParams * params, GstQuery * query);
|
||||||
|
|
||||||
static gint64 gst_gl_mixer_do_qos (GstGLMixer * mix, GstClockTime timestamp);
|
static gint64 gst_gl_mixer_do_qos (GstGLMixer * mix, GstClockTime timestamp);
|
||||||
static void gst_gl_mixer_update_qos (GstGLMixer * mix, gdouble proportion,
|
static void gst_gl_mixer_update_qos (GstGLMixer * mix, gdouble proportion,
|
||||||
GstClockTimeDiff diff, GstClockTime timestamp);
|
GstClockTimeDiff diff, GstClockTime timestamp);
|
||||||
|
@ -484,6 +510,8 @@ gst_gl_mixer_class_init (GstGLMixerClass * klass)
|
||||||
gobject_class = (GObjectClass *) klass;
|
gobject_class = (GObjectClass *) klass;
|
||||||
element_class = GST_ELEMENT_CLASS (klass);
|
element_class = GST_ELEMENT_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (GstGLMixerPrivate));
|
||||||
|
|
||||||
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_gl_mixer_finalize);
|
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_gl_mixer_finalize);
|
||||||
|
|
||||||
gobject_class->get_property = gst_gl_mixer_get_property;
|
gobject_class->get_property = gst_gl_mixer_get_property;
|
||||||
|
@ -517,6 +545,7 @@ gst_gl_mixer_collect_free (GstGLMixerCollect * mixcol)
|
||||||
static void
|
static void
|
||||||
gst_gl_mixer_reset (GstGLMixer * mix)
|
gst_gl_mixer_reset (GstGLMixer * mix)
|
||||||
{
|
{
|
||||||
|
GstGLMixerPrivate *priv = mix->priv;
|
||||||
GSList *l;
|
GSList *l;
|
||||||
|
|
||||||
gst_video_info_init (&mix->info);
|
gst_video_info_init (&mix->info);
|
||||||
|
@ -540,6 +569,8 @@ gst_gl_mixer_reset (GstGLMixer * mix)
|
||||||
|
|
||||||
mix->newseg_pending = TRUE;
|
mix->newseg_pending = TRUE;
|
||||||
mix->flush_stop_pending = FALSE;
|
mix->flush_stop_pending = FALSE;
|
||||||
|
|
||||||
|
priv->negotiated = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -547,6 +578,8 @@ gst_gl_mixer_init (GstGLMixer * mix)
|
||||||
{
|
{
|
||||||
GstElementClass *klass = GST_ELEMENT_GET_CLASS (mix);
|
GstElementClass *klass = GST_ELEMENT_GET_CLASS (mix);
|
||||||
|
|
||||||
|
mix->priv = GST_GL_MIXER_GET_PRIVATE (mix);
|
||||||
|
|
||||||
mix->srcpad =
|
mix->srcpad =
|
||||||
gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
|
gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
|
||||||
"src"), "src");
|
"src"), "src");
|
||||||
|
@ -927,12 +960,152 @@ gst_gl_mixer_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_gl_mixer_decide_allocation (GstGLMixer * mix, GstQuery * query)
|
||||||
|
{
|
||||||
|
GstBufferPool *pool = NULL;
|
||||||
|
GstStructure *config;
|
||||||
|
GstCaps *caps;
|
||||||
|
guint min, max, size;
|
||||||
|
gboolean update_pool;
|
||||||
|
|
||||||
|
gst_query_parse_allocation (query, &caps, NULL);
|
||||||
|
|
||||||
|
if (gst_query_get_n_allocation_pools (query) > 0) {
|
||||||
|
gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
|
||||||
|
|
||||||
|
update_pool = TRUE;
|
||||||
|
} else {
|
||||||
|
GstVideoInfo vinfo;
|
||||||
|
|
||||||
|
gst_video_info_init (&vinfo);
|
||||||
|
gst_video_info_from_caps (&vinfo, caps);
|
||||||
|
size = vinfo.size;
|
||||||
|
min = max = 0;
|
||||||
|
update_pool = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pool)
|
||||||
|
pool = gst_gl_buffer_pool_new (mix->display);
|
||||||
|
|
||||||
|
config = gst_buffer_pool_get_config (pool);
|
||||||
|
gst_buffer_pool_config_set_params (config, caps, size, min, max);
|
||||||
|
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
||||||
|
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_GL_META);
|
||||||
|
gst_buffer_pool_set_config (pool, config);
|
||||||
|
|
||||||
|
if (update_pool)
|
||||||
|
gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
|
||||||
|
else
|
||||||
|
gst_query_add_allocation_pool (query, pool, size, min, max);
|
||||||
|
|
||||||
|
gst_object_unref (pool);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* takes ownership of the pool, allocator and query */
|
||||||
|
static gboolean
|
||||||
|
gst_gl_mixer_set_allocation (GstGLMixer * mix,
|
||||||
|
GstBufferPool * pool, GstAllocator * allocator,
|
||||||
|
GstAllocationParams * params, GstQuery * query)
|
||||||
|
{
|
||||||
|
GstAllocator *oldalloc;
|
||||||
|
GstBufferPool *oldpool;
|
||||||
|
GstQuery *oldquery;
|
||||||
|
GstGLMixerPrivate *priv = mix->priv;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (mix);
|
||||||
|
oldpool = priv->pool;
|
||||||
|
priv->pool = pool;
|
||||||
|
priv->pool_active = FALSE;
|
||||||
|
|
||||||
|
oldalloc = priv->allocator;
|
||||||
|
priv->allocator = allocator;
|
||||||
|
|
||||||
|
oldquery = priv->query;
|
||||||
|
priv->query = query;
|
||||||
|
|
||||||
|
if (params)
|
||||||
|
priv->params = *params;
|
||||||
|
else
|
||||||
|
gst_allocation_params_init (&priv->params);
|
||||||
|
GST_OBJECT_UNLOCK (mix);
|
||||||
|
|
||||||
|
if (oldpool) {
|
||||||
|
GST_DEBUG_OBJECT (mix, "deactivating old pool %p", oldpool);
|
||||||
|
gst_buffer_pool_set_active (oldpool, FALSE);
|
||||||
|
gst_object_unref (oldpool);
|
||||||
|
}
|
||||||
|
if (oldalloc) {
|
||||||
|
gst_allocator_unref (oldalloc);
|
||||||
|
}
|
||||||
|
if (oldquery) {
|
||||||
|
gst_query_unref (oldquery);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_gl_mixer_do_bufferpool (GstGLMixer * mix, GstCaps * outcaps)
|
||||||
|
{
|
||||||
|
GstQuery *query;
|
||||||
|
gboolean result = TRUE;
|
||||||
|
GstBufferPool *pool = NULL;
|
||||||
|
GstAllocator *allocator;
|
||||||
|
GstAllocationParams params;
|
||||||
|
|
||||||
|
/* find a pool for the negotiated caps now */
|
||||||
|
GST_DEBUG_OBJECT (mix, "doing allocation query");
|
||||||
|
query = gst_query_new_allocation (outcaps, TRUE);
|
||||||
|
if (!gst_pad_peer_query (mix->srcpad, query)) {
|
||||||
|
/* not a problem, just debug a little */
|
||||||
|
GST_DEBUG_OBJECT (mix, "peer ALLOCATION query failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (mix, "calling decide_allocation");
|
||||||
|
result = gst_gl_mixer_decide_allocation (mix, query);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (mix, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, result,
|
||||||
|
query);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
goto no_decide_allocation;
|
||||||
|
|
||||||
|
/* we got configuration from our peer or the decide_allocation method,
|
||||||
|
* parse them */
|
||||||
|
if (gst_query_get_n_allocation_params (query) > 0) {
|
||||||
|
gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms);
|
||||||
|
} else {
|
||||||
|
allocator = NULL;
|
||||||
|
gst_allocation_params_init (¶ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_query_get_n_allocation_pools (query) > 0)
|
||||||
|
gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
/* now store */
|
||||||
|
result = gst_gl_mixer_set_allocation (mix, pool, allocator, ¶ms, query);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
/* Errors */
|
||||||
|
no_decide_allocation:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (mix, "Failed to decide allocation");
|
||||||
|
gst_query_unref (query);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gl_mixer_src_setcaps (GstPad * pad, GstGLMixer * mix, GstCaps * caps)
|
gst_gl_mixer_src_setcaps (GstPad * pad, GstGLMixer * mix, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix);
|
GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix);
|
||||||
|
GstGLMixerPrivate *priv = mix->priv;
|
||||||
GstVideoInfo info;
|
GstVideoInfo info;
|
||||||
gboolean ret;
|
gboolean ret = TRUE;
|
||||||
|
|
||||||
GST_INFO_OBJECT (mix, "set src caps: %" GST_PTR_FORMAT, caps);
|
GST_INFO_OBJECT (mix, "set src caps: %" GST_PTR_FORMAT, caps);
|
||||||
|
|
||||||
|
@ -967,8 +1140,12 @@ gst_gl_mixer_src_setcaps (GstPad * pad, GstGLMixer * mix, GstCaps * caps)
|
||||||
if (mixer_class->set_caps)
|
if (mixer_class->set_caps)
|
||||||
mixer_class->set_caps (mix, caps);
|
mixer_class->set_caps (mix, caps);
|
||||||
|
|
||||||
ret = TRUE;
|
ret = gst_pad_set_caps (mix->srcpad, caps);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
ret = gst_gl_mixer_do_bufferpool (mix, caps);
|
||||||
done:
|
done:
|
||||||
|
priv->negotiated = ret;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1243,6 +1420,8 @@ gst_gl_mixer_process_buffers (GstGLMixer * mix, GstBuffer * outbuf)
|
||||||
GSList *walk = mix->sinkpads;
|
GSList *walk = mix->sinkpads;
|
||||||
gint array_index = 0;
|
gint array_index = 0;
|
||||||
|
|
||||||
|
GST_TRACE ("Processing buffers");
|
||||||
|
|
||||||
while (walk) { /* We walk with this list because it's ordered */
|
while (walk) { /* We walk with this list because it's ordered */
|
||||||
GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
|
GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
|
||||||
GstGLMixerCollect *mixcol = pad->mixcol;
|
GstGLMixerCollect *mixcol = pad->mixcol;
|
||||||
|
@ -1401,14 +1580,23 @@ gst_gl_mixer_collected (GstCollectPads * pads, GstGLMixer * mix)
|
||||||
|
|
||||||
jitter = gst_gl_mixer_do_qos (mix, output_start_time);
|
jitter = gst_gl_mixer_do_qos (mix, output_start_time);
|
||||||
if (jitter <= 0) {
|
if (jitter <= 0) {
|
||||||
/* FIXME: Use GstGLMeta */
|
|
||||||
/* Calculating out buffer size from input size */
|
|
||||||
/*ret = gst_gl_buffer_parse_caps (GST_PAD_CAPS (mix->srcpad), &width, &height);
|
|
||||||
|
|
||||||
gl_outbuf = gst_gl_buffer_new (mix->display, mix->width, mix->height);
|
if (!mix->priv->pool_active) {
|
||||||
|
if (!gst_buffer_pool_set_active (mix->priv->pool, TRUE)) {
|
||||||
|
GST_ELEMENT_ERROR (mix, RESOURCE, SETTINGS,
|
||||||
|
("failed to activate bufferpool"),
|
||||||
|
("failed to activate bufferpool"));
|
||||||
|
ret = GST_FLOW_ERROR;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
mix->priv->pool_active = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
outbuf = GST_BUFFER (gl_outbuf);
|
ret = gst_buffer_pool_acquire_buffer (mix->priv->pool, &outbuf, NULL);
|
||||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (mix->srcpad)); */
|
|
||||||
|
gst_buffer_add_video_meta (outbuf, 0, GST_VIDEO_INFO_FORMAT (&mix->info),
|
||||||
|
GST_VIDEO_INFO_WIDTH (&mix->info), GST_VIDEO_INFO_HEIGHT (&mix->info));
|
||||||
|
gst_buffer_add_gl_meta (outbuf, mix->display);
|
||||||
|
|
||||||
gst_gl_mixer_process_buffers (mix, outbuf);
|
gst_gl_mixer_process_buffers (mix, outbuf);
|
||||||
mix->qos_processed++;
|
mix->qos_processed++;
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include "gstglmixerpad.h"
|
#include "gstglmixerpad.h"
|
||||||
|
|
||||||
|
#include "gstglbufferpool.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define GST_TYPE_GL_MIXER (gst_gl_mixer_get_type())
|
#define GST_TYPE_GL_MIXER (gst_gl_mixer_get_type())
|
||||||
|
@ -41,6 +43,7 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GstGLMixer GstGLMixer;
|
typedef struct _GstGLMixer GstGLMixer;
|
||||||
typedef struct _GstGLMixerClass GstGLMixerClass;
|
typedef struct _GstGLMixerClass GstGLMixerClass;
|
||||||
|
typedef struct _GstGLMixerPrivate GstGLMixerPrivate;
|
||||||
|
|
||||||
typedef gboolean (*GstGLMixerSetCaps) (GstGLMixer* mixer,
|
typedef gboolean (*GstGLMixerSetCaps) (GstGLMixer* mixer,
|
||||||
GstCaps* outcaps);
|
GstCaps* outcaps);
|
||||||
|
@ -52,6 +55,8 @@ struct _GstGLMixer
|
||||||
{
|
{
|
||||||
GstElement element;
|
GstElement element;
|
||||||
|
|
||||||
|
GstGLMixerPrivate *priv;
|
||||||
|
|
||||||
/* pad */
|
/* pad */
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue