Refactored *_new() functions.

Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gstghostpad.c: (gst_proxy_pad_do_getcaps),
(gst_proxy_pad_do_setcaps), (gst_proxy_pad_set_target_unlocked),
(gst_proxy_pad_dispose), (gst_ghost_pad_new_full),
(gst_ghost_pad_new_no_target), (gst_ghost_pad_new),
(gst_ghost_pad_new_from_template),
(gst_ghost_pad_new_no_target_from_template):
* gst/gstghostpad.h:
Refactored *_new() functions.
Templates are now used as a g_object_new() parameter.
Use template in _do_getcaps() if we don't have a target.
Small documentation cleanups.
Added two new constructors:
gst_ghost_pad_new_from_template()
gst_ghost_pad_new_no_target_from_template()
* tests/check/gst/gstghostpad.c: (GST_START_TEST),
(gst_ghost_pad_suite):
Added tests for new ghostpad instanciation functions.
API additions: gst_ghost_pad_new_from_template,
gst_ghost_pad_new_no_target_from_template
This commit is contained in:
Edward Hervey 2006-08-31 10:59:11 +00:00
parent 8a74297153
commit ce6e126d47
5 changed files with 261 additions and 33 deletions

View file

@ -1,3 +1,27 @@
2006-08-31 Edward Hervey <edward@fluendo.com>
* docs/gst/gstreamer-sections.txt:
* gst/gstghostpad.c: (gst_proxy_pad_do_getcaps),
(gst_proxy_pad_do_setcaps), (gst_proxy_pad_set_target_unlocked),
(gst_proxy_pad_dispose), (gst_ghost_pad_new_full),
(gst_ghost_pad_new_no_target), (gst_ghost_pad_new),
(gst_ghost_pad_new_from_template),
(gst_ghost_pad_new_no_target_from_template):
* gst/gstghostpad.h:
Refactored *_new() functions.
Templates are now used as a g_object_new() parameter.
Use template in _do_getcaps() if we don't have a target.
Small documentation cleanups.
Added two new constructors:
gst_ghost_pad_new_from_template()
gst_ghost_pad_new_no_target_from_template()
* tests/check/gst/gstghostpad.c: (GST_START_TEST),
(gst_ghost_pad_suite):
Added tests for new ghostpad instanciation functions.
API additions: gst_ghost_pad_new_from_template,
gst_ghost_pad_new_no_target_from_template
2006-08-30 Stefan Kost,,, <ensonic@users.sf.net> 2006-08-30 Stefan Kost,,, <ensonic@users.sf.net>
* docs/random/ensonic/profiling.txt: * docs/random/ensonic/profiling.txt:

View file

@ -714,6 +714,8 @@ gst_format_get_type
GstGhostPad GstGhostPad
gst_ghost_pad_new gst_ghost_pad_new
gst_ghost_pad_new_no_target gst_ghost_pad_new_no_target
gst_ghost_pad_new_from_template
gst_ghost_pad_new_no_target_from_template
gst_ghost_pad_set_target gst_ghost_pad_set_target
gst_ghost_pad_get_target gst_ghost_pad_get_target
<SUBSECTION Standard> <SUBSECTION Standard>
@ -723,6 +725,7 @@ GST_IS_GHOST_PAD
GST_GHOST_PAD_CLASS GST_GHOST_PAD_CLASS
GST_IS_GHOST_PAD_CLASS GST_IS_GHOST_PAD_CLASS
GST_TYPE_GHOST_PAD GST_TYPE_GHOST_PAD
GST_GHOST_PAD_CAST
<SUBSECTION Private> <SUBSECTION Private>
gst_ghost_pad_get_type gst_ghost_pad_get_type
</SECTION> </SECTION>

View file

