mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-31 11:32:38 +00:00
[542/906] GstGLMixer: add allocation and bufferpool methods
based off GstBaseTransform
This commit is contained in:
parent
3be415e5c9
commit
fe1ce6a7ff
2 changed files with 201 additions and 8 deletions
|
@ -66,6 +66,20 @@ enum
|
|||
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);
|
||||
|
||||
static void
|
||||
|
@ -207,6 +221,7 @@ gst_gl_mixer_update_src_caps (GstGLMixer * mix)
|
|||
|
||||
GST_GL_MIXER_UNLOCK (mix);
|
||||
ret = gst_gl_mixer_src_setcaps (mix->srcpad, mix, caps);
|
||||
// ret = gst_pad_set_caps (mix->srcpad, caps);
|
||||
gst_caps_unref (caps);
|
||||
} else {
|
||||
GST_GL_MIXER_UNLOCK (mix);
|
||||
|
@ -334,6 +349,8 @@ gst_gl_mixer_pad_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
|||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
GST_TRACE ("QUERY %d", GST_QUERY_TYPE (query));
|
||||
|
||||
switch (GST_QUERY_TYPE (query)) {
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -422,6 +440,14 @@ static gboolean gst_gl_mixer_query_duration (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 void gst_gl_mixer_update_qos (GstGLMixer * mix, gdouble proportion,
|
||||
GstClockTimeDiff diff, GstClockTime timestamp);
|
||||
|
@ -484,6 +510,8 @@ gst_gl_mixer_class_init (GstGLMixerClass * klass)
|
|||
gobject_class = (GObjectClass *) 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->get_property = gst_gl_mixer_get_property;
|
||||
|
@ -517,6 +545,7 @@ gst_gl_mixer_collect_free (GstGLMixerCollect * mixcol)
|
|||
static void
|
||||
gst_gl_mixer_reset (GstGLMixer * mix)
|
||||
{
|
||||
GstGLMixerPrivate *priv = mix->priv;
|
||||
GSList *l;
|
||||
|
||||
gst_video_info_init (&mix->info);
|
||||
|
@ -540,6 +569,8 @@ gst_gl_mixer_reset (GstGLMixer * mix)
|
|||
|
||||
mix->newseg_pending = TRUE;
|
||||
mix->flush_stop_pending = FALSE;
|
||||
|
||||
priv->negotiated = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -547,6 +578,8 @@ gst_gl_mixer_init (GstGLMixer * mix)
|
|||
{
|
||||
GstElementClass *klass = GST_ELEMENT_GET_CLASS (mix);
|
||||
|
||||
mix->priv = GST_GL_MIXER_GET_PRIVATE (mix);
|
||||
|
||||
mix->srcpad =
|
||||
gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
|
||||
"src"), "src");
|
||||
|
@ -927,12 +960,152 @@ gst_gl_mixer_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
|||
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
|
||||
gst_gl_mixer_src_setcaps (GstPad * pad, GstGLMixer * mix, GstCaps * caps)
|
||||
{
|
||||
GstGLMixerClass *mixer_class = GST_GL_MIXER_GET_CLASS (mix);
|
||||
GstGLMixerPrivate *priv = mix->priv;
|
||||
GstVideoInfo info;
|
||||
gboolean ret;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
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)
|
||||
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:
|
||||
priv->negotiated = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1243,6 +1420,8 @@ gst_gl_mixer_process_buffers (GstGLMixer * mix, GstBuffer * outbuf)
|
|||
GSList *walk = mix->sinkpads;
|
||||
gint array_index = 0;
|
||||
|
||||
GST_TRACE ("Processing buffers");
|
||||
|
||||
while (walk) { /* We walk with this list because it's ordered */
|
||||
GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data);
|
||||
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);
|
||||
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);
|
||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (mix->srcpad)); */
|
||||
ret = gst_buffer_pool_acquire_buffer (mix->priv->pool, &outbuf, NULL);
|
||||
|
||||
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);
|
||||
mix->qos_processed++;
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <gst/video/video.h>
|
||||
#include "gstglmixerpad.h"
|
||||
|
||||
#include "gstglbufferpool.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_GL_MIXER (gst_gl_mixer_get_type())
|
||||
|
@ -41,6 +43,7 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _GstGLMixer GstGLMixer;
|
||||
typedef struct _GstGLMixerClass GstGLMixerClass;
|
||||
typedef struct _GstGLMixerPrivate GstGLMixerPrivate;
|
||||
|
||||
typedef gboolean (*GstGLMixerSetCaps) (GstGLMixer* mixer,
|
||||
GstCaps* outcaps);
|
||||
|
@ -52,6 +55,8 @@ struct _GstGLMixer
|
|||
{
|
||||
GstElement element;
|
||||
|
||||
GstGLMixerPrivate *priv;
|
||||
|
||||
/* pad */
|
||||
GstPad *srcpad;
|
||||
|
||||
|
|
Loading…
Reference in a new issue