diff --git a/ChangeLog b/ChangeLog index 7dfd690d6e..32286a9f3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2004-08-18 David Schleef + + * 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 * gst/autoplug/gstspideridentity.c: diff --git a/docs/gst/Makefile.am b/docs/gst/Makefile.am index 25d0b346f0..b1a0f21321 100644 --- a/docs/gst/Makefile.am +++ b/docs/gst/Makefile.am @@ -332,7 +332,7 @@ uninstall-local: 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 diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index 98fe2044fb..e614c39cf4 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -142,6 +142,7 @@ GST_CAPS_IS_SIMPLE gst_caps_is_simple GST_DEBUG_CAPS GST_STATIC_CAPS +GST_STATIC_CAPS_PREFERRED GstCaps GstStaticCaps gst_caps_new_empty @@ -181,6 +182,9 @@ gst_caps_from_string 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 GST_CAPS GST_IS_CAPS diff --git a/docs/gst/tmpl/gstcaps.sgml b/docs/gst/tmpl/gstcaps.sgml index 4c43a70b20..10d73356a1 100644 --- a/docs/gst/tmpl/gstcaps.sgml +++ b/docs/gst/tmpl/gstcaps.sgml @@ -82,6 +82,15 @@ Structure describing sets of media formats @string: + + + + + +@string: +@preferred: + + @@ -90,6 +99,7 @@ Structure describing sets of media formats @type: @flags: @structs: +@preferred: @_gst_reserved: @@ -99,6 +109,7 @@ Structure describing sets of media formats @caps: @string: +@preferred: @_gst_reserved: @@ -454,3 +465,30 @@ Structure describing sets of media formats @Returns: + + + + + +@caps: +@Returns: + + + + + + + +@caps: +@structure: + + + + + + + +@caps: +@Returns: + + diff --git a/docs/gst/tmpl/gstxml.sgml b/docs/gst/tmpl/gstxml.sgml index ccad08d7d5..056f62e03e 100644 --- a/docs/gst/tmpl/gstxml.sgml +++ b/docs/gst/tmpl/gstxml.sgml @@ -33,12 +33,6 @@ XML save/restore operations of pipelines @arg1: @arg2: - - - - - - diff --git a/docs/libs/Makefile.am b/docs/libs/Makefile.am index 0abce001c4..a4d6ce9be2 100644 --- a/docs/libs/Makefile.am +++ b/docs/libs/Makefile.am @@ -299,7 +299,7 @@ uninstall-local: 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 diff --git a/docs/random/ds/0.9-planning b/docs/random/ds/0.9-planning index d2606bd42d..f9f60e9fc0 100644 --- a/docs/random/ds/0.9-planning +++ b/docs/random/ds/0.9-planning @@ -151,6 +151,15 @@ Example #2: - osssink.iterate() is called +Evil: + + fakesrc ! tee ! fakesink tee0. ! never_accept_a_buffer_sink + + sinesrc ! osssink videotestsrc ! ximagesink + + fakesrc ! fakesink (pausing) + + sinesrc ! identity ! osssink diff --git a/docs/random/ds/0.9-suggested-changes b/docs/random/ds/0.9-suggested-changes index 77b3a56800..0adbb83634 100644 --- a/docs/random/ds/0.9-suggested-changes +++ b/docs/random/ds/0.9-suggested-changes @@ -86,6 +86,8 @@ API: - rename GST_TYPE_FIXED_LIST to GST_TYPE_ARRAY + - remove GstMemChunk + caps: (Company:) diff --git a/gst/gstcaps.c b/gst/gstcaps.c index a7d29f39c2..9516b81024 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -210,6 +210,10 @@ gst_caps_copy (const GstCaps * caps) gst_caps_append_structure (newcaps, gst_structure_copy (structure)); } + if (caps->preferred) { + newcaps->preferred = gst_structure_copy (caps->preferred); + } + return newcaps; } @@ -228,6 +232,9 @@ gst_caps_free (GstCaps * caps) 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); @@ -302,6 +309,15 @@ gst_caps_append (GstCaps * caps1, GstCaps * caps2) 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)); @@ -442,6 +458,10 @@ gst_caps_copy_1 (const GstCaps * caps) gst_caps_append_structure (newcaps, gst_structure_copy (structure)); } + if (caps->preferred) { + newcaps->preferred = gst_structure_copy (caps->preferred); + } + return newcaps; } @@ -849,6 +869,12 @@ gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2) } } + 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; } @@ -1010,6 +1036,12 @@ gst_caps_union (const GstCaps * caps1, const GstCaps * caps2) 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; } @@ -1612,3 +1644,107 @@ gst_caps_structure_fixate_field_nearest_double (GstStructure * structure, 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; +} diff --git a/gst/gstcaps.h b/gst/gstcaps.h index 359175cce9..22bfb8ec28 100644 --- a/gst/gstcaps.h +++ b/gst/gstcaps.h @@ -26,7 +26,7 @@ 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) @@ -51,6 +51,13 @@ G_BEGIN_DECLS /* string */ string, \ } +#define GST_STATIC_CAPS_PREFERRED(string, preferred) \ +{ \ + /* caps */ { 0 }, \ + /* string */ string, \ + /* preferred */ preferred, \ +} + typedef struct _GstCaps GstCaps; typedef struct _GstStaticCaps GstStaticCaps; @@ -59,14 +66,17 @@ struct _GstCaps { 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; @@ -149,6 +159,12 @@ gboolean gst_caps_structure_fixate_field_nearest_double (GstStru 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__ */ diff --git a/gst/gstpad.c b/gst/gstpad.c index bacf31fd5a..3ff424fdf6 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1149,20 +1149,61 @@ gst_pad_link_ready_for_negotiation (GstPadLink * link) 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; @@ -1305,6 +1346,8 @@ gst_pad_link_call_link_functions (GstPadLink * link) } } + 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; @@ -1435,8 +1478,8 @@ gst_pad_renegotiate (GstPad * pad) 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); @@ -2600,6 +2643,52 @@ gst_pad_get_negotiated_caps (GstPad * pad) 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. @@ -2660,6 +2749,16 @@ gst_pad_get_caps (GstPad * pad) } } #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; } } @@ -3199,7 +3298,7 @@ gst_pad_push (GstPad * pad, GstData * data) 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) { diff --git a/gst/gstxml.h b/gst/gstxml.h index 0ab06f8de2..01518d9de9 100644 --- a/gst/gstxml.h +++ b/gst/gstxml.h @@ -52,8 +52,6 @@ struct _GstXML { gpointer _gst_reserved[GST_PADDING]; }; -typedef struct _GstXMLNs GstXMLNs; - struct _GstXMLClass { GstObjectClass parent_class;