@ -39,6 +39,8 @@
* to create the ghost-pad and use gst_ghost_pad_set_target() to establish the * to create the ghost-pad and use gst_ghost_pad_set_target() to establish the
* association later on. * association later on.
* *
* Note that GhostPads add overhead to the data processing of a pipeline.
*
* Last reviewed on 2005-11-18 (0.9.5) * Last reviewed on 2005-11-18 (0.9.5)
*/ */
@ -51,6 +53,8 @@
#define GST_IS_PROXY_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PROXY_PAD)) #define GST_IS_PROXY_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PROXY_PAD))
#define GST_PROXY_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PROXY_PAD, GstProxyPad)) #define GST_PROXY_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PROXY_PAD, GstProxyPad))
#define GST_PROXY_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PROXY_PAD, GstProxyPadClass)) #define GST_PROXY_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PROXY_PAD, GstProxyPadClass))
#define GST_PROXY_PAD_CAST(obj) ((GstProxyPad *)obj)
#define GST_PROXY_PAD_TARGET(pad) (GST_PROXY_PAD (pad)->target) #define GST_PROXY_PAD_TARGET(pad) (GST_PROXY_PAD (pad)->target)
#define GST_PROXY_PAD_INTERNAL(pad) (GST_PROXY_PAD (pad)->internal) #define GST_PROXY_PAD_INTERNAL(pad) (GST_PROXY_PAD (pad)->internal)
@ -233,11 +237,29 @@ gst_proxy_pad_do_getcaps (GstPad * pad)
GstCaps *res; GstCaps *res;
if (target) { if (target) {
/* if we have a real target, proxy the call */
GST_DEBUG_OBJECT (pad, "get caps of target");
res = gst_pad_get_caps (target); res = gst_pad_get_caps (target);
gst_object_unref (target); gst_object_unref (target);
} else { } else {
GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);
/* else, if we have a template, use that */
if (templ) {
res = GST_PAD_TEMPLATE_CAPS (templ);
GST_DEBUG_OBJECT (pad,
"using pad template %p with caps %p %" GST_PTR_FORMAT, templ, res,
res);
res = gst_caps_ref (res);
goto done;
}
/* last resort, any caps */
GST_DEBUG_OBJECT (pad, "pad has no template, returning ANY");
res = gst_caps_new_any (); res = gst_caps_new_any ();
} }
done:
return res; return res;
} }
@ -276,10 +298,9 @@ gst_proxy_pad_do_setcaps (GstPad * pad, GstCaps * caps)
res = gst_pad_set_caps (target, caps); res = gst_pad_set_caps (target, caps);
gst_object_unref (target); gst_object_unref (target);
} else { } else {
/* /* We don't have any target, but we shouldn't return FALSE since this
We don't have any target, but we shouldn't return FALSE since this * would stop the actual push of a buffer (which might trigger a pad block
would stop the actual push of a buffer (which might trigger a pad block * or probe, or properly return GST_FLOW_NOT_LINKED.
or probe, or properly return GST_FLOW_NOT_LINKED.
*/ */
res = TRUE; res = TRUE;
} }
@ -293,11 +314,9 @@ gst_proxy_pad_set_target_unlocked (GstPad * pad, GstPad * target)
if (target) { if (target) {
GST_LOG_OBJECT (pad, "setting target %s:%s", GST_DEBUG_PAD_NAME (target)); GST_LOG_OBJECT (pad, "setting target %s:%s", GST_DEBUG_PAD_NAME (target));
if (G_UNLIKELY (GST_PAD_DIRECTION (pad) != GST_PAD_DIRECTION (target))) {
GST_ERROR_OBJECT (pad, if (G_UNLIKELY (GST_PAD_DIRECTION (pad) != GST_PAD_DIRECTION (target)))
"target pad doesn't have the same direction as ourself"); goto wrong_direction;
return FALSE;
}
} else } else
GST_LOG_OBJECT (pad, "clearing target"); GST_LOG_OBJECT (pad, "clearing target");
@ -312,6 +331,13 @@ gst_proxy_pad_set_target_unlocked (GstPad * pad, GstPad * target)
GST_PROXY_PAD_TARGET (pad) = gst_object_ref (target); GST_PROXY_PAD_TARGET (pad) = gst_object_ref (target);
return TRUE; return TRUE;
wrong_direction:
{
GST_ERROR_OBJECT (pad,
"target pad doesn't have the same direction as ourself");
return FALSE;
}
} }
static gboolean static gboolean
@ -364,9 +390,8 @@ gst_proxy_pad_dispose (GObject * object)
/* remove and unref the target */ /* remove and unref the target */
target_p = &GST_PROXY_PAD_TARGET (pad); target_p = &GST_PROXY_PAD_TARGET (pad);
gst_object_replace ((GstObject **) target_p, NULL); gst_object_replace ((GstObject **) target_p, NULL);
/* /* The internal is only cleared by GstGhostPad::dispose, since it is the
The internal is only cleared by GstGhostPad::dispose, since it is the * parent of non-ghost GstProxyPad and owns the refcount on the internal.
parent of non-ghost GstProxyPad and owns the refcount on the internal.
*/ */
GST_PROXY_UNLOCK (pad); GST_PROXY_UNLOCK (pad);
@ -757,30 +782,23 @@ gst_ghost_pad_dispose (GObject * object)
G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object); G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object);
} }
/** static GstPad *
* gst_ghost_pad_new_no_target: gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir,
* @name: the name of the new pad, or NULL to assign a default name. GstPadTemplate * templ)
* @dir: the direction of the ghostpad
*
* Create a new ghostpad without a target with the given direction.
* A target can be set on the ghostpad later with the
* gst_ghost_pad_set_target() function.
*
* The created ghostpad will not have a padtemplate.
*
* Returns: a new #GstPad, or NULL in case of an error.
*/
GstPad *
gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
{ {
GstPad *ret; GstPad *ret;
GstPad *internal; GstPad *internal;
GST_LOG ("name:%s, direction:%d", name, dir); g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL);
/* OBJECT CREATION */ /* OBJECT CREATION */
if (templ) {
ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name, "direction", dir, NULL); ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name,
"direction", dir, "template", templ, NULL);
} else {
ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name,
"direction", dir, NULL);
}
/* Set directional padfunctions for ghostpad */ /* Set directional padfunctions for ghostpad */
if (dir == GST_PAD_SINK) { if (dir == GST_PAD_SINK) {
@ -837,7 +855,7 @@ gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
This is why we don't take extra refcounts in the assignments below This is why we don't take extra refcounts in the assignments below
*/ */
GST_PROXY_PAD_INTERNAL (ret) = internal; GST_PROXY_PAD_INTERNAL (ret) = internal;
GST_PROXY_PAD_INTERNAL (GST_PROXY_PAD_INTERNAL (ret)) = GST_PAD (ret); GST_PROXY_PAD_INTERNAL (internal) = GST_PAD (ret);
/* could be more general here, iterating over all writable properties... /* could be more general here, iterating over all writable properties...
* taking the short road for now tho */ * taking the short road for now tho */
@ -855,6 +873,29 @@ beach:
return ret; return ret;
} }
/**
* gst_ghost_pad_new_no_target:
* @name: the name of the new pad, or NULL to assign a default name.
* @dir: the direction of the ghostpad
*
* Create a new ghostpad without a target with the given direction.
* A target can be set on the ghostpad later with the
* gst_ghost_pad_set_target() function.
*
* The created ghostpad will not have a padtemplate.
*
* Returns: a new #GstPad, or NULL in case of an error.
*/
GstPad *
gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
{
g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL);
GST_LOG ("name:%s, direction:%d", name, dir);
return gst_ghost_pad_new_full (name, dir, NULL);
}
/** /**
* gst_ghost_pad_new: * gst_ghost_pad_new:
* @name: the name of the new pad, or NULL to assign a default name. * @name: the name of the new pad, or NULL to assign a default name.
@ -877,9 +918,85 @@ gst_ghost_pad_new (const gchar * name, GstPad * target)
g_return_val_if_fail (GST_IS_PAD (target), NULL); g_return_val_if_fail (GST_IS_PAD (target), NULL);
g_return_val_if_fail (!gst_pad_is_linked (target), NULL); g_return_val_if_fail (!gst_pad_is_linked (target), NULL);
if ((ret = gst_ghost_pad_new_no_target (name, GST_PAD_DIRECTION (target)))) { if ((ret = gst_ghost_pad_new_no_target (name, GST_PAD_DIRECTION (target))))
gst_ghost_pad_set_target (GST_GHOST_PAD (ret), target); if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
goto set_target_failed;
return ret;
/* ERRORS */
set_target_failed:
{
gst_object_unref (ret);
return NULL;
} }
}
/**
* gst_ghost_pad_new_from_template:
* @name: the name of the new pad, or NULL to assign a default name.
* @target: the pad to ghost.
* @templ: the #GstPadTemplate to use on the ghostpad.
*
* Create a new ghostpad with @target as the target. The direction will be taken
* from the target pad. The template used on the ghostpad will be @template.
*
* Will ref the target.
*
* Returns: a new #GstPad, or NULL in case of an error.
*
* Since: 0.10.10
*/
GstPad *
gst_ghost_pad_new_from_template (const gchar * name, GstPad * target,
GstPadTemplate * templ)
{
GstPad *ret;
g_return_val_if_fail (GST_IS_PAD (target), NULL);
g_return_val_if_fail (!gst_pad_is_linked (target), NULL);
g_return_val_if_fail (templ != NULL, NULL);
g_return_val_if_fail (templ->direction == GST_PAD_DIRECTION (target), NULL);
if ((ret = gst_ghost_pad_new_full (name, GST_PAD_DIRECTION (target), templ)))
if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
goto set_target_failed;
return ret;
/* ERRORS */
set_target_failed:
{
gst_object_unref (ret);
return NULL;
}
}
/**
* gst_ghost_pad_new_no_target_from_template:
* @name: the name of the new pad, or NULL to assign a default name.
* @templ: the #GstPadTemplate to create the ghostpad from.
*
* Create a new ghostpad based on @templ, without setting a target. The
* direction will be taken from @templ.
*
* Returns: a new #GstPad, or NULL in case of an error.
*
* Since: 0.10.10
*/
GstPad *
gst_ghost_pad_new_no_target_from_template (const gchar * name,
GstPadTemplate * templ)
{
GstPad *ret;
g_return_val_if_fail (templ != NULL, NULL);
ret =
gst_ghost_pad_new_full (name, GST_PAD_TEMPLATE_DIRECTION (templ), templ);
return ret; return ret;
} }

