+2004-08-18 David Schleef <ds@schleef.org>
+
+ * docs/gst/Makefile.am: Remove --ignore-fail-on-non-empty (#150331)
+ * docs/libs/Makefile.am: same
+ * docs/gst/tmpl/gstxml.sgml: Remove GstXMLNs
+ * docs/random/ds/0.9-planning: random additions
+ * docs/random/ds/0.9-suggested-changes: same
+ * gst/gstxml.h: remove vestigal GstXMLNs definition
+
+ Preferred caps: (#147789)
+ * docs/gst/gstreamer-sections.txt: Add symbols
+ * docs/gst/tmpl/gstcaps.sgml: Add symbols
+ * gst/gstcaps.c: (gst_caps_copy), (gst_caps_free),
+ (gst_caps_append), (gst_caps_copy_1), (gst_caps_intersect),
+ (gst_caps_union), (gst_caps_save_thyself), (gst_caps_load_thyself),
+ (gst_caps_get_preferred), (gst_caps_set_preferred),
+ (gst_caps_get_structure_by_id), (gst_caps_prefer_foreach),
+ (gst_caps_use_preferred): Handle caps preferences
+ * gst/gstcaps.h: Add caps preferences
+ * gst/gstpad.c: (gst_pad_link_get_preferred),
+ (gst_pad_link_fixate), (gst_pad_link_call_link_functions),
+ (gst_pad_renegotiate), (gst_pad_guess_preferred),
+ (gst_pad_get_caps), (gst_pad_push): Use caps preferences for
+ negotiation.
+
2004-08-17 Benjamin Otte <in7y118@public.uni-hamburg.de>
* gst/autoplug/gstspideridentity.c:
echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/index.sgml' ; \
rm -f $(DESTDIR)$(TARGET_DIR)/index.sgml; \
fi)
- if test -d $(DESTDIR)$(TARGET_DIR); then rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR); fi
+ if test -d $(DESTDIR)$(TARGET_DIR); then rmdir -p $(DESTDIR)$(TARGET_DIR) 2>/dev/null; fi
#
# Require gtk-doc when making dist
gst_caps_is_simple
GST_DEBUG_CAPS
GST_STATIC_CAPS
+GST_STATIC_CAPS_PREFERRED
GstCaps
GstStaticCaps
gst_caps_new_empty
gst_caps_structure_fixate_field_nearest_int
gst_caps_structure_fixate_field_nearest_double
gst_caps_subtract
+gst_caps_get_preferred
+gst_caps_set_preferred
+gst_caps_use_preferred
<SUBSECTION Standard>
GST_CAPS
GST_IS_CAPS
@string:
+<!-- ##### MACRO GST_STATIC_CAPS_PREFERRED ##### -->
+<para>
+
+</para>
+
+@string:
+@preferred:
+
+
<!-- ##### STRUCT GstCaps ##### -->
<para>
@type:
@flags:
@structs:
+@preferred:
@_gst_reserved:
<!-- ##### STRUCT GstStaticCaps ##### -->
@caps:
@string:
+@preferred:
@_gst_reserved:
<!-- ##### FUNCTION gst_caps_new_empty ##### -->
@Returns:
+<!-- ##### FUNCTION gst_caps_get_preferred ##### -->
+<para>
+
+</para>
+
+@caps:
+@Returns:
+
+
+<!-- ##### FUNCTION gst_caps_set_preferred ##### -->
+<para>
+
+</para>
+
+@caps:
+@structure:
+
+
+<!-- ##### FUNCTION gst_caps_use_preferred ##### -->
+<para>
+
+</para>
+
+@caps:
+@Returns:
+
+
@arg1:
@arg2:
-<!-- ##### STRUCT GstXMLNs ##### -->
-<para>
-
-</para>
-
-
<!-- ##### FUNCTION gst_xml_write ##### -->
<para>
echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/index.sgml' ; \
rm -f $(DESTDIR)$(TARGET_DIR)/index.sgml; \
fi)
- if test -d $(DESTDIR)$(TARGET_DIR); then rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR); fi
+ if test -d $(DESTDIR)$(TARGET_DIR); then rmdir -p $(DESTDIR)$(TARGET_DIR) 2>/dev/null; fi
#
# Require gtk-doc when making dist
- osssink.iterate() is called
+Evil:
+
+ fakesrc ! tee ! fakesink tee0. ! never_accept_a_buffer_sink
+
+ sinesrc ! osssink videotestsrc ! ximagesink
+
+ fakesrc ! fakesink (pausing)
+
+ sinesrc ! identity ! osssink
- rename GST_TYPE_FIXED_LIST to GST_TYPE_ARRAY
+ - remove GstMemChunk
+
caps:
(Company:)
gst_caps_append_structure (newcaps, gst_structure_copy (structure));
}
+ if (caps->preferred) {
+ newcaps->preferred = gst_structure_copy (caps->preferred);
+ }
+
return newcaps;
}
g_return_if_fail (GST_IS_CAPS (caps));
+ if (caps->preferred) {
+ gst_structure_free (caps->preferred);
+ }
for (i = 0; i < caps->structs->len; i++) {
structure = gst_caps_get_structure (caps, i);
gst_structure_free (structure);
gst_caps_append_structure (caps1, structure);
}
}
+
+ if (caps2->preferred) {
+ if (caps1->preferred) {
+ gst_structure_free (caps2->preferred);
+ } else {
+ caps1->preferred = caps2->preferred;
+ }
+ }
+
g_ptr_array_free (caps2->structs, TRUE);
#ifdef USE_POISONING
memset (caps2, 0xff, sizeof (GstCaps));
gst_caps_append_structure (newcaps, gst_structure_copy (structure));
}
+ if (caps->preferred) {
+ newcaps->preferred = gst_structure_copy (caps->preferred);
+ }
+
return newcaps;
}
}
}
+ if (caps1->preferred) {
+ dest->preferred = gst_structure_copy (caps1->preferred);
+ } else if (caps2->preferred) {
+ dest->preferred = gst_structure_copy (caps2->preferred);
+ }
+
gst_caps_do_simplify (dest);
return dest;
}
dest2 = gst_caps_copy (caps2);
gst_caps_append (dest1, dest2);
+ if (caps1->preferred) {
+ dest1->preferred = gst_structure_copy (caps1->preferred);
+ } else if (caps2->preferred) {
+ dest1->preferred = gst_structure_copy (caps2->preferred);
+ }
+
gst_caps_do_simplify (dest1);
return dest1;
}
return FALSE;
}
+
+
+const GstStructure *
+gst_caps_get_preferred (const GstCaps * caps)
+{
+ g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
+
+ return caps->preferred;
+}
+
+void
+gst_caps_set_preferred (GstCaps * caps, const GstStructure * structure)
+{
+ g_return_if_fail (GST_IS_CAPS (caps));
+ g_return_if_fail (GST_IS_STRUCTURE (structure));
+
+ if (caps->preferred)
+ gst_structure_free (caps->preferred);
+ caps->preferred = gst_structure_copy (structure);
+}
+
+GstStructure *
+gst_caps_get_structure_by_id (const GstCaps * caps, GQuark id)
+{
+ int i;
+ GstStructure *structure;
+
+ g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
+
+ for (i = 0; i < gst_caps_get_size (caps); i++) {
+ structure = gst_caps_get_structure (caps, i);
+ if (structure->name == id) {
+ return structure;
+ }
+ }
+
+ return NULL;
+}
+
+static gboolean
+gst_caps_prefer_foreach (GQuark name, GValue * value, gpointer user_data)
+{
+ GstStructure *structure = (GstStructure *) user_data;
+ const GValue *svalue;
+ GValue ivalue = { 0 };
+ gboolean ret;
+
+ svalue = gst_structure_id_get_value (structure, name);
+ if (svalue == NULL)
+ return TRUE;
+
+ if (G_VALUE_TYPE (value) == G_TYPE_INT) {
+ int target = g_value_get_int (value);
+
+ gst_caps_structure_fixate_field_nearest_int (structure,
+ g_quark_to_string (name), target);
+ } else if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) {
+ double target = g_value_get_double (value);
+
+ gst_caps_structure_fixate_field_nearest_double (structure,
+ g_quark_to_string (name), target);
+ } else {
+ ret = gst_value_intersect (&ivalue, value, svalue);
+ if (ret) {
+ gst_structure_id_set_value (structure, name, &ivalue);
+ g_value_unset (&ivalue);
+ }
+ }
+ return TRUE;
+}
+
+GstCaps *
+gst_caps_use_preferred (const GstCaps * caps)
+{
+ GstCaps *pcaps;
+ GstStructure *structure;
+
+ g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
+
+ if (!caps->preferred || gst_caps_is_any (caps) || gst_caps_is_empty (caps)
+ || gst_caps_is_fixed (caps)) {
+ return gst_caps_copy (caps);
+ }
+
+ if (gst_caps_is_simple (caps)) {
+ structure = gst_caps_get_structure (caps, 0);
+ } else {
+ structure = gst_caps_get_structure_by_id (caps, caps->preferred->name);
+ }
+
+ if (structure) {
+ structure = gst_structure_copy (structure);
+
+ gst_structure_foreach (caps->preferred, gst_caps_prefer_foreach, structure);
+
+ pcaps = gst_caps_new_full (structure, NULL);
+
+ return pcaps;
+ }
+
+ /* FIXME */
+
+ return NULL;
+}
G_BEGIN_DECLS
#define GST_TYPE_CAPS (gst_caps_get_type())
-#define GST_CAPS(object) ((GstCaps*)object)
+#define GST_CAPS(object) ((GstCaps*)(object))
#define GST_IS_CAPS(object) ((object) && (GST_CAPS(object)->type == GST_TYPE_CAPS))
#define GST_CAPS_FLAGS_ANY (1 << 0)
/* string */ string, \
}
+#define GST_STATIC_CAPS_PREFERRED(string, preferred) \
+{ \
+ /* caps */ { 0 }, \
+ /* string */ string, \
+ /* preferred */ preferred, \
+}
+
typedef struct _GstCaps GstCaps;
typedef struct _GstStaticCaps GstStaticCaps;
guint16 flags;
GPtrArray *structs;
+ GstStructure *preferred;
- gpointer _gst_reserved[GST_PADDING];
+ gpointer _gst_reserved[GST_PADDING - 1];
};
struct _GstStaticCaps {
GstCaps caps;
const char *string;
- gpointer _gst_reserved[GST_PADDING];
+ const char *preferred;
+
+ gpointer _gst_reserved[GST_PADDING - 1];
};
GType gst_caps_get_type (void) G_GNUC_CONST;
const char *field_name,
double target);
+const GstStructure * gst_caps_get_preferred (const GstCaps *caps);
+void gst_caps_set_preferred (GstCaps *caps,
+ const GstStructure *structure);
+GstCaps * gst_caps_use_preferred (const GstCaps *caps);
+
+
G_END_DECLS
#endif /* __GST_CAPS_H__ */
return TRUE;
}
+static const GstStructure *
+gst_pad_link_get_preferred (GstPadLink * link)
+{
+ const GstStructure *pref;
+
+ if (link->filtercaps) {
+ pref = gst_caps_get_preferred (link->filtercaps);
+ if (pref)
+ return pref;
+ }
+
+ if (link->srccaps) {
+ pref = gst_caps_get_preferred (link->srccaps);
+ if (pref)
+ return pref;
+ }
+
+ if (link->sinkcaps) {
+ pref = gst_caps_get_preferred (link->sinkcaps);
+ if (pref)
+ return pref;
+ }
+
+ return NULL;
+}
+
static void
gst_pad_link_fixate (GstPadLink * link)
{
GstCaps *caps;
GstCaps *newcaps;
+ const GstStructure *pref;
caps = link->caps;
g_return_if_fail (caps != NULL);
g_return_if_fail (!gst_caps_is_empty (caps));
- GST_DEBUG ("trying to fixate caps %" GST_PTR_FORMAT, caps);
-
gst_caps_do_simplify (caps);
+
+ pref = gst_pad_link_get_preferred (link);
+ GST_DEBUG ("link had preferred format %" GST_PTR_FORMAT, pref);
+ if (pref) {
+ GstCaps *caps2;
+
+ gst_caps_set_preferred (caps, pref);
+ caps2 = gst_caps_use_preferred (caps);
+ GST_DEBUG ("using preferred format %" GST_PTR_FORMAT, caps2);
+ if (caps2) {
+ gst_caps_free (caps);
+ caps = caps2;
+ }
+ }
+
+ GST_DEBUG ("trying to fixate caps %" GST_PTR_FORMAT, caps);
while (!gst_caps_is_fixed (caps)) {
int i;
}
}
+ g_assert (GST_IS_PAD (link->srcpad));
+ g_assert (GST_IS_PAD (link->sinkpad));
GST_FLAG_UNSET (link->srcpad, GST_PAD_NEGOTIATING);
GST_FLAG_UNSET (link->sinkpad, GST_PAD_NEGOTIATING);
return res;
link = gst_pad_link_new ();
- link->srcpad = GST_PAD_LINK_SRC (pad);
- link->sinkpad = GST_PAD_LINK_SINK (pad);
+ link->srcpad = GST_PAD (GST_PAD_REALIZE (GST_PAD_LINK_SRC (pad)));
+ link->sinkpad = GST_PAD (GST_PAD_REALIZE (GST_PAD_LINK_SINK (pad)));
if (!gst_pad_link_ready_for_negotiation (link)) {
gst_pad_link_free (link);
return GST_RPAD_LINK (pad)->caps;
}
+static GstStructure *
+gst_pad_guess_preferred (GstPad * pad, const GstCaps * caps)
+{
+ GstCaps *prefcaps;
+ GstStructure *pref = NULL;
+
+ if (caps->preferred != NULL)
+ return NULL;
+ if (GST_RPAD_FIXATEFUNC (pad) == NULL)
+ return NULL;
+
+ GST_DEBUG ("guessing preferred format of %" GST_PTR_FORMAT, caps);
+ prefcaps = gst_caps_copy (caps);
+
+ /* help things along a bit */
+ if (!gst_caps_is_simple (prefcaps)) {
+ GstCaps *newpref;
+
+ newpref =
+ gst_caps_new_full (gst_structure_copy (gst_caps_get_structure (caps,
+ 0)), NULL);
+ gst_caps_free (prefcaps);
+ prefcaps = newpref;
+ }
+
+ while (!gst_caps_is_fixed (prefcaps)) {
+ GstCaps *newpref;
+
+ newpref = GST_RPAD_FIXATEFUNC (pad) (pad, prefcaps);
+ GST_DEBUG ("fixated to %" GST_PTR_FORMAT, newpref);
+ if (newpref) {
+ gst_caps_free (prefcaps);
+ prefcaps = newpref;
+ } else {
+ break;
+ }
+ }
+
+ if (gst_caps_is_fixed (prefcaps)) {
+ pref = gst_structure_copy (gst_caps_get_structure (prefcaps, 0));
+ }
+
+ gst_caps_free (prefcaps);
+ return pref;
+}
+
/**
* gst_pad_get_caps:
* @pad: a #GstPad to get the capabilities of.
}
}
#endif
+
+ if (caps->preferred == NULL && GST_RPAD_FIXATEFUNC (pad)) {
+ GstStructure *pref;
+
+ pref = gst_pad_guess_preferred (pad, caps);
+ if (pref) {
+ gst_caps_set_preferred (caps, pref);
+ }
+ }
+
return caps;
}
}
if (!GST_IS_EVENT (data) && !GST_PAD_IS_ACTIVE (peer)) {
g_warning ("push on peer of pad %s:%s but peer is not active",
GST_DEBUG_PAD_NAME (pad));
- return;
+ //return;
}
if (peer->chainhandler) {
gpointer _gst_reserved[GST_PADDING];
};
-typedef struct _GstXMLNs GstXMLNs;
-
struct _GstXMLClass {
GstObjectClass parent_class;