diff --git a/ChangeLog b/ChangeLog index 93c3b27118..9f8e310337 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2004-01-04 David Schleef + + * gst/elements/gsttee.c: (gst_tee_init), (gst_tee_request_new_pad): + Remove usage of gst_pad_proxy_fixate. + * gst/gstcaps.c: (gst_caps_append), (gst_caps_append_structure), + (gst_caps_split_one), (gst_caps_replace): + Add poisoning code. + * gst/gstmarshal.list: + Add pointer__pointer for fixate signal + * gst/gstpad.c: (gst_real_pad_class_init), + (_gst_real_pad_fixate_accumulator), (gst_pad_link_fixate), + (_gst_pad_default_fixate_func), (gst_pad_proxy_fixate), + (gst_pad_set_explicit_caps), (gst_pad_template_new): + Add poisoning code. Add fixate signal on RealPad. Change + set_explicit_caps() to take const GstCaps, like try_set_caps(). + * gst/gstpad.h: + * testsuite/caps/Makefile.am: + * testsuite/caps/app_fixate.c: Add a test for the fixate signal + 2004-01-03 David Schleef * gst/elements/gsttypefindelement.c: diff --git a/gst/elements/gsttee.c b/gst/elements/gsttee.c index 55eb46e11b..c2b1cf294e 100644 --- a/gst/elements/gsttee.c +++ b/gst/elements/gsttee.c @@ -145,7 +145,6 @@ gst_tee_init (GstTee *tee) gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain)); gst_pad_set_link_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); - gst_pad_set_fixate_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_fixate)); tee->silent = FALSE; tee->last_message = NULL; @@ -205,7 +204,6 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar g_free (name); gst_pad_set_link_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); - gst_pad_set_fixate_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_fixate)); gst_element_add_pad (GST_ELEMENT (tee), srcpad); GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL; diff --git a/gst/gstcaps.c b/gst/gstcaps.c index 3d446d735f..8724ce1a50 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -24,6 +24,18 @@ #include +#define CAPS_POISON(caps) do{ \ + GstCaps *_newcaps = gst_caps_copy (caps); \ + gst_caps_free(caps); \ + caps = _newcaps; \ +} while (0) +#define STRUCTURE_POISON(structure) do{ \ + GstStructure *_newstruct = gst_structure_copy (structure); \ + gst_structure_free(structure); \ + structure = _newstruct; \ +} while (0) + + static void _gst_caps_transform_to_string (const GValue *src_value, GValue *dest_value); static void _gst_caps_value_init (GValue *value); @@ -210,6 +222,9 @@ void gst_caps_append (GstCaps *caps1, GstCaps *caps2) g_return_if_fail (caps1 != NULL); g_return_if_fail (caps2 != NULL); +#ifdef USE_POISONING + CAPS_POISON (caps2); +#endif for(i=0;istructs->len;i++){ structure = gst_caps_get_structure (caps2, i); gst_caps_append_structure (caps1, structure); @@ -225,6 +240,9 @@ void gst_caps_append_structure (GstCaps *caps, GstStructure *structure) { g_return_if_fail(caps != NULL); +#ifdef USE_POISONING + STRUCTURE_POISON (structure); +#endif if (structure){ g_ptr_array_add (caps->structs, structure); } @@ -233,6 +251,7 @@ void gst_caps_append_structure (GstCaps *caps, GstStructure *structure) GstCaps *gst_caps_split_one (GstCaps *caps) { /* FIXME */ + g_critical ("unimplemented"); return NULL; } @@ -731,6 +750,9 @@ GstCaps *gst_caps_load_thyself (xmlNodePtr parent) /* utility */ void gst_caps_replace (GstCaps **caps, GstCaps *newcaps) { +#ifdef USE_POISONING + if (newcaps) CAPS_POISON (newcaps); +#endif if (*caps) gst_caps_free(*caps); *caps = newcaps; } diff --git a/gst/gstmarshal.list b/gst/gstmarshal.list index f136fbb524..261e1ed8b3 100644 --- a/gst/gstmarshal.list +++ b/gst/gstmarshal.list @@ -14,3 +14,4 @@ VOID:UINT,BOXED VOID:UINT,POINTER BOOLEAN:VOID BOOLEAN:POINTER +POINTER:POINTER diff --git a/gst/gstpad.c b/gst/gstpad.c index d6c38cd99c..3e6ad9ee56 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -54,7 +54,7 @@ static void gst_pad_init (GstPad *pad); static void gst_pad_dispose (GObject *object); static void gst_pad_set_pad_template (GstPad *pad, GstPadTemplate *templ); -static GstCaps * _gst_pad_default_fixate_func (GstPad *pad, GstCaps *caps, gpointer unused); +static GstCaps * _gst_pad_default_fixate_func (GstPad *pad, const GstCaps *caps); static gboolean gst_pad_link_try (GstPadLink *link); static void gst_pad_link_free (GstPadLink *link); @@ -117,6 +117,7 @@ enum { REAL_CAPS_NEGO_FAILED, REAL_LINKED, REAL_UNLINKED, + REAL_FIXATE, /* FILL ME */ REAL_LAST_SIGNAL }; @@ -132,6 +133,8 @@ static void gst_real_pad_class_init (GstRealPadClass *klass); static void gst_real_pad_init (GstRealPad *pad); static void gst_real_pad_dispose (GObject *object); +static gboolean _gst_real_pad_fixate_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, const GValue *handler_return, gpointer dummy); static void gst_real_pad_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); @@ -190,6 +193,12 @@ gst_real_pad_class_init (GstRealPadClass *klass) G_STRUCT_OFFSET (GstRealPadClass, unlinked), NULL, NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD); + gst_real_pad_signals[REAL_FIXATE] = + g_signal_new ("fixate", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstRealPadClass, appfixatefunc), + _gst_real_pad_fixate_accumulator, NULL, + gst_marshal_POINTER__POINTER, G_TYPE_POINTER, 1, + G_TYPE_POINTER); /* gtk_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */ /* GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */ @@ -206,6 +215,17 @@ gst_real_pad_class_init (GstRealPadClass *klass) gstobject_class->path_string_separator = "."; } +static gboolean +_gst_real_pad_fixate_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, const GValue *handler_return, gpointer dummy) +{ + if (g_value_get_pointer (handler_return)) { + /* stop emission if something was returned */ + return FALSE; + } + return TRUE; +} + static void gst_real_pad_init (GstRealPad *pad) { @@ -1059,37 +1079,48 @@ gst_pad_link_fixate (GstPadLink *link) GST_DEBUG_CAPS ("trying to fixate caps", caps); while (!gst_caps_is_fixed (caps)) { - if (link->app_fixate) { - newcaps = (link->app_fixate) (GST_PAD (link->srcpad), caps, NULL); - if (newcaps) { - caps = newcaps; - GST_DEBUG_CAPS ("app fixated to", caps); - continue; - } - } - if (GST_RPAD_FIXATEFUNC(link->srcpad)) { - newcaps = GST_RPAD_FIXATEFUNC(link->srcpad) (GST_PAD (link->srcpad), - caps, NULL); - if (newcaps) { - caps = newcaps; - GST_DEBUG_CAPS ("src pad fixated to", caps); - continue; - } - } - if (GST_RPAD_FIXATEFUNC(link->sinkpad)) { - newcaps = GST_RPAD_FIXATEFUNC(link->sinkpad) (GST_PAD (link->sinkpad), - caps, NULL); - if (newcaps) { - caps = newcaps; - GST_DEBUG_CAPS ("sink pad fixated to", caps); - continue; - } - } - caps = _gst_pad_default_fixate_func (GST_PAD(link->srcpad), caps, NULL); - GST_DEBUG_CAPS ("core fixated to", caps); - } + int i; - GST_DEBUG_CAPS ("fixate decided on", caps); + for (i=0;i<5;i++){ + newcaps = NULL; + switch (i) { + case 0: + g_signal_emit (G_OBJECT (link->srcpad), + gst_real_pad_signals[REAL_FIXATE], 0, caps, &newcaps); + GST_DEBUG_CAPS ("app srcpad signal fixated to", newcaps); + break; + case 1: + g_signal_emit (G_OBJECT (link->sinkpad), + gst_real_pad_signals[REAL_FIXATE], 0, caps, &newcaps); + GST_DEBUG_CAPS ("app sinkpad signal fixated to", newcaps); + break; + case 2: + if (GST_RPAD_FIXATEFUNC(link->srcpad)) { + newcaps = GST_RPAD_FIXATEFUNC(link->srcpad) ( + GST_PAD (link->srcpad), caps); + GST_DEBUG_CAPS ("srcpad fixated to", newcaps); + } + break; + case 3: + if (GST_RPAD_FIXATEFUNC(link->sinkpad)) { + newcaps = GST_RPAD_FIXATEFUNC(link->sinkpad) ( + GST_PAD (link->sinkpad), caps); + GST_DEBUG_CAPS ("sinkpad fixated to", newcaps); + } + break; + case 4: + newcaps = _gst_pad_default_fixate_func ( + GST_PAD(link->srcpad), caps); + GST_DEBUG_CAPS ("core fixated to", newcaps); + break; + } + if (newcaps) { + gst_caps_free (caps); + caps = newcaps; + break; + } + } + } link->caps = caps; } @@ -1809,32 +1840,32 @@ _gst_pad_default_fixate_foreach (GQuark field_id, GValue *value, } static GstCaps * -_gst_pad_default_fixate_func (GstPad *pad, GstCaps *caps, gpointer unused) +_gst_pad_default_fixate_func (GstPad *pad, const GstCaps *caps) { static GstStaticCaps octetcaps = GST_STATIC_CAPS ( "application/octet-stream"); GstStructure *structure; + GstCaps *newcaps; g_return_val_if_fail (pad != NULL, NULL); g_return_val_if_fail (caps != NULL, NULL); g_return_val_if_fail (!gst_caps_is_empty (caps), NULL); if (gst_caps_is_any (caps)) { - gst_caps_free (caps); return gst_caps_copy (gst_static_caps_get (&octetcaps)); } if (caps->structs->len > 1) { GstCaps *retcaps = gst_caps_copy_1 (caps); - gst_caps_free (caps); return retcaps; } - structure = gst_caps_get_structure (caps, 0); + newcaps = gst_caps_copy (caps); + structure = gst_caps_get_structure (newcaps, 0); gst_structure_foreach (structure, _gst_pad_default_fixate_foreach, structure); - return caps; + return newcaps; } /** @@ -2080,7 +2111,7 @@ gst_pad_proxy_pad_link (GstPad *pad, const GstCaps *caps) * Returns: a fixated caps, or NULL if caps cannot be fixed */ GstCaps * -gst_pad_proxy_fixate (GstPad *pad, const GstCaps *caps, gpointer unused) +gst_pad_proxy_fixate (GstPad *pad, const GstCaps *caps) { GstElement *element; const GList *pads; @@ -2132,7 +2163,7 @@ gst_pad_proxy_fixate (GstPad *pad, const GstCaps *caps, gpointer unused) * Returns: TRUE if the caps were set correctly, otherwise FALSE */ gboolean -gst_pad_set_explicit_caps (GstPad *pad, GstCaps *caps) +gst_pad_set_explicit_caps (GstPad *pad, const GstCaps *caps) { GstPadLinkReturn link_ret; @@ -2141,12 +2172,13 @@ gst_pad_set_explicit_caps (GstPad *pad, GstCaps *caps) GST_CAT_DEBUG (GST_CAT_PADS, "setting explicit caps to %s", gst_caps_to_string (caps)); - gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), caps); - if (caps == NULL) { GST_CAT_DEBUG (GST_CAT_PADS, "caps is NULL"); + gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL); return TRUE; } + + gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), gst_caps_copy(caps)); if (!GST_PAD_IS_LINKED (pad)) { GST_CAT_DEBUG (GST_CAT_PADS, "pad is not linked"); @@ -3114,6 +3146,15 @@ gst_pad_template_new (const gchar *name_template, if (!name_is_valid (name_template, presence)) return NULL; +#if 0 +#ifdef USE_POISONING + if (caps) { + GstCaps *newcaps = gst_caps_copy (caps); + gst_caps_free(caps); + caps = newcaps; + } +#endif +#endif new = g_object_new (gst_pad_template_get_type (), "name", name_template, NULL); diff --git a/gst/gstpad.h b/gst/gstpad.h index 8e46c4eb68..c0efb0f83f 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -124,7 +124,7 @@ typedef const GstQueryType* (*GstPadQueryTypeFunction) (GstPad *pad); typedef GstPadLinkReturn (*GstPadLinkFunction) (GstPad *pad, const GstCaps *caps); typedef void (*GstPadUnlinkFunction) (GstPad *pad); typedef GstCaps* (*GstPadGetCapsFunction) (GstPad *pad); -typedef GstCaps* (*GstPadFixateFunction) (GstPad *pad, const GstCaps *caps, gpointer user_data); +typedef GstCaps* (*GstPadFixateFunction) (GstPad *pad, const GstCaps *caps); typedef GstBuffer* (*GstPadBufferAllocFunction) (GstPad *pad, guint64 offset, guint size); typedef gboolean (*GstPadDispatcherFunction) (GstPad *pad, gpointer data); @@ -212,8 +212,9 @@ struct _GstRealPadClass { void (*linked) (GstPad *pad, GstPad *peer); void (*unlinked) (GstPad *pad, GstPad *peer); + GstPadFixateFunction appfixatefunc; - gpointer _gst_reserved[GST_PADDING]; + gpointer _gst_reserved[GST_PADDING - 1]; }; struct _GstGhostPad { @@ -414,11 +415,11 @@ void gst_pad_set_getcaps_function (GstPad *pad, GstPadGetCapsFunction getcaps void gst_pad_set_fixate_function (GstPad *pad, GstPadFixateFunction fixate); GstCaps * gst_pad_proxy_getcaps (GstPad *pad); GstPadLinkReturn gst_pad_proxy_pad_link (GstPad *pad, const GstCaps *caps); -GstCaps * gst_pad_proxy_fixate (GstPad *pad, const GstCaps *caps, gpointer unused); +GstCaps * gst_pad_proxy_fixate (GstPad *pad, const GstCaps *caps); #ifndef GST_DISABLE_DEPRECATED GstPadLinkReturn gst_pad_proxy_link (GstPad *pad, const GstCaps *caps); #endif -gboolean gst_pad_set_explicit_caps (GstPad *pad, GstCaps *caps); +gboolean gst_pad_set_explicit_caps (GstPad *pad, const GstCaps *caps); void gst_pad_use_explicit_caps (GstPad *pad); gboolean gst_pad_relink_filtered (GstPad *srcpad, GstPad *sinkpad, const GstCaps *filtercaps); #ifndef GST_DISABLE_DEPRECATED diff --git a/plugins/elements/gsttee.c b/plugins/elements/gsttee.c index 55eb46e11b..c2b1cf294e 100644 --- a/plugins/elements/gsttee.c +++ b/plugins/elements/gsttee.c @@ -145,7 +145,6 @@ gst_tee_init (GstTee *tee) gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain)); gst_pad_set_link_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); - gst_pad_set_fixate_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_fixate)); tee->silent = FALSE; tee->last_message = NULL; @@ -205,7 +204,6 @@ gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar g_free (name); gst_pad_set_link_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); - gst_pad_set_fixate_function (srcpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_fixate)); gst_element_add_pad (GST_ELEMENT (tee), srcpad); GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL; diff --git a/tests/old/testsuite/caps/Makefile.am b/tests/old/testsuite/caps/Makefile.am index aad5b07d9c..10d217aa1a 100644 --- a/tests/old/testsuite/caps/Makefile.am +++ b/tests/old/testsuite/caps/Makefile.am @@ -2,6 +2,7 @@ include ../Rules tests_pass = \ + app_fixate \ intersection \ compatibility \ normalisation \ @@ -16,6 +17,8 @@ tests_pass = \ tests_fail = +app_fixate_LDADD = $(GST_LIBS) +app_fixate_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) intersection_LDADD = $(GST_LIBS) intersection_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) compatibility_LDADD = $(GST_LIBS) diff --git a/tests/old/testsuite/caps/app_fixate.c b/tests/old/testsuite/caps/app_fixate.c new file mode 100644 index 0000000000..fbaea42166 --- /dev/null +++ b/tests/old/testsuite/caps/app_fixate.c @@ -0,0 +1,52 @@ + +#include + + +static GstCaps * +handler (GObject *object, GstCaps *caps, gpointer user_data) +{ + g_print("in handler %p, %p, %p\n", object, caps, user_data); + + g_assert (GST_IS_PAD(object)); + + g_print("caps: %s\n", gst_caps_to_string(caps)); + + if (gst_caps_is_any (caps)) { + return gst_caps_new_simple ("application/x-foo", + "field", GST_TYPE_INT_RANGE, 1, 10, NULL); + } + + return NULL; +} + + +int +main (int argc, char *argv[]) +{ + GstElement *a; + GstElement *b; + GstElement *pipeline; + GstPad *pad; + + gst_init(&argc, &argv); + + pipeline = gst_pipeline_new (NULL); + + a = gst_element_factory_make ("fakesrc", NULL); + g_assert (a); + b = gst_element_factory_make ("fakesink", NULL); + g_assert (b); + + gst_bin_add_many (GST_BIN (pipeline), a,b, NULL); + gst_element_link (a,b); + + pad = gst_element_get_pad (a, "src"); + g_signal_connect (G_OBJECT (pad), "fixate", G_CALLBACK (handler), + (void *)0xdeadbeef); + + gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); + + + return 0; +} + diff --git a/testsuite/caps/Makefile.am b/testsuite/caps/Makefile.am index aad5b07d9c..10d217aa1a 100644 --- a/testsuite/caps/Makefile.am +++ b/testsuite/caps/Makefile.am @@ -2,6 +2,7 @@ include ../Rules tests_pass = \ + app_fixate \ intersection \ compatibility \ normalisation \ @@ -16,6 +17,8 @@ tests_pass = \ tests_fail = +app_fixate_LDADD = $(GST_LIBS) +app_fixate_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) intersection_LDADD = $(GST_LIBS) intersection_CFLAGS = $(GST_CFLAGS) $(XML_CFLAGS) compatibility_LDADD = $(GST_LIBS) diff --git a/testsuite/caps/app_fixate.c b/testsuite/caps/app_fixate.c new file mode 100644 index 0000000000..fbaea42166 --- /dev/null +++ b/testsuite/caps/app_fixate.c @@ -0,0 +1,52 @@ + +#include + + +static GstCaps * +handler (GObject *object, GstCaps *caps, gpointer user_data) +{ + g_print("in handler %p, %p, %p\n", object, caps, user_data); + + g_assert (GST_IS_PAD(object)); + + g_print("caps: %s\n", gst_caps_to_string(caps)); + + if (gst_caps_is_any (caps)) { + return gst_caps_new_simple ("application/x-foo", + "field", GST_TYPE_INT_RANGE, 1, 10, NULL); + } + + return NULL; +} + + +int +main (int argc, char *argv[]) +{ + GstElement *a; + GstElement *b; + GstElement *pipeline; + GstPad *pad; + + gst_init(&argc, &argv); + + pipeline = gst_pipeline_new (NULL); + + a = gst_element_factory_make ("fakesrc", NULL); + g_assert (a); + b = gst_element_factory_make ("fakesink", NULL); + g_assert (b); + + gst_bin_add_many (GST_BIN (pipeline), a,b, NULL); + gst_element_link (a,b); + + pad = gst_element_get_pad (a, "src"); + g_signal_connect (G_OBJECT (pad), "fixate", G_CALLBACK (handler), + (void *)0xdeadbeef); + + gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); + + + return 0; +} +