View file

@ -36,6 +36,7 @@ G_BEGIN_DECLS
#define GST_IS_GHOST_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_GHOST_PAD)) #define GST_IS_GHOST_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_GHOST_PAD))
#define GST_GHOST_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GHOST_PAD, GstGhostPad)) #define GST_GHOST_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GHOST_PAD, GstGhostPad))
#define GST_GHOST_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GHOST_PAD, GstGhostPadClass)) #define GST_GHOST_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GHOST_PAD, GstGhostPadClass))
#define GST_GHOST_PAD_CAST(obj) ((GstGhostPad*)(obj))
/** /**
* GstGhostPad: * GstGhostPad:
@ -50,6 +51,9 @@ GType gst_ghost_pad_get_type (void);
GstPad* gst_ghost_pad_new (const gchar *name, GstPad *target); GstPad* gst_ghost_pad_new (const gchar *name, GstPad *target);
GstPad* gst_ghost_pad_new_no_target (const gchar *name, GstPadDirection dir); GstPad* gst_ghost_pad_new_no_target (const gchar *name, GstPadDirection dir);
GstPad* gst_ghost_pad_new_from_template (const gchar *name, GstPad * target, GstPadTemplate * templ);
GstPad* gst_ghost_pad_new_no_target_from_template (const gchar *name, GstPadTemplate * templ);
GstPad* gst_ghost_pad_get_target (GstGhostPad *gpad); GstPad* gst_ghost_pad_get_target (GstGhostPad *gpad);
gboolean gst_ghost_pad_set_target (GstGhostPad *gpad, GstPad *newtarget); gboolean gst_ghost_pad_set_target (GstGhostPad *gpad, GstPad *newtarget);

View file

@ -479,6 +479,84 @@ GST_START_TEST (test_ghost_pads_probes)
GST_END_TEST; GST_END_TEST;
GST_START_TEST (test_ghost_pads_new_from_template)
{
GstPad *sinkpad, *ghostpad;
GstPadTemplate *padtempl, *ghosttempl;
GstCaps *padcaps, *ghostcaps, *newcaps;
padcaps = gst_caps_from_string ("some/caps");
fail_unless (padcaps != NULL);
ghostcaps = gst_caps_from_string ("some/caps;some/other-caps");
fail_unless (ghostcaps != NULL);
padtempl = gst_pad_template_new ("padtempl", GST_PAD_SINK,
GST_PAD_ALWAYS, padcaps);
fail_unless (padtempl != NULL);
ghosttempl = gst_pad_template_new ("ghosttempl", GST_PAD_SINK,
GST_PAD_ALWAYS, ghostcaps);
sinkpad = gst_pad_new_from_template (padtempl, "sinkpad");
fail_unless (sinkpad != NULL);
ghostpad = gst_ghost_pad_new_from_template ("ghostpad", sinkpad, ghosttempl);
fail_unless (ghostpad != NULL);
/* check template is properly set */
fail_unless (GST_PAD_PAD_TEMPLATE (ghostpad) == ghosttempl);
/* check ghostpad caps are from the sinkpad */
newcaps = gst_pad_get_caps (ghostpad);
fail_unless (newcaps != NULL);
fail_unless (gst_caps_is_equal (newcaps, padcaps));
}
GST_END_TEST;
GST_START_TEST (test_ghost_pads_new_no_target_from_template)
{
GstPad *sinkpad, *ghostpad;
GstPadTemplate *padtempl, *ghosttempl;
GstCaps *padcaps, *ghostcaps, *newcaps;
padcaps = gst_caps_from_string ("some/caps");
fail_unless (padcaps != NULL);
ghostcaps = gst_caps_from_string ("some/caps;some/other-caps");
fail_unless (ghostcaps != NULL);
padtempl = gst_pad_template_new ("padtempl", GST_PAD_SINK,
GST_PAD_ALWAYS, padcaps);
fail_unless (padtempl != NULL);
ghosttempl = gst_pad_template_new ("ghosttempl", GST_PAD_SINK,
GST_PAD_ALWAYS, ghostcaps);
sinkpad = gst_pad_new_from_template (padtempl, "sinkpad");
fail_unless (sinkpad != NULL);
ghostpad = gst_ghost_pad_new_no_target_from_template ("ghostpad", ghosttempl);
fail_unless (ghostpad != NULL);
/* check template is properly set */
fail_unless (GST_PAD_PAD_TEMPLATE (ghostpad) == ghosttempl);
/* check ghostpad caps are from the ghostpad template */
newcaps = gst_pad_get_caps (ghostpad);
fail_unless (newcaps != NULL);
fail_unless (gst_caps_is_equal (newcaps, ghostcaps));
gst_caps_unref (newcaps);
fail_unless (gst_ghost_pad_set_target ((GstGhostPad *) ghostpad, sinkpad));
/* check ghostpad caps are now from the target pad */
newcaps = gst_pad_get_caps (ghostpad);
fail_unless (newcaps != NULL);
fail_unless (gst_caps_is_equal (newcaps, padcaps));
gst_caps_unref (newcaps);
}
GST_END_TEST;
Suite * Suite *
gst_ghost_pad_suite (void) gst_ghost_pad_suite (void)
{ {
@ -494,6 +572,8 @@ gst_ghost_pad_suite (void)
/* tcase_add_test (tc_chain, test_ghost_pad_notarget); */ /* tcase_add_test (tc_chain, test_ghost_pad_notarget); */
tcase_add_test (tc_chain, test_ghost_pads_block); tcase_add_test (tc_chain, test_ghost_pads_block);
tcase_add_test (tc_chain, test_ghost_pads_probes); tcase_add_test (tc_chain, test_ghost_pads_probes);
tcase_add_test (tc_chain, test_ghost_pads_new_from_template);
tcase_add_test (tc_chain, test_ghost_pads_new_no_target_from_template);
return s; return s;
} }