From 329b786569831c4a8f9686b4dbee23b174cb4f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Fri, 27 May 2011 15:14:32 +0100 Subject: [PATCH 1/5] tools: catch and print missing-plugin messages in gst-launch So that users get some feedback if they're using a pipeline like src ! decodebin2 ! sink and are missing an element. --- tools/gst-launch.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tools/gst-launch.c b/tools/gst-launch.c index 2b0d86245e..ea99b8f6dd 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -403,6 +403,24 @@ print_index_stats (GPtrArray * index_stats) } } +/* Kids, use the functions from libgstpbutils in gst-plugins-base in your + * own code (we can't do that here because it would introduce a circular + * dependency) */ +static gboolean +gst_is_missing_plugin_message (GstMessage * msg) +{ + if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ELEMENT || msg->structure == NULL) + return FALSE; + + return gst_structure_has_name (msg->structure, "missing-plugin"); +} + +static const gchar * +gst_missing_plugin_message_get_description (GstMessage * msg) +{ + return gst_structure_get_string (msg->structure, "name"); +} + static void print_error_message (GstMessage * msg) { @@ -821,6 +839,16 @@ event_loop (GstElement * pipeline, gboolean blocking, GstState target_state) res = ELR_INTERRUPT; goto exit; } + break; + } + case GST_MESSAGE_ELEMENT:{ + if (gst_is_missing_plugin_message (message)) { + const gchar *desc; + + desc = gst_missing_plugin_message_get_description (message); + PRINT (_("Missing element: %s\n"), desc ? desc : "(no description)"); + } + break; } default: /* just be quiet by default */ From dd6a5d81c408b3802a27907a5defcf1fa9349b5d Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Sat, 28 May 2011 09:51:45 +0300 Subject: [PATCH 2/5] docs: xref the async messages to GstStateChange --- gst/gstmessage.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gst/gstmessage.h b/gst/gstmessage.h index 0eafac52df..757b1d5bed 100644 --- a/gst/gstmessage.h +++ b/gst/gstmessage.h @@ -74,11 +74,11 @@ typedef struct _GstMessageClass GstMessageClass; * @GST_MESSAGE_SEGMENT_START posted a GST_MESSAGE_SEGMENT_DONE message. * @GST_MESSAGE_DURATION: The duration of a pipeline changed. The application * can get the new duration with a duration query. - * @GST_MESSAGE_ASYNC_START: Posted by elements when they start an ASYNC state - * change. This message is not forwarded to the application but is used + * @GST_MESSAGE_ASYNC_START: Posted by elements when they start an ASYNC + * #GstStateChange. This message is not forwarded to the application but is used * internally. Since: 0.10.13. - * @GST_MESSAGE_ASYNC_DONE: Posted by elements when they complete an ASYNC state - * change. The application will only receive this message from the toplevel + * @GST_MESSAGE_ASYNC_DONE: Posted by elements when they complete an ASYNC + * #GstStateChange. The application will only receive this message from the toplevel * pipeline. Since: 0.10.13 * @GST_MESSAGE_LATENCY: Posted by elements when their latency changes. The * application should recalculate and distribute a new latency. Since: 0.10.12 From 6c2024f88116f92a53960cb174c9754873082b02 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Sat, 28 May 2011 10:24:37 +0300 Subject: [PATCH 3/5] docs: xrefs more api around GstStateChange and GstStateChangeReturn. --- gst/gstelement.h | 51 ++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/gst/gstelement.h b/gst/gstelement.h index d391907b78..43788ed113 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -85,8 +85,8 @@ G_BEGIN_DECLS * cannot produce data in %GST_STATE_PAUSED. * This typically happens with live sources. * - * The possible return values from a state change function. Only - * @GST_STATE_CHANGE_FAILURE is a real failure. + * The possible return values from a state change function such as + * gst_element_set_state(). Only @GST_STATE_CHANGE_FAILURE is a real failure. */ typedef enum { GST_STATE_CHANGE_FAILURE = 0, @@ -195,17 +195,17 @@ typedef enum { * Streaming threads are started. * * - * Some elements might need to return ASYNC and complete the state change - * when they have enough information. It is a requirement for sinks to - * return ASYNC and complete the state change when they receive the first - * buffer or EOS event (preroll). Sinks also block the dataflow when in - * PAUSED. + * Some elements might need to return %GST_STATE_CHANGE_ASYNC and complete + * the state change when they have enough information. It is a requirement + * for sinks to return %GST_STATE_CHANGE_ASYNC and complete the state change + * when they receive the first buffer or %GST_EVENT_EOS (preroll). + * Sinks also block the dataflow when in PAUSED. * * * A pipeline resets the running_time to 0. * * - * Live sources return NO_PREROLL and don't generate data. + * Live sources return %GST_STATE_CHANGE_NO_PREROLL and don't generate data. * * * @GST_STATE_CHANGE_PAUSED_TO_PLAYING: state change from PAUSED to PLAYING. @@ -214,12 +214,12 @@ typedef enum { * Most elements ignore this state change. * * - * The pipeline selects a clock and distributes this to all the children + * The pipeline selects a #GstClock and distributes this to all the children * before setting them to PLAYING. This means that it is only alowed to - * synchronize on the clock in the PLAYING state. + * synchronize on the #GstClock in the PLAYING state. * * - * The pipeline uses the clock and the running_time to calculate the + * The pipeline uses the #GstClock and the running_time to calculate the * base_time. The base_time is distributed to all children when performing * the state change. * @@ -228,15 +228,15 @@ typedef enum { * rendering the data. * * - * Sinks can post the EOS message in the PLAYING state. It is not allowed to - * post EOS when not in the PLAYING state. + * Sinks can post %GST_MESSAGE_EOS in the PLAYING state. It is not allowed + * to post %GST_MESSAGE_EOS when not in the PLAYING state. * * * While streaming in PAUSED or PLAYING elements can create and remove * sometimes pads. * * - * Live sources start generating data and return SUCCESS. + * Live sources start generating data and return %GST_STATE_CHANGE_SUCCESS. * * * @GST_STATE_CHANGE_PLAYING_TO_PAUSED: state change from PLAYING to PAUSED. @@ -245,24 +245,25 @@ typedef enum { * Most elements ignore this state change. * * - * The pipeline calculates the running_time based on the last selected clock - * and the base_time. It stores this information to continue playback when - * going back to the PLAYING state. + * The pipeline calculates the running_time based on the last selected + * #GstClock and the base_time. It stores this information to continue + * playback when going back to the PLAYING state. * * - * Sinks unblock any clock wait calls. + * Sinks unblock any #GstClock wait calls. * * - * When a sink does not have a pending buffer to play, it returns ASYNC from - * this state change and completes the state change when it receives a new - * buffer or an EOS event. + * When a sink does not have a pending buffer to play, it returns + * %GST_STATE_CHANGE_ASYNC from this state change and completes the state + * change when it receives a new buffer or an %GST_EVENT_EOS. * * - * Any queued EOS messages are removed since they will be reposted when going - * back to the PLAYING state. The EOS messages are queued in GstBins. + * Any queued %GST_MESSAGE_EOS items are removed since they will be reposted + * when going back to the PLAYING state. The EOS messages are queued in + * #GstBin containers. * * - * Live sources stop generating data and return NO_PREROLL. + * Live sources stop generating data and return %GST_STATE_CHANGE_NO_PREROLL. * * * @GST_STATE_CHANGE_PAUSED_TO_READY : state change from PAUSED to READY. @@ -274,7 +275,7 @@ typedef enum { * Elements unblock any waits on devices * * - * Chain or get_range functions return WRONG_STATE. + * Chain or get_range functions return %GST_FLOW_WRONG_STATE. * * * The element pads are deactivated so that streaming becomes impossible and From 5442bdf31162e34f6fd0bb5e7d8b8c37c49b09d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Sun, 29 May 2011 19:28:34 +0100 Subject: [PATCH 4/5] docs: fix bugzilla URL htpp -> http https://bugzilla.gnome.org/show_bug.cgi?id=651362 --- docs/faq/general.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq/general.xml b/docs/faq/general.xml index 1e6641cf30..60e9b7ddcc 100644 --- a/docs/faq/general.xml +++ b/docs/faq/general.xml @@ -77,7 +77,7 @@ on the GStreamer project website. GStreamer aims to support every format imaginable, but that doesn't mean the developers have managed to achieve that aim yet. If a GStreamer enabled application doesn't play back your files, you can help us solve that problem -by filing an enhancement request +by filing an enhancement request bug for that format. If you have it, please provide: links to other players, preferrably Open Source and working From f304196148f4f084120299770e4c5b4cf5c6e8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 30 May 2011 07:36:58 +0200 Subject: [PATCH 5/5] caps: Fix subset check for equivalent lists and scalar values For example "{ 1 }" and "1" are not strictly equal but both are a subset of each other. Also add a unit test for this. --- gst/gststructure.c | 37 +++++++++++++++++++++++++++++++++++++ tests/check/gst/gstcaps.c | 17 +++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/gst/gststructure.c b/gst/gststructure.c index 3b2c2e4121..1f3a462f35 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -3107,11 +3107,48 @@ gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value, GstStructure *superset = user_data; GValue subtraction = { 0, }; const GValue *other; + GType ltype; if (!(other = gst_structure_id_get_value (superset, field_id))) /* field is missing in the superset => is subset */ return TRUE; + /* Special case: lists and scalar values + * "{ 1 }" and "1" subsets of each other + * but not strictly equal */ + ltype = gst_value_list_get_type (); + if (G_VALUE_HOLDS (other, ltype) && !G_VALUE_HOLDS (value, ltype)) { + const GValue *elt; + gint i, n; + gboolean all_equal = TRUE; + + n = gst_value_list_get_size (other); + for (i = 0; i < n; i++) { + elt = gst_value_list_get_value (other, 0); + if (gst_value_compare (elt, value) != GST_VALUE_EQUAL) { + all_equal = FALSE; + break; + } + } + if (all_equal) + return TRUE; + } else if (G_VALUE_HOLDS (value, ltype) && !G_VALUE_HOLDS (other, ltype)) { + const GValue *elt; + gint i, n; + gboolean all_equal = TRUE; + + n = gst_value_list_get_size (value); + for (i = 0; i < n; i++) { + elt = gst_value_list_get_value (value, 0); + if (gst_value_compare (elt, other) != GST_VALUE_EQUAL) { + all_equal = FALSE; + break; + } + } + if (all_equal) + return TRUE; + } + /* equal values are subset */ if (gst_value_compare (other, value) == GST_VALUE_EQUAL) return TRUE; diff --git a/tests/check/gst/gstcaps.c b/tests/check/gst/gstcaps.c index 235e5887fa..cd8b9d0b3b 100644 --- a/tests/check/gst/gstcaps.c +++ b/tests/check/gst/gstcaps.c @@ -367,6 +367,23 @@ GST_START_TEST (test_subset) fail_if (gst_caps_is_subset (c1, c2)); gst_caps_unref (c1); gst_caps_unref (c2); + + c1 = gst_caps_from_string ("audio/x-raw-int, channels=(int) {1}"); + c2 = gst_caps_from_string ("audio/x-raw-int, channels=(int)1"); + fail_unless (gst_caps_is_subset (c2, c1)); + fail_unless (gst_caps_is_subset (c1, c2)); + fail_unless (gst_caps_is_equal (c1, c2)); + gst_caps_unref (c1); + gst_caps_unref (c2); + + c1 = gst_caps_from_string + ("audio/x-raw-int, rate=(int)44100, channels=(int)3, endianness=(int)1234, width=(int)16, depth=(int)16, signed=(boolean)false"); + c2 = gst_caps_from_string + ("audio/x-raw-int, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], endianness=(int){ 1234, 4321 }, width=(int)16, depth=(int)[ 1, 16 ], signed=(boolean){ true, false }"); + fail_unless (gst_caps_is_subset (c1, c2)); + fail_if (gst_caps_is_subset (c2, c1)); + gst_caps_unref (c1); + gst_caps_unref (c2); } GST_END_TEST;