From: Edward Hervey Date: Thu, 31 Aug 2006 10:59:11 +0000 (+0000) Subject: Refactored *_new() functions. X-Git-Tag: RELEASE-0_10_10~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ce6e126d47e30eb107caf5f4fc37a80dc805c08d;p=platform%2Fupstream%2Fgstreamer.git 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 --- diff --git a/ChangeLog b/ChangeLog index f3f145b..ab90f2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2006-08-31 Edward Hervey + + * 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,,, * docs/random/ensonic/profiling.txt: diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index faf54b9..113df16 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -714,6 +714,8 @@ gst_format_get_type GstGhostPad gst_ghost_pad_new 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_get_target @@ -723,6 +725,7 @@ GST_IS_GHOST_PAD GST_GHOST_PAD_CLASS GST_IS_GHOST_PAD_CLASS GST_TYPE_GHOST_PAD +GST_GHOST_PAD_CAST gst_ghost_pad_get_type diff --git a/gst/gstghostpad.c b/gst/gstghostpad.c index 99876f7..f418128 100644 --- a/gst/gstghostpad.c +++ b/gst/gstghostpad.c @@ -39,6 +39,8 @@ * to create the ghost-pad and use gst_ghost_pad_set_target() to establish the * association later on. * + * Note that GhostPads add overhead to the data processing of a pipeline. + * * 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_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_CAST(obj) ((GstProxyPad *)obj) + #define GST_PROXY_PAD_TARGET(pad) (GST_PROXY_PAD (pad)->target) #define GST_PROXY_PAD_INTERNAL(pad) (GST_PROXY_PAD (pad)->internal) @@ -233,11 +237,29 @@ gst_proxy_pad_do_getcaps (GstPad * pad) GstCaps *res; 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); gst_object_unref (target); } 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 (); } + +done: return res; } @@ -276,10 +298,9 @@ gst_proxy_pad_do_setcaps (GstPad * pad, GstCaps * caps) res = gst_pad_set_caps (target, caps); gst_object_unref (target); } else { - /* - 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 - or probe, or properly return GST_FLOW_NOT_LINKED. + /* 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 + * or probe, or properly return GST_FLOW_NOT_LINKED. */ res = TRUE; } @@ -293,11 +314,9 @@ gst_proxy_pad_set_target_unlocked (GstPad * pad, GstPad * target) if (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, - "target pad doesn't have the same direction as ourself"); - return FALSE; - } + + if (G_UNLIKELY (GST_PAD_DIRECTION (pad) != GST_PAD_DIRECTION (target))) + goto wrong_direction; } else 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); return TRUE; + +wrong_direction: + { + GST_ERROR_OBJECT (pad, + "target pad doesn't have the same direction as ourself"); + return FALSE; + } } static gboolean @@ -364,9 +390,8 @@ gst_proxy_pad_dispose (GObject * object) /* remove and unref the target */ target_p = &GST_PROXY_PAD_TARGET (pad); gst_object_replace ((GstObject **) target_p, NULL); - /* - The internal is only cleared by GstGhostPad::dispose, since it is the - parent of non-ghost GstProxyPad and owns the refcount on the internal. + /* The internal is only cleared by GstGhostPad::dispose, since it is the + * parent of non-ghost GstProxyPad and owns the refcount on the internal. */ GST_PROXY_UNLOCK (pad); @@ -757,30 +782,23 @@ gst_ghost_pad_dispose (GObject * object) G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object); } -/** - * 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) +static GstPad * +gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir, + GstPadTemplate * templ) { GstPad *ret; GstPad *internal; - GST_LOG ("name:%s, direction:%d", name, dir); + g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL); /* OBJECT CREATION */ - - ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name, "direction", dir, NULL); + if (templ) { + 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 */ 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 */ 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... * taking the short road for now tho */ @@ -856,6 +874,29 @@ beach: } /** + * 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: * @name: the name of the new pad, or NULL to assign a default name. * @target: the pad to ghost. @@ -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_pad_is_linked (target), NULL); - if ((ret = gst_ghost_pad_new_no_target (name, GST_PAD_DIRECTION (target)))) { - gst_ghost_pad_set_target (GST_GHOST_PAD (ret), target); + if ((ret = gst_ghost_pad_new_no_target (name, GST_PAD_DIRECTION (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; } diff --git a/gst/gstghostpad.h b/gst/gstghostpad.h index 3e19f3a..dd9dd83 100644 --- a/gst/gstghostpad.h +++ b/gst/gstghostpad.h @@ -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_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_CAST(obj) ((GstGhostPad*)(obj)) /** * 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_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); gboolean gst_ghost_pad_set_target (GstGhostPad *gpad, GstPad *newtarget); diff --git a/tests/check/gst/gstghostpad.c b/tests/check/gst/gstghostpad.c index 793dd35..f9cc49f 100644 --- a/tests/check/gst/gstghostpad.c +++ b/tests/check/gst/gstghostpad.c @@ -479,6 +479,84 @@ GST_START_TEST (test_ghost_pads_probes) 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 * 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_pads_block); 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; }