mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 02:01:12 +00:00
gnl: Add the srcpad directly to GnlObject
Starting from now we will not claim that we support GnlObject that have several source pads as this is 1- Not true at all; 2- the design of priorities in the GnlComposition tree does not allow that; 3- Not very useful in most of the cases and it complexifies quite a lot the code in the composition. Conflicts: configure.ac tests/check/Makefile.am
This commit is contained in:
parent
38b080deb3
commit
4cb834fa21
14 changed files with 438 additions and 967 deletions
File diff suppressed because it is too large
Load diff
|
@ -35,6 +35,8 @@ struct _GnlPadPrivate
|
|||
GstPadDirection dir;
|
||||
GstPadEventFunction eventfunc;
|
||||
GstPadQueryFunction queryfunc;
|
||||
|
||||
GstEvent *pending_seek;
|
||||
};
|
||||
|
||||
static GstEvent *
|
||||
|
@ -489,7 +491,18 @@ ghostpad_event_function (GstPad * ghostpad, GstObject * parent,
|
|||
{
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_SEEK:
|
||||
{
|
||||
GstPad *target;
|
||||
|
||||
event = translate_incoming_seek (object, event);
|
||||
if (!(target = gst_ghost_pad_get_target (GST_GHOST_PAD (ghostpad)))) {
|
||||
priv->pending_seek = event;
|
||||
GST_INFO_OBJECT (ghostpad, "No target set yet, "
|
||||
"Will send the seek event when the target is set");
|
||||
ret = TRUE;
|
||||
event = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -661,7 +674,7 @@ gnl_object_ghost_pad (GnlObject * object, const gchar * name, GstPad * target)
|
|||
g_return_val_if_fail (target, FALSE);
|
||||
g_return_val_if_fail ((dir != GST_PAD_UNKNOWN), FALSE);
|
||||
|
||||
ghost = gnl_object_ghost_pad_no_target (object, name, dir);
|
||||
ghost = gnl_object_ghost_pad_no_target (object, name, dir, NULL);
|
||||
if (!ghost) {
|
||||
GST_WARNING_OBJECT (object, "Couldn't create ghostpad");
|
||||
return NULL;
|
||||
|
@ -692,17 +705,19 @@ gnl_object_ghost_pad (GnlObject * object, const gchar * name, GstPad * target)
|
|||
*/
|
||||
GstPad *
|
||||
gnl_object_ghost_pad_no_target (GnlObject * object, const gchar * name,
|
||||
GstPadDirection dir)
|
||||
GstPadDirection dir, GstPadTemplate * template)
|
||||
{
|
||||
GstPad *ghost;
|
||||
GnlPadPrivate *priv;
|
||||
|
||||
/* create a no_target ghostpad */
|
||||
ghost = gst_ghost_pad_new_no_target (name, dir);
|
||||
if (template)
|
||||
ghost = gst_ghost_pad_new_no_target_from_template (name, template);
|
||||
else
|
||||
ghost = gst_ghost_pad_new_no_target (name, dir);
|
||||
if (!ghost)
|
||||
return NULL;
|
||||
|
||||
GST_DEBUG ("grabbing existing pad functions");
|
||||
|
||||
/* remember the existing ghostpad event/query/link/unlink functions */
|
||||
priv = g_slice_new0 (GnlPadPrivate);
|
||||
|
@ -726,6 +741,8 @@ gnl_object_ghost_pad_no_target (GnlObject * object, const gchar * name,
|
|||
return ghost;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
gnl_object_remove_ghost_pad (GnlObject * object, GstPad * ghost)
|
||||
{
|
||||
|
@ -747,16 +764,32 @@ gnl_object_ghost_pad_set_target (GnlObject * object, GstPad * ghost,
|
|||
GnlPadPrivate *priv = gst_pad_get_element_private (ghost);
|
||||
|
||||
g_return_val_if_fail (priv, FALSE);
|
||||
g_return_val_if_fail (GST_IS_PAD (ghost), FALSE);
|
||||
|
||||
if (target)
|
||||
GST_DEBUG_OBJECT (object, "setting target %s:%s on ghostpad",
|
||||
GST_DEBUG_PAD_NAME (target));
|
||||
else
|
||||
GST_DEBUG_OBJECT (object, "removing target from ghostpad");
|
||||
if (target) {
|
||||
GST_DEBUG_OBJECT (object, "setting target %s:%s on %s:%s",
|
||||
GST_DEBUG_PAD_NAME (target), GST_DEBUG_PAD_NAME (ghost));
|
||||
} else {
|
||||
GST_ERROR_OBJECT (object, "removing target from ghostpad");
|
||||
priv->pending_seek = NULL;
|
||||
}
|
||||
|
||||
/* set target */
|
||||
if (!(gst_ghost_pad_set_target (GST_GHOST_PAD (ghost), target)))
|
||||
if (!(gst_ghost_pad_set_target (GST_GHOST_PAD (ghost), target))) {
|
||||
GST_WARNING_OBJECT (priv->object, "Could not set ghost %s:%s "
|
||||
"target to: %s:%s", GST_DEBUG_PAD_NAME (ghost),
|
||||
GST_DEBUG_PAD_NAME (target));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (target && priv->pending_seek) {
|
||||
gboolean res = gst_pad_send_event (ghost, priv->pending_seek);
|
||||
|
||||
GST_INFO_OBJECT (object, "Sending our pending seek event: %" GST_PTR_FORMAT
|
||||
" -- Result is %i", priv->pending_seek, res);
|
||||
|
||||
priv->pending_seek = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ GstPad *gnl_object_ghost_pad (GnlObject * object,
|
|||
const gchar * name, GstPad * target);
|
||||
|
||||
GstPad *gnl_object_ghost_pad_no_target (GnlObject * object,
|
||||
const gchar * name, GstPadDirection dir);
|
||||
const gchar * name, GstPadDirection dir, GstPadTemplate *templ);
|
||||
|
||||
gboolean gnl_object_ghost_pad_set_target (GnlObject * object,
|
||||
GstPad * ghost, GstPad * target);
|
||||
|
|
|
@ -42,10 +42,7 @@
|
|||
GST_DEBUG_CATEGORY_STATIC (gnlobject_debug);
|
||||
#define GST_CAT_DEFAULT gnlobject_debug
|
||||
|
||||
#define _do_init \
|
||||
GST_DEBUG_CATEGORY_INIT (gnlobject_debug, "gnlobject", GST_DEBUG_FG_BLUE | GST_DEBUG_BOLD, "GNonLin Object base class");
|
||||
#define gnl_object_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GnlObject, gnl_object, GST_TYPE_BIN, _do_init);
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
/****************************************************
|
||||
* Helper macros *
|
||||
|
@ -117,6 +114,9 @@ gnl_object_class_init (GnlObjectClass * klass)
|
|||
gobject_class = (GObjectClass *) klass;
|
||||
gstelement_class = (GstElementClass *) klass;
|
||||
gnlobject_class = (GnlObjectClass *) klass;
|
||||
GST_DEBUG_CATEGORY_INIT (gnlobject_debug, "gnlobject",
|
||||
GST_DEBUG_FG_BLUE | GST_DEBUG_BOLD, "GNonLin object");
|
||||
parent_class = g_type_class_ref (GST_TYPE_BIN);
|
||||
|
||||
gobject_class->set_property = GST_DEBUG_FUNCPTR (gnl_object_set_property);
|
||||
gobject_class->get_property = GST_DEBUG_FUNCPTR (gnl_object_get_property);
|
||||
|
@ -243,7 +243,7 @@ gnl_object_class_init (GnlObjectClass * klass)
|
|||
}
|
||||
|
||||
static void
|
||||
gnl_object_init (GnlObject * object)
|
||||
gnl_object_init (GnlObject * object, GnlObjectClass * klass)
|
||||
{
|
||||
object->start = object->pending_start = 0;
|
||||
object->duration = object->pending_duration = 0;
|
||||
|
@ -258,6 +258,12 @@ gnl_object_init (GnlObject * object)
|
|||
object->segment_rate = 1.0;
|
||||
object->segment_start = -1;
|
||||
object->segment_stop = -1;
|
||||
|
||||
object->srcpad = gnl_object_ghost_pad_no_target (object,
|
||||
"src", GST_PAD_SRC,
|
||||
gst_element_class_get_pad_template ((GstElementClass *) klass, "src"));
|
||||
|
||||
gst_element_add_pad (GST_ELEMENT (object), object->srcpad);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -653,3 +659,30 @@ gnl_object_reset (GnlObject * object)
|
|||
object->priority = 0;
|
||||
object->active = TRUE;
|
||||
}
|
||||
|
||||
GType
|
||||
gnl_object_get_type (void)
|
||||
{
|
||||
static volatile gsize type = 0;
|
||||
|
||||
if (g_once_init_enter (&type)) {
|
||||
GType _type;
|
||||
static const GTypeInfo info = {
|
||||
sizeof (GnlObjectClass),
|
||||
NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gnl_object_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GnlObject),
|
||||
0,
|
||||
(GInstanceInitFunc) gnl_object_init,
|
||||
};
|
||||
|
||||
_type = g_type_register_static (GST_TYPE_BIN,
|
||||
"GnlObject", &info, G_TYPE_FLAG_ABSTRACT);
|
||||
g_once_init_leave (&type, _type);
|
||||
}
|
||||
return type;
|
||||
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@ G_BEGIN_DECLS
|
|||
#define GNL_IS_OBJECT_CLASS(obj) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GNL_TYPE_OBJECT))
|
||||
|
||||
#define GNL_OBJECT_SRC(obj) (((GnlObject *) obj)->srcpad)
|
||||
|
||||
/**
|
||||
* GnlObjectFlags:
|
||||
* @GNL_OBJECT_IS_SOURCE:
|
||||
|
@ -84,6 +86,8 @@ struct _GnlObject
|
|||
{
|
||||
GstBin parent;
|
||||
|
||||
GstPad *srcpad;
|
||||
|
||||
/* Time positionning */
|
||||
GstClockTime start;
|
||||
GstClockTime inpoint;
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
static GstStaticPadTemplate gnl_operation_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_SOMETIMES,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
static GstStaticPadTemplate gnl_operation_sink_template =
|
||||
|
@ -163,10 +163,9 @@ gnl_operation_dispose (GObject * object)
|
|||
GnlOperation *oper = (GnlOperation *) object;
|
||||
|
||||
GST_DEBUG_OBJECT (object, "Disposing of source pad");
|
||||
if (oper->ghostpad) {
|
||||
gnl_object_remove_ghost_pad (GNL_OBJECT (oper), oper->ghostpad);
|
||||
oper->ghostpad = NULL;
|
||||
}
|
||||
|
||||
gnl_object_ghost_pad_set_target (GNL_OBJECT (object),
|
||||
GNL_OBJECT (object)->srcpad, NULL);
|
||||
|
||||
GST_DEBUG_OBJECT (object, "Disposing of sink pad(s)");
|
||||
while (oper->sinks) {
|
||||
|
@ -190,7 +189,6 @@ static void
|
|||
gnl_operation_init (GnlOperation * operation)
|
||||
{
|
||||
gnl_operation_reset (operation);
|
||||
operation->ghostpad = NULL;
|
||||
operation->element = NULL;
|
||||
}
|
||||
|
||||
|
@ -362,13 +360,8 @@ gnl_operation_add_element (GstBin * bin, GstElement * element)
|
|||
operation->element = element;
|
||||
operation->dynamicsinks = isdynamic;
|
||||
|
||||
/* Source ghostpad */
|
||||
if (operation->ghostpad)
|
||||
gnl_object_ghost_pad_set_target (GNL_OBJECT (operation),
|
||||
operation->ghostpad, srcpad);
|
||||
else
|
||||
operation->ghostpad = gnl_object_ghost_pad (GNL_OBJECT (operation),
|
||||
GST_PAD_NAME (srcpad), srcpad);
|
||||
gnl_object_ghost_pad_set_target (GNL_OBJECT (operation),
|
||||
GNL_OBJECT (operation)->srcpad, srcpad);
|
||||
|
||||
/* Remove the reference get_src_pad gave us */
|
||||
gst_object_unref (srcpad);
|
||||
|
|
|
@ -59,8 +59,6 @@ G_BEGIN_DECLS
|
|||
/* FIXME : We might need to use a lock to access this list */
|
||||
GList * sinks; /* The sink ghostpads */
|
||||
|
||||
GstPad *ghostpad; /* src ghostpad */
|
||||
|
||||
GstElement *element; /* controlled element */
|
||||
|
||||
GstClockTime next_base_time;
|
||||
|
|
108
gnl/gnlsource.c
108
gnl/gnlsource.c
|
@ -35,7 +35,7 @@
|
|||
static GstStaticPadTemplate gnl_source_src_template =
|
||||
GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_SOMETIMES,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS_ANY);
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (gnlsource);
|
||||
|
@ -51,7 +51,6 @@ struct _GnlSourcePrivate
|
|||
gboolean dispose_has_run;
|
||||
|
||||
gboolean dynamicpads; /* TRUE if the controlled element has dynamic pads */
|
||||
GstPad *ghostpad; /* The source ghostpad */
|
||||
GstEvent *event; /* queued event */
|
||||
|
||||
gulong padremovedid; /* signal handler for element pad-removed signal */
|
||||
|
@ -59,9 +58,10 @@ struct _GnlSourcePrivate
|
|||
gulong probeid; /* source pad probe id */
|
||||
|
||||
gboolean pendingblock; /* We have a pending pad_block */
|
||||
gboolean areblocked; /* We already got blocked */
|
||||
gboolean is_blocked; /* We already got blocked */
|
||||
GstPad *ghostedpad; /* Pad (to be) ghosted */
|
||||
GstPad *staticpad; /* The only pad. We keep an extra ref */
|
||||
gboolean got_seeked;
|
||||
};
|
||||
|
||||
static gboolean gnl_source_prepare (GnlObject * object);
|
||||
|
@ -136,6 +136,7 @@ gnl_source_init (GnlSource * source)
|
|||
static void
|
||||
gnl_source_dispose (GObject * object)
|
||||
{
|
||||
GnlObject *gnlobject = (GnlObject *) object;
|
||||
GnlSource *source = (GnlSource *) object;
|
||||
GnlSourcePrivate *priv = source->priv;
|
||||
|
||||
|
@ -153,9 +154,8 @@ gnl_source_dispose (GObject * object)
|
|||
if (priv->event)
|
||||
gst_event_unref (priv->event);
|
||||
|
||||
if (priv->ghostpad)
|
||||
gnl_object_remove_ghost_pad ((GnlObject *) object, priv->ghostpad);
|
||||
priv->ghostpad = NULL;
|
||||
if (priv->ghostedpad)
|
||||
gnl_object_ghost_pad_set_target (gnlobject, gnlobject->srcpad, NULL);
|
||||
|
||||
if (priv->staticpad) {
|
||||
gst_object_unref (priv->staticpad);
|
||||
|
@ -171,19 +171,20 @@ element_pad_added_cb (GstElement * element G_GNUC_UNUSED, GstPad * pad,
|
|||
{
|
||||
GstCaps *srccaps;
|
||||
GnlSourcePrivate *priv = source->priv;
|
||||
GnlObject *gnlobject = (GnlObject *) source;
|
||||
|
||||
GST_DEBUG_OBJECT (source, "pad %s:%s", GST_DEBUG_PAD_NAME (pad));
|
||||
|
||||
if (priv->ghostpad || priv->pendingblock) {
|
||||
if (priv->pendingblock) {
|
||||
GST_WARNING_OBJECT (source,
|
||||
"We already have (pending) ghost-ed a valid source pad (ghostpad:%s:%s, pendingblock:%d",
|
||||
GST_DEBUG_PAD_NAME (priv->ghostpad), priv->pendingblock);
|
||||
"We already have (pending) ghost-ed a valid source pad (srcpad:%s:%s, pendingblock:%d",
|
||||
GST_DEBUG_PAD_NAME (gnlobject->srcpad), priv->pendingblock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* FIXME: pass filter caps to query_caps directly */
|
||||
srccaps = gst_pad_query_caps (pad, NULL);
|
||||
if (!gst_caps_can_intersect (srccaps, GNL_OBJECT (source)->caps)) {
|
||||
if (gnlobject->caps && !gst_caps_can_intersect (srccaps, gnlobject->caps)) {
|
||||
gst_caps_unref (srccaps);
|
||||
GST_DEBUG_OBJECT (source, "Pad doesn't have valid caps, ignoring");
|
||||
return;
|
||||
|
@ -210,6 +211,7 @@ element_pad_removed_cb (GstElement * element G_GNUC_UNUSED, GstPad * pad,
|
|||
GnlSource * source)
|
||||
{
|
||||
GnlSourcePrivate *priv = source->priv;
|
||||
GnlObject *gnlobject = (GnlObject *) source;
|
||||
|
||||
GST_DEBUG_OBJECT (source, "pad %s:%s (controlled pad %s:%s)",
|
||||
GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (priv->ghostedpad));
|
||||
|
@ -218,19 +220,17 @@ element_pad_removed_cb (GstElement * element G_GNUC_UNUSED, GstPad * pad,
|
|||
GST_DEBUG_OBJECT (source,
|
||||
"The removed pad is the controlled pad, clearing up");
|
||||
|
||||
if (priv->ghostpad) {
|
||||
GST_DEBUG_OBJECT (source, "Clearing up ghostpad");
|
||||
GST_DEBUG_OBJECT (source, "Clearing up ghostpad");
|
||||
|
||||
priv->areblocked = FALSE;
|
||||
if (priv->probeid) {
|
||||
gst_pad_remove_probe (pad, priv->probeid);
|
||||
priv->probeid = 0;
|
||||
}
|
||||
|
||||
gnl_object_remove_ghost_pad ((GnlObject *) source, priv->ghostpad);
|
||||
priv->ghostpad = NULL;
|
||||
priv->is_blocked = FALSE;
|
||||
if (priv->probeid) {
|
||||
gst_pad_remove_probe (pad, priv->probeid);
|
||||
priv->probeid = 0;
|
||||
}
|
||||
|
||||
gnl_object_ghost_pad_set_target (GNL_OBJECT (source), gnlobject->srcpad,
|
||||
NULL);
|
||||
|
||||
priv->pendingblock = FALSE;
|
||||
priv->ghostedpad = NULL;
|
||||
} else {
|
||||
|
@ -292,20 +292,24 @@ ghost_seek_pad (GnlSource * source)
|
|||
{
|
||||
GnlSourcePrivate *priv = source->priv;
|
||||
GstPad *pad = priv->ghostedpad;
|
||||
GnlObject *gnlobject = (GnlObject *) source;
|
||||
|
||||
if (priv->ghostpad || !pad)
|
||||
priv->got_seeked = TRUE;
|
||||
|
||||
if (!pad)
|
||||
goto beach;
|
||||
|
||||
GST_DEBUG_OBJECT (source, "ghosting %s:%s", GST_DEBUG_PAD_NAME (pad));
|
||||
|
||||
priv->ghostpad = gnl_object_ghost_pad ((GnlObject *) source,
|
||||
GST_PAD_NAME (pad), pad);
|
||||
gnl_object_ghost_pad_set_target (gnlobject, gnlobject->srcpad, pad);
|
||||
GST_DEBUG_OBJECT (source, "emitting no more pads");
|
||||
gst_pad_set_active (priv->ghostpad, TRUE);
|
||||
|
||||
/*FIXME : do that when going to PAUSED */
|
||||
gst_pad_set_active (gnlobject->srcpad, TRUE);
|
||||
|
||||
if (priv->event) {
|
||||
GST_DEBUG_OBJECT (source, "sending queued seek event");
|
||||
if (!(gst_pad_send_event (priv->ghostpad, priv->event)))
|
||||
if (!(gst_pad_send_event (gnlobject->srcpad, priv->event)))
|
||||
GST_ELEMENT_ERROR (source, RESOURCE, SEEK,
|
||||
(NULL), ("Sending initial seek to upstream element failed"));
|
||||
else
|
||||
|
@ -314,7 +318,7 @@ ghost_seek_pad (GnlSource * source)
|
|||
}
|
||||
|
||||
GST_DEBUG_OBJECT (source, "about to unblock %s:%s", GST_DEBUG_PAD_NAME (pad));
|
||||
priv->areblocked = FALSE;
|
||||
priv->is_blocked = FALSE;
|
||||
if (priv->probeid) {
|
||||
gst_pad_remove_probe (pad, priv->probeid);
|
||||
priv->probeid = 0;
|
||||
|
@ -332,10 +336,10 @@ pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, GnlSource * source)
|
|||
{
|
||||
GST_DEBUG_OBJECT (pad, "probe callback");
|
||||
|
||||
if (!source->priv->ghostpad && !source->priv->areblocked) {
|
||||
if (!source->priv->got_seeked && !source->priv->is_blocked) {
|
||||
GThread *lthread;
|
||||
|
||||
source->priv->areblocked = TRUE;
|
||||
source->priv->is_blocked = TRUE;
|
||||
GST_DEBUG_OBJECT (pad, "starting thread to call ghost_seek_pad");
|
||||
lthread =
|
||||
g_thread_new ("gnlsourceseek", (GThreadFunc) ghost_seek_pad, source);
|
||||
|
@ -439,6 +443,7 @@ static gboolean
|
|||
gnl_source_remove_element (GstBin * bin, GstElement * element)
|
||||
{
|
||||
GnlSource *source = (GnlSource *) bin;
|
||||
GnlObject *gnlobject = (GnlObject *) element;
|
||||
GnlSourcePrivate *priv = source->priv;
|
||||
gboolean pret;
|
||||
|
||||
|
@ -452,11 +457,9 @@ gnl_source_remove_element (GstBin * bin, GstElement * element)
|
|||
}
|
||||
|
||||
if (pret) {
|
||||
/* remove ghostpad */
|
||||
if (priv->ghostpad) {
|
||||
gnl_object_remove_ghost_pad ((GnlObject *) bin, priv->ghostpad);
|
||||
priv->ghostpad = NULL;
|
||||
}
|
||||
gnl_object_ghost_pad_set_target (GNL_OBJECT (source), gnlobject->srcpad,
|
||||
NULL);
|
||||
priv->got_seeked = FALSE;
|
||||
|
||||
/* discard events */
|
||||
if (priv->event) {
|
||||
|
@ -485,12 +488,13 @@ static gboolean
|
|||
gnl_source_send_event (GstElement * element, GstEvent * event)
|
||||
{
|
||||
GnlSource *source = (GnlSource *) element;
|
||||
GnlObject *gnlobject = (GnlObject *) element;
|
||||
gboolean res = TRUE;
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_SEEK:
|
||||
if (source->priv->ghostpad)
|
||||
res = gst_pad_send_event (source->priv->ghostpad, event);
|
||||
if (source->priv->ghostedpad)
|
||||
res = gst_pad_send_event (gnlobject->srcpad, event);
|
||||
else {
|
||||
if (source->priv->event)
|
||||
gst_event_unref (source->priv->event);
|
||||
|
@ -516,13 +520,15 @@ gnl_source_prepare (GnlObject * object)
|
|||
if (!source->element) {
|
||||
GST_WARNING_OBJECT (source,
|
||||
"GnlSource doesn't have an element to control !");
|
||||
if (parent)
|
||||
gst_object_unref (parent);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_LOG_OBJECT (source, "ghostpad:%p, dynamicpads:%d",
|
||||
priv->ghostpad, priv->dynamicpads);
|
||||
GST_LOG_OBJECT (source, "srcpad:%p, dynamicpads:%d",
|
||||
object->srcpad, priv->dynamicpads);
|
||||
|
||||
if (!(priv->ghostpad) && !priv->pendingblock) {
|
||||
if (!(priv->got_seeked) && !priv->pendingblock) {
|
||||
GstPad *pad;
|
||||
|
||||
GST_LOG_OBJECT (source, "no ghostpad and no dynamic pads");
|
||||
|
@ -568,22 +574,22 @@ gnl_source_cleanup (GnlObject * object)
|
|||
GnlSource *source = GNL_SOURCE (object);
|
||||
GnlSourcePrivate *priv = source->priv;
|
||||
|
||||
if (priv->ghostpad) {
|
||||
GstPad *target = gst_ghost_pad_get_target ((GstGhostPad *) priv->ghostpad);
|
||||
/* FIXME : should just be ghostedpad */
|
||||
GstPad *target = gst_ghost_pad_get_target ((GstGhostPad *) object->srcpad);
|
||||
|
||||
if (target) {
|
||||
if (priv->probeid) {
|
||||
gst_pad_remove_probe (target, priv->probeid);
|
||||
priv->probeid = 0;
|
||||
}
|
||||
gst_object_unref (target);
|
||||
if (target) {
|
||||
if (priv->probeid) {
|
||||
gst_pad_remove_probe (target, priv->probeid);
|
||||
priv->probeid = 0;
|
||||
}
|
||||
gnl_object_remove_ghost_pad ((GnlObject *) source, priv->ghostpad);
|
||||
priv->ghostpad = NULL;
|
||||
priv->ghostedpad = NULL;
|
||||
priv->areblocked = FALSE;
|
||||
priv->pendingblock = FALSE;
|
||||
gst_object_unref (target);
|
||||
}
|
||||
|
||||
gnl_object_ghost_pad_set_target (GNL_OBJECT (source), object->srcpad, NULL);
|
||||
priv->got_seeked = FALSE;
|
||||
priv->ghostedpad = NULL;
|
||||
priv->is_blocked = FALSE;
|
||||
priv->pendingblock = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -26,8 +26,7 @@ fill_pipeline_and_check (GstElement * comp, GList * segments,
|
|||
/* Expected segments */
|
||||
collect->expected_segments = segments;
|
||||
|
||||
g_signal_connect (G_OBJECT (comp), "pad-added",
|
||||
G_CALLBACK (composition_pad_added_cb), collect);
|
||||
gst_element_link (comp, sink);
|
||||
|
||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||
gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
|
||||
|
@ -562,8 +561,7 @@ GST_START_TEST (test_renegotiation)
|
|||
segment_new (1.0, GST_FORMAT_TIME,
|
||||
2 * GST_SECOND, 3 * GST_SECOND, 2 * GST_SECOND));
|
||||
|
||||
g_signal_connect (G_OBJECT (comp), "pad-added",
|
||||
G_CALLBACK (composition_pad_added_cb), collect);
|
||||
gst_element_link (comp, audioconvert);
|
||||
|
||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||
gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
|
||||
|
|
|
@ -24,12 +24,7 @@ typedef struct
|
|||
GstElement *source3;
|
||||
} TestClosure;
|
||||
|
||||
static int composition_pad_added;
|
||||
static int composition_pad_removed;
|
||||
static int seek_events;
|
||||
static gulong blockprobeid = 0;
|
||||
static GMutex pad_added_lock;
|
||||
static GCond pad_added_cond;
|
||||
|
||||
static GstPadProbeReturn
|
||||
on_source1_pad_event_cb (GstPad * pad, GstPadProbeInfo * info,
|
||||
|
@ -41,35 +36,9 @@ on_source1_pad_event_cb (GstPad * pad, GstPadProbeInfo * info,
|
|||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
on_source1_pad_added_cb (GstElement * source, GstPad * pad, gpointer user_data)
|
||||
{
|
||||
gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
|
||||
(GstPadProbeCallback) on_source1_pad_event_cb, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_composition_pad_added_cb (GstElement * composition, GstPad * pad,
|
||||
GstElement * sink)
|
||||
{
|
||||
GstPad *s = gst_element_get_static_pad (sink, "sink");
|
||||
gst_pad_link (pad, s);
|
||||
++composition_pad_added;
|
||||
g_mutex_lock (&pad_added_lock);
|
||||
g_cond_broadcast (&pad_added_cond);
|
||||
g_mutex_unlock (&pad_added_lock);
|
||||
gst_object_unref (s);
|
||||
}
|
||||
|
||||
static void
|
||||
on_composition_pad_removed_cb (GstElement * composition, GstPad * pad,
|
||||
GstElement * sink)
|
||||
{
|
||||
++composition_pad_removed;
|
||||
}
|
||||
|
||||
GST_START_TEST (test_change_object_start_stop_in_current_stack)
|
||||
{
|
||||
GstPad *srcpad;
|
||||
GstElement *pipeline;
|
||||
GstElement *comp, *source1, *def, *sink;
|
||||
GstBus *bus;
|
||||
|
@ -84,11 +53,7 @@ GST_START_TEST (test_change_object_start_stop_in_current_stack)
|
|||
sink = gst_element_factory_make_or_warn ("fakesink", "sink");
|
||||
gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL);
|
||||
|
||||
/* connect to pad-added */
|
||||
g_object_connect (comp, "signal::pad-added",
|
||||
on_composition_pad_added_cb, sink, NULL);
|
||||
g_object_connect (comp, "signal::pad-removed",
|
||||
on_composition_pad_removed_cb, NULL, NULL);
|
||||
gst_element_link (comp, sink);
|
||||
|
||||
/*
|
||||
source1
|
||||
|
@ -98,8 +63,9 @@ GST_START_TEST (test_change_object_start_stop_in_current_stack)
|
|||
*/
|
||||
|
||||
source1 = videotest_gnl_src ("source1", 0, 2 * GST_SECOND, 2, 2);
|
||||
g_object_connect (source1, "signal::pad-added",
|
||||
on_source1_pad_added_cb, NULL, NULL);
|
||||
srcpad = gst_element_get_static_pad (source1, "src");
|
||||
gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
|
||||
(GstPadProbeCallback) on_source1_pad_event_cb, NULL, NULL);
|
||||
|
||||
/*
|
||||
def (default source)
|
||||
|
@ -161,9 +127,6 @@ GST_START_TEST (test_change_object_start_stop_in_current_stack)
|
|||
}
|
||||
}
|
||||
|
||||
fail_unless_equals_int (composition_pad_added, 1);
|
||||
fail_unless_equals_int (composition_pad_removed, 0);
|
||||
|
||||
seek_events_before = seek_events;
|
||||
|
||||
/* pipeline is paused at this point */
|
||||
|
@ -171,15 +134,13 @@ GST_START_TEST (test_change_object_start_stop_in_current_stack)
|
|||
/* move source1 out of the active segment */
|
||||
g_object_set (source1, "start", (guint64) 4 * GST_SECOND, NULL);
|
||||
g_signal_emit_by_name (comp, "commit", TRUE, &ret);
|
||||
fail_unless (seek_events > seek_events_before);
|
||||
fail_unless (seek_events > seek_events_before, "%i > %i", seek_events,
|
||||
seek_events_before);
|
||||
|
||||
/* remove source1 from the composition, which will become empty and remove the
|
||||
* ghostpad */
|
||||
gst_bin_remove (GST_BIN (comp), source1);
|
||||
|
||||
fail_unless_equals_int (composition_pad_added, 1);
|
||||
fail_unless_equals_int (composition_pad_removed, 1);
|
||||
|
||||
g_object_set (source1, "start", (guint64) 0 * GST_SECOND, NULL);
|
||||
/* add the source again and check that the ghostpad is added again */
|
||||
gst_bin_add (GST_BIN (comp), source1);
|
||||
|
@ -234,177 +195,6 @@ GST_START_TEST (test_remove_invalid_object)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
static GstPadProbeReturn
|
||||
pad_block (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||
{
|
||||
GstPad *ghost;
|
||||
GstBin *bin;
|
||||
|
||||
bin = GST_BIN (user_data);
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "probe type:0x%x", GST_PAD_PROBE_INFO_TYPE (info));
|
||||
|
||||
ghost = gst_ghost_pad_new ("src", pad);
|
||||
gst_pad_set_active (ghost, TRUE);
|
||||
|
||||
gst_element_add_pad (GST_ELEMENT (bin), ghost);
|
||||
|
||||
return GST_PAD_PROBE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
no_more_pads_test_cb (GObject * object, TestClosure * c)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
GST_WARNING ("NO MORE PADS");
|
||||
gst_bin_add (GST_BIN (c->composition), c->source3);
|
||||
g_signal_emit_by_name (c->composition, "commit", TRUE, &ret);
|
||||
}
|
||||
|
||||
GST_START_TEST (test_no_more_pads_race)
|
||||
{
|
||||
gboolean ret;
|
||||
GstElement *source1, *source2, *source3;
|
||||
GstBin *bin;
|
||||
GstElement *videotestsrc1, *videotestsrc2;
|
||||
GstElement *operation;
|
||||
GstElement *composition;
|
||||
GstElement *videomixer, *fakesink;
|
||||
GstElement *pipeline;
|
||||
GstBus *bus;
|
||||
GstMessage *message;
|
||||
GstPad *pad;
|
||||
TestClosure closure;
|
||||
|
||||
/* We create a composition with an operation and three sources. The operation
|
||||
* contains a videomixer instance and the three sources are videotestsrc's.
|
||||
*
|
||||
* One of the sources, source2, contains videotestsrc inside a bin. Initially
|
||||
* the bin doesn't have a source pad. We do this to exercise the dynamic src
|
||||
* pad code path in gnlcomposition. We block on the videotestsrc srcpad and in
|
||||
* the pad block callback we ghost the pad and add the ghost to the parent
|
||||
* bin. This makes gnlsource emit no-more-pads, which is used by
|
||||
* gnlcomposition to link the source2:src pad to videomixer.
|
||||
*
|
||||
* We start with the composition containing operation and source1. We preroll
|
||||
* and then add source2. Source2 will do what described above and emit
|
||||
* no-more-pads. We connect to that no-more-pads and from there we add source3 to
|
||||
* the composition. Adding a new source will make gnlcomposition deactivate
|
||||
* the old stack and activate a new one. The new one contains operation,
|
||||
* source1, source2 and source3. Source2 was active in the old stack as well and
|
||||
* gnlcomposition is *still waiting* for no-more-pads to be emitted on it
|
||||
* (since the no-more-pads emission is now blocked in our test's no-more-pads
|
||||
* callback, calling gst_bin_add). In short, here, we're simulating a race between
|
||||
* no-more-pads and someone modifying the composition.
|
||||
*
|
||||
* Activating the new stack, gnlcomposition calls compare_relink_single_node,
|
||||
* which finds an existing source pad for source2 this time since we have
|
||||
* already blocked and ghosted. It takes another code path that assumes that
|
||||
* source2 doesn't have dynamic pads and *BOOM*.
|
||||
*/
|
||||
|
||||
pipeline = GST_ELEMENT (gst_pipeline_new (NULL));
|
||||
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
|
||||
|
||||
composition = gst_element_factory_make ("gnlcomposition", "composition");
|
||||
fakesink = gst_element_factory_make ("fakesink", NULL);
|
||||
fail_unless (fakesink != NULL);
|
||||
g_object_set (fakesink, "sync", TRUE, NULL);
|
||||
|
||||
/* operation */
|
||||
operation = gst_element_factory_make ("gnloperation", "operation");
|
||||
videomixer = gst_element_factory_make ("videomixer", "videomixer");
|
||||
fail_unless (videomixer != NULL);
|
||||
gst_bin_add (GST_BIN (operation), videomixer);
|
||||
g_object_set (operation, "start", (guint64) 0 * GST_SECOND,
|
||||
"duration", (guint64) 10 * GST_SECOND,
|
||||
"inpoint", (guint64) 0 * GST_SECOND, "priority", 10, NULL);
|
||||
gst_bin_add (GST_BIN (composition), operation);
|
||||
|
||||
/* source 1 */
|
||||
source1 = gst_element_factory_make ("gnlsource", "source1");
|
||||
videotestsrc1 = gst_element_factory_make ("videotestsrc", "videotestsrc1");
|
||||
gst_bin_add (GST_BIN (source1), videotestsrc1);
|
||||
g_object_set (source1, "start", (guint64) 0 * GST_SECOND, "duration",
|
||||
(guint64) 5 * GST_SECOND, "inpoint", (guint64) 0 * GST_SECOND, "priority",
|
||||
20, NULL);
|
||||
|
||||
/* source2 */
|
||||
source2 = gst_element_factory_make ("gnlsource", "source2");
|
||||
bin = GST_BIN (gst_bin_new (NULL));
|
||||
videotestsrc2 = gst_element_factory_make ("videotestsrc", "videotestsrc2");
|
||||
pad = gst_element_get_static_pad (videotestsrc2, "src");
|
||||
blockprobeid =
|
||||
gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
|
||||
(GstPadProbeCallback) pad_block, bin, NULL);
|
||||
gst_bin_add (bin, videotestsrc2);
|
||||
gst_bin_add (GST_BIN (source2), GST_ELEMENT (bin));
|
||||
g_object_set (source2, "start", (guint64) 0 * GST_SECOND, "duration",
|
||||
(guint64) 5 * GST_SECOND, "inpoint", (guint64) 0 * GST_SECOND, "priority",
|
||||
20, NULL);
|
||||
|
||||
/* source3 */
|
||||
source3 = gst_element_factory_make ("gnlsource", "source3");
|
||||
videotestsrc2 = gst_element_factory_make ("videotestsrc", "videotestsrc3");
|
||||
gst_bin_add (GST_BIN (source3), videotestsrc2);
|
||||
g_object_set (source3, "start", (guint64) 0 * GST_SECOND, "duration",
|
||||
(guint64) 5 * GST_SECOND, "inpoint", (guint64) 0 * GST_SECOND, "priority",
|
||||
20, NULL);
|
||||
|
||||
closure.composition = composition;
|
||||
closure.source3 = source3;
|
||||
g_object_connect (source2, "signal::no-more-pads",
|
||||
no_more_pads_test_cb, &closure, NULL);
|
||||
|
||||
gst_bin_add (GST_BIN (composition), source1);
|
||||
g_signal_emit_by_name (composition, "commit", TRUE, &ret);
|
||||
g_object_connect (composition, "signal::pad-added",
|
||||
on_composition_pad_added_cb, fakesink, NULL);
|
||||
g_object_connect (composition, "signal::pad-removed",
|
||||
on_composition_pad_removed_cb, NULL, NULL);
|
||||
|
||||
GST_DEBUG ("Adding composition to pipeline");
|
||||
|
||||
gst_bin_add_many (GST_BIN (pipeline), composition, fakesink, NULL);
|
||||
|
||||
GST_DEBUG ("Setting pipeline to PAUSED");
|
||||
|
||||
fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED)
|
||||
== GST_STATE_CHANGE_FAILURE);
|
||||
|
||||
message = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
|
||||
GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);
|
||||
if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR) {
|
||||
fail_error_message (message);
|
||||
}
|
||||
gst_message_unref (message);
|
||||
|
||||
GST_DEBUG ("Adding second source");
|
||||
|
||||
/* FIXME: maybe slow down the videotestsrc steaming thread */
|
||||
gst_bin_add (GST_BIN (composition), source2);
|
||||
g_signal_emit_by_name (composition, "commit", TRUE, &ret);
|
||||
|
||||
message =
|
||||
gst_bus_timed_pop_filtered (bus, GST_SECOND / 10, GST_MESSAGE_ERROR);
|
||||
if (message) {
|
||||
if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR) {
|
||||
fail_error_message (message);
|
||||
} else {
|
||||
fail_if (TRUE);
|
||||
}
|
||||
|
||||
gst_message_unref (message);
|
||||
}
|
||||
|
||||
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
|
||||
gst_object_unref (pipeline);
|
||||
gst_object_unref (bus);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_simple_adder)
|
||||
{
|
||||
GstBus *bus;
|
||||
|
@ -452,19 +242,13 @@ GST_START_TEST (test_simple_adder)
|
|||
g_object_set (gnlsource2, "start", (guint64) 0 * GST_SECOND,
|
||||
"duration", total_time, "inpoint", (guint64) 0 * GST_SECOND, "priority",
|
||||
2, NULL);
|
||||
fail_unless (gst_bin_add (GST_BIN (composition), gnlsource2));
|
||||
|
||||
/* Connecting signals */
|
||||
g_object_connect (composition, "signal::pad-added",
|
||||
on_composition_pad_added_cb, fakesink, NULL);
|
||||
g_object_connect (composition, "signal::pad-removed",
|
||||
on_composition_pad_removed_cb, NULL, NULL);
|
||||
|
||||
|
||||
GST_DEBUG ("Adding composition to pipeline");
|
||||
|
||||
gst_bin_add_many (GST_BIN (pipeline), composition, fakesink, NULL);
|
||||
|
||||
fail_unless (gst_bin_add (GST_BIN (composition), gnlsource2));
|
||||
fail_unless (gst_element_link (composition, fakesink) == TRUE);
|
||||
|
||||
GST_DEBUG ("Setting pipeline to PAUSED");
|
||||
|
||||
g_signal_emit_by_name (composition, "commit", TRUE, &ret);
|
||||
|
@ -536,16 +320,8 @@ gnonlin_suite (void)
|
|||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
|
||||
g_cond_init (&pad_added_cond);
|
||||
g_mutex_init (&pad_added_lock);
|
||||
tcase_add_test (tc_chain, test_change_object_start_stop_in_current_stack);
|
||||
tcase_add_test (tc_chain, test_remove_invalid_object);
|
||||
if (gst_registry_check_feature_version (gst_registry_get (), "videomixer", 0,
|
||||
11, 0)) {
|
||||
tcase_add_test (tc_chain, test_no_more_pads_race);
|
||||
} else {
|
||||
GST_WARNING ("videomixer element not available, skipping 1 test");
|
||||
}
|
||||
|
||||
if (gst_registry_check_feature_version (gst_registry_get (), "adder", 1,
|
||||
0, 0)) {
|
||||
|
|
|
@ -25,8 +25,7 @@ fill_pipeline_and_check (GstElement * comp, GList * segments)
|
|||
/* Expected segments */
|
||||
collect->expected_segments = segments;
|
||||
|
||||
g_signal_connect (G_OBJECT (comp), "pad-added",
|
||||
G_CALLBACK (composition_pad_added_cb), collect);
|
||||
gst_element_link (comp, sink);
|
||||
|
||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||
gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
|
||||
|
|
|
@ -39,8 +39,7 @@ GST_START_TEST (test_simple_videotestsrc)
|
|||
segment_new (1.0, GST_FORMAT_TIME,
|
||||
1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND));
|
||||
|
||||
g_signal_connect (G_OBJECT (gnlsource), "pad-added",
|
||||
G_CALLBACK (composition_pad_added_cb), collect);
|
||||
gst_element_link (gnlsource, sink);
|
||||
|
||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||
fail_if (sinkpad == NULL);
|
||||
|
@ -139,8 +138,7 @@ GST_START_TEST (test_videotestsrc_in_bin)
|
|||
collect->expected_segments = g_list_append (collect->expected_segments,
|
||||
segment_new (1.0, GST_FORMAT_TIME, 0, 1 * GST_SECOND, 0));
|
||||
|
||||
g_signal_connect (G_OBJECT (gnlsource), "pad-added",
|
||||
G_CALLBACK (composition_pad_added_cb), collect);
|
||||
gst_element_link (gnlsource, sink);
|
||||
|
||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||
fail_if (sinkpad == NULL);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "common.h"
|
||||
static const gchar *compositor_element = NULL;
|
||||
|
||||
typedef struct _SeekInfo
|
||||
{
|
||||
|
@ -48,8 +49,7 @@ fill_pipeline_and_check (GstElement * comp, GList * segments, GList * seeks)
|
|||
collect->expected_segments = segments;
|
||||
collect->keep_expected_segments = TRUE;
|
||||
|
||||
g_signal_connect (G_OBJECT (comp), "pad-added",
|
||||
G_CALLBACK (composition_pad_added_cb), collect);
|
||||
gst_element_link (comp, sink);
|
||||
|
||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||
gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
|
||||
|
@ -521,7 +521,8 @@ GST_START_TEST (test_complex_operations)
|
|||
*/
|
||||
|
||||
oper =
|
||||
new_operation ("oper", "videomixer", 2 * GST_SECOND, 2 * GST_SECOND, 1);
|
||||
new_operation ("oper", compositor_element, 2 * GST_SECOND, 2 * GST_SECOND,
|
||||
1);
|
||||
fail_if (oper == NULL);
|
||||
check_start_stop_duration (oper, 2 * GST_SECOND, 4 * GST_SECOND,
|
||||
2 * GST_SECOND);
|
||||
|
@ -639,7 +640,8 @@ GST_START_TEST (test_complex_operations_bis)
|
|||
*/
|
||||
|
||||
oper =
|
||||
new_operation ("oper", "videomixer", 2 * GST_SECOND, 2 * GST_SECOND, 1);
|
||||
new_operation ("oper", compositor_element, 2 * GST_SECOND, 2 * GST_SECOND,
|
||||
1);
|
||||
fail_if (oper == NULL);
|
||||
check_start_stop_duration (oper, 2 * GST_SECOND, 4 * GST_SECOND,
|
||||
2 * GST_SECOND);
|
||||
|
@ -751,12 +753,26 @@ gnonlin_suite (void)
|
|||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
|
||||
if (gst_registry_check_feature_version (gst_registry_get (), "compositor", 1,
|
||||
0, 0)) {
|
||||
compositor_element = "compositor";
|
||||
} else if (gst_registry_check_feature_version (gst_registry_get (),
|
||||
"videomixer", 1, 0, 0)) {
|
||||
compositor_element = "videomixer";
|
||||
|
||||
}
|
||||
|
||||
tcase_add_test (tc_chain, test_simplest);
|
||||
tcase_add_test (tc_chain, test_one_after_other);
|
||||
tcase_add_test (tc_chain, test_one_under_another);
|
||||
tcase_add_test (tc_chain, test_one_bin_after_other);
|
||||
tcase_add_test (tc_chain, test_complex_operations);
|
||||
tcase_add_test (tc_chain, test_complex_operations_bis);
|
||||
|
||||
if (compositor_element) {
|
||||
tcase_add_test (tc_chain, test_complex_operations);
|
||||
tcase_add_test (tc_chain, test_complex_operations_bis);
|
||||
} else {
|
||||
GST_WARNING ("No compositor element, can not run operations tests");
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -52,9 +52,7 @@ test_simplest_full (void)
|
|||
collect->expected_segments = g_list_append (collect->expected_segments,
|
||||
segment_new (1.0, GST_FORMAT_TIME, 5 * GST_SECOND, 6 * GST_SECOND, 0));
|
||||
|
||||
g_signal_connect (G_OBJECT (comp), "pad-added",
|
||||
G_CALLBACK (composition_pad_added_cb), collect);
|
||||
|
||||
gst_element_link (comp, sink);
|
||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||
gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
|
||||
(GstPadProbeCallback) sinkpad_probe, collect, NULL);
|
||||
|
@ -282,8 +280,7 @@ test_one_after_other_full (void)
|
|||
segment_new (1.0, GST_FORMAT_TIME,
|
||||
2 * GST_SECOND, 3 * GST_SECOND, 1 * GST_SECOND));
|
||||
|
||||
g_signal_connect (G_OBJECT (comp), "pad-added",
|
||||
G_CALLBACK (composition_pad_added_cb), collect);
|
||||
gst_element_link (comp, sink);
|
||||
|
||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||
gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
|
||||
|
@ -485,8 +482,7 @@ test_one_under_another_full (void)
|
|||
segment_new (1.0, GST_FORMAT_TIME,
|
||||
2 * GST_SECOND, 3 * GST_SECOND, 2 * GST_SECOND));
|
||||
|
||||
g_signal_connect (G_OBJECT (comp), "pad-added",
|
||||
G_CALLBACK (composition_pad_added_cb), collect);
|
||||
gst_element_link (comp, sink);
|
||||
|
||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||
gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
|
||||
|
@ -634,8 +630,7 @@ test_one_bin_after_other_full (void)
|
|||
segment_new (1.0, GST_FORMAT_TIME,
|
||||
1 * GST_SECOND, 2 * GST_SECOND, 1 * GST_SECOND));
|
||||
|
||||
g_signal_connect (G_OBJECT (comp), "pad-added",
|
||||
G_CALLBACK (composition_pad_added_cb), collect);
|
||||
gst_element_link (comp, sink);
|
||||
|
||||
sinkpad = gst_element_get_static_pad (sink, "sink");
|
||||
gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
|
||||
|
|
Loading…
Reference in a new issue