Merge branch 'master' into 0.11

This commit is contained in:
Sebastian Dröge 2011-05-30 07:41:13 +02:00
commit 58302cedfa
6 changed files with 113 additions and 30 deletions

View file

@ -77,7 +77,7 @@ on the GStreamer project website.
GStreamer aims to support every format imaginable, but that doesn't mean the 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 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 application doesn't play back your files, you can help us solve that problem
by <ulink url="htpp://bugzilla.gnome.org">filing an enhancement request by <ulink url="http://bugzilla.gnome.org">filing an enhancement request
bug</ulink> for that format. If you have it, please provide: bug</ulink> for that format. If you have it, please provide:
<itemizedlist> <itemizedlist>
<listitem><para>links to other players, preferrably Open Source and working <listitem><para>links to other players, preferrably Open Source and working

View file

@ -85,8 +85,8 @@ G_BEGIN_DECLS
* cannot produce data in %GST_STATE_PAUSED. * cannot produce data in %GST_STATE_PAUSED.
* This typically happens with live sources. * This typically happens with live sources.
* *
* The possible return values from a state change function. Only * The possible return values from a state change function such as
* @GST_STATE_CHANGE_FAILURE is a real failure. * gst_element_set_state(). Only @GST_STATE_CHANGE_FAILURE is a real failure.
*/ */
typedef enum { typedef enum {
GST_STATE_CHANGE_FAILURE = 0, GST_STATE_CHANGE_FAILURE = 0,
@ -195,17 +195,17 @@ typedef enum {
* Streaming threads are started. * Streaming threads are started.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* Some elements might need to return ASYNC and complete the state change * Some elements might need to return %GST_STATE_CHANGE_ASYNC and complete
* when they have enough information. It is a requirement for sinks to * the state change when they have enough information. It is a requirement
* return ASYNC and complete the state change when they receive the first * for sinks to return %GST_STATE_CHANGE_ASYNC and complete the state change
* buffer or EOS event (preroll). Sinks also block the dataflow when in * when they receive the first buffer or %GST_EVENT_EOS (preroll).
* PAUSED. * Sinks also block the dataflow when in PAUSED.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* A pipeline resets the running_time to 0. * A pipeline resets the running_time to 0.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* Live sources return NO_PREROLL and don't generate data. * Live sources return %GST_STATE_CHANGE_NO_PREROLL and don't generate data.
* </para></listitem> * </para></listitem>
* </itemizedlist> * </itemizedlist>
* @GST_STATE_CHANGE_PAUSED_TO_PLAYING: state change from PAUSED to PLAYING. * @GST_STATE_CHANGE_PAUSED_TO_PLAYING: state change from PAUSED to PLAYING.
@ -214,12 +214,12 @@ typedef enum {
* Most elements ignore this state change. * Most elements ignore this state change.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* 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 * 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.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* 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 * base_time. The base_time is distributed to all children when performing
* the state change. * the state change.
* </para></listitem> * </para></listitem>
@ -228,15 +228,15 @@ typedef enum {
* rendering the data. * rendering the data.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* Sinks can post the EOS message in the PLAYING state. It is not allowed to * Sinks can post %GST_MESSAGE_EOS in the PLAYING state. It is not allowed
* post EOS when not in the PLAYING state. * to post %GST_MESSAGE_EOS when not in the PLAYING state.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* While streaming in PAUSED or PLAYING elements can create and remove * While streaming in PAUSED or PLAYING elements can create and remove
* sometimes pads. * sometimes pads.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* Live sources start generating data and return SUCCESS. * Live sources start generating data and return %GST_STATE_CHANGE_SUCCESS.
* </para></listitem> * </para></listitem>
* </itemizedlist> * </itemizedlist>
* @GST_STATE_CHANGE_PLAYING_TO_PAUSED: state change from PLAYING to PAUSED. * @GST_STATE_CHANGE_PLAYING_TO_PAUSED: state change from PLAYING to PAUSED.
@ -245,24 +245,25 @@ typedef enum {
* Most elements ignore this state change. * Most elements ignore this state change.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* The pipeline calculates the running_time based on the last selected clock * The pipeline calculates the running_time based on the last selected
* and the base_time. It stores this information to continue playback when * #GstClock and the base_time. It stores this information to continue
* going back to the PLAYING state. * playback when going back to the PLAYING state.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* Sinks unblock any clock wait calls. * Sinks unblock any #GstClock wait calls.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* When a sink does not have a pending buffer to play, it returns ASYNC from * When a sink does not have a pending buffer to play, it returns
* this state change and completes the state change when it receives a new * %GST_STATE_CHANGE_ASYNC from this state change and completes the state
* buffer or an EOS event. * change when it receives a new buffer or an %GST_EVENT_EOS.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* Any queued EOS messages are removed since they will be reposted when going * Any queued %GST_MESSAGE_EOS items are removed since they will be reposted
* back to the PLAYING state. The EOS messages are queued in GstBins. * when going back to the PLAYING state. The EOS messages are queued in
* #GstBin containers.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* Live sources stop generating data and return NO_PREROLL. * Live sources stop generating data and return %GST_STATE_CHANGE_NO_PREROLL.
* </para></listitem> * </para></listitem>
* </itemizedlist> * </itemizedlist>
* @GST_STATE_CHANGE_PAUSED_TO_READY : state change from PAUSED to READY. * @GST_STATE_CHANGE_PAUSED_TO_READY : state change from PAUSED to READY.
@ -274,7 +275,7 @@ typedef enum {
* Elements unblock any waits on devices * Elements unblock any waits on devices
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* Chain or get_range functions return WRONG_STATE. * Chain or get_range functions return %GST_FLOW_WRONG_STATE.
* </para></listitem> * </para></listitem>
* <listitem><para> * <listitem><para>
* The element pads are deactivated so that streaming becomes impossible and * The element pads are deactivated so that streaming becomes impossible and

View file

@ -73,11 +73,11 @@ typedef struct _GstMessage GstMessage;
* @GST_MESSAGE_SEGMENT_START posted a GST_MESSAGE_SEGMENT_DONE message. * @GST_MESSAGE_SEGMENT_START posted a GST_MESSAGE_SEGMENT_DONE message.
* @GST_MESSAGE_DURATION: The duration of a pipeline changed. The application * @GST_MESSAGE_DURATION: The duration of a pipeline changed. The application
* can get the new duration with a duration query. * can get the new duration with a duration query.
* @GST_MESSAGE_ASYNC_START: Posted by elements when they start an ASYNC state * @GST_MESSAGE_ASYNC_START: Posted by elements when they start an ASYNC
* change. This message is not forwarded to the application but is used * #GstStateChange. This message is not forwarded to the application but is used
* internally. Since: 0.10.13. * internally. Since: 0.10.13.
* @GST_MESSAGE_ASYNC_DONE: Posted by elements when they complete an ASYNC state * @GST_MESSAGE_ASYNC_DONE: Posted by elements when they complete an ASYNC
* change. The application will only receive this message from the toplevel * #GstStateChange. The application will only receive this message from the toplevel
* pipeline. Since: 0.10.13 * pipeline. Since: 0.10.13
* @GST_MESSAGE_LATENCY: Posted by elements when their latency changes. The * @GST_MESSAGE_LATENCY: Posted by elements when their latency changes. The
* application should recalculate and distribute a new latency. Since: 0.10.12 * application should recalculate and distribute a new latency. Since: 0.10.12

View file

@ -3130,11 +3130,48 @@ gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
GstStructure *superset = user_data; GstStructure *superset = user_data;
GValue subtraction = { 0, }; GValue subtraction = { 0, };
const GValue *other; const GValue *other;
GType ltype;
if (!(other = gst_structure_id_get_value (superset, field_id))) if (!(other = gst_structure_id_get_value (superset, field_id)))
/* field is missing in the superset => is subset */ /* field is missing in the superset => is subset */
return TRUE; 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 */ /* equal values are subset */
if (gst_value_compare (other, value) == GST_VALUE_EQUAL) if (gst_value_compare (other, value) == GST_VALUE_EQUAL)
return TRUE; return TRUE;

View file

@ -346,6 +346,23 @@ GST_START_TEST (test_subset)
fail_if (gst_caps_is_subset (c1, c2)); fail_if (gst_caps_is_subset (c1, c2));
gst_caps_unref (c1); gst_caps_unref (c1);
gst_caps_unref (c2); 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; GST_END_TEST;

View file

@ -330,6 +330,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 static void
print_error_message (GstMessage * msg) print_error_message (GstMessage * msg)
{ {
@ -747,6 +765,16 @@ event_loop (GstElement * pipeline, gboolean blocking, GstState target_state)
res = ELR_INTERRUPT; res = ELR_INTERRUPT;
goto exit; 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: default:
/* just be quiet by default */ /* just be quiet by default */