+2004-01-04 David Schleef <ds@schleef.org>
+
+ * 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 <ds@schleef.org>
* gst/elements/gsttypefindelement.c:
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;
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;
#include <gst/gst.h>
+#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);
g_return_if_fail (caps1 != NULL);
g_return_if_fail (caps2 != NULL);
+#ifdef USE_POISONING
+ CAPS_POISON (caps2);
+#endif
for(i=0;i<caps2->structs->len;i++){
structure = gst_caps_get_structure (caps2, i);
gst_caps_append_structure (caps1, structure);
{
g_return_if_fail(caps != NULL);
+#ifdef USE_POISONING
+ STRUCTURE_POISON (structure);
+#endif
if (structure){
g_ptr_array_add (caps->structs, structure);
}
GstCaps *gst_caps_split_one (GstCaps *caps)
{
/* FIXME */
+ g_critical ("unimplemented");
return NULL;
}
/* 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;
}
VOID:UINT,POINTER
BOOLEAN:VOID
BOOLEAN:POINTER
+POINTER:POINTER
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);
REAL_CAPS_NEGO_FAILED,
REAL_LINKED,
REAL_UNLINKED,
+ REAL_FIXATE,
/* FILL ME */
REAL_LAST_SIGNAL
};
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);
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); */
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)
{
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;
+ int i;
+
+ 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 (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;
+ gst_caps_free (caps);
+ caps = newcaps;
+ break;
}
}
- caps = _gst_pad_default_fixate_func (GST_PAD(link->srcpad), caps, NULL);
- GST_DEBUG_CAPS ("core fixated to", caps);
}
- GST_DEBUG_CAPS ("fixate decided on", caps);
-
link->caps = caps;
}
}
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;
}
/**
* 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;
* 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;
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");
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);
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);
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 {
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
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;
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;
tests_pass = \
+ app_fixate \
intersection \
compatibility \
normalisation \
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)
--- /dev/null
+
+#include <gst/gst.h>
+
+
+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;
+}
+
tests_pass = \
+ app_fixate \
intersection \
compatibility \
normalisation \
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)
--- /dev/null
+
+#include <gst/gst.h>
+
+
+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;
+}
+