From 97ec47cabb1eb2280cf14f334f4264d5cb7e6a88 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 13 Oct 2008 17:19:25 +0000 Subject: [PATCH] docs/design/part-TODO.txt: Remove item from the todo list because it was fixed with the latency state change rewrites. Original commit message from CVS: * docs/design/part-TODO.txt: Remove item from the todo list because it was fixed with the latency state change rewrites. * docs/design/part-seeking.txt: * docs/design/part-segments.txt: Update some docs. * gst/gstevent.c: (gst_event_new_new_segment_full), (gst_event_parse_new_segment_full), (gst_event_new_buffer_size), (gst_event_parse_buffer_size), (gst_event_new_qos), (gst_event_parse_qos), (gst_event_new_seek), (gst_event_parse_seek), (gst_event_new_latency), (gst_event_parse_latency): Use quarks to construct and parse events. * gst/gstquark.c: (_priv_gst_quarks_initialize): * gst/gstquark.h: Add some more quarks to the table. Emit a warning when the quark tables are not in sync. * tests/check/gst/gstbus.c: (GST_START_TEST): Add an assert. --- ChangeLog | 26 +++++ docs/design/part-TODO.txt | 6 -- docs/design/part-seeking.txt | 57 +++++++---- docs/design/part-segments.txt | 16 ++- gst/gstevent.c | 181 +++++++++++++++++++++++----------- gst/gstquark.c | 9 +- gst/gstquark.h | 17 +++- tests/check/gst/gstbus.c | 1 + 8 files changed, 224 insertions(+), 89 deletions(-) diff --git a/ChangeLog b/ChangeLog index a64224549b..64a12a2d32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2008-10-13 Wim Taymans + + * docs/design/part-TODO.txt: + Remove item from the todo list because it was fixed with the latency + state change rewrites. + + * docs/design/part-seeking.txt: + * docs/design/part-segments.txt: + Update some docs. + + * gst/gstevent.c: (gst_event_new_new_segment_full), + (gst_event_parse_new_segment_full), (gst_event_new_buffer_size), + (gst_event_parse_buffer_size), (gst_event_new_qos), + (gst_event_parse_qos), (gst_event_new_seek), + (gst_event_parse_seek), (gst_event_new_latency), + (gst_event_parse_latency): + Use quarks to construct and parse events. + + * gst/gstquark.c: (_priv_gst_quarks_initialize): + * gst/gstquark.h: + Add some more quarks to the table. + Emit a warning when the quark tables are not in sync. + + * tests/check/gst/gstbus.c: (GST_START_TEST): + Add an assert. + 2008-10-13 Stefan Kost * plugins/elements/Makefile.am: diff --git a/docs/design/part-TODO.txt b/docs/design/part-TODO.txt index ed1c356663..1278a64901 100644 --- a/docs/design/part-TODO.txt +++ b/docs/design/part-TODO.txt @@ -59,12 +59,6 @@ API/ABI - Make serialisation of structures more consistent, readable and nicer code-wise. -- When a seekable live source does a flushing seek, it needs a new base_time to - timestamp new data. The pipeline however does not know that there is a live - source in the pipeline and thus does not select a new base_time automatically. - There needs to be a mechanism for a live source to request a new base_time or - pipeline restart. - - pad block has several issues: * can't block on selected things, like push, pull, pad_alloc, events, ... * can't check why the block happened. We should also be able to get the item/ diff --git a/docs/design/part-seeking.txt b/docs/design/part-seeking.txt index 76c2e9a0bd..6a0f2d46bc 100644 --- a/docs/design/part-seeking.txt +++ b/docs/design/part-seeking.txt @@ -2,46 +2,63 @@ Seeking ------- Seeking in GStreamer means configuring the pipeline for playback of the -media between a certain start and stop time, called a segment. +media between a certain start and stop time, called a segment. By default a +pipeline will play from position 0 to the total duration of the media at a rate +of 1.0. -Different kinds of seeking exist: +A seek is performed by sending a seek event to the sink elements of a +pipeline. Sending the seek event to a bin will by default forward +the event to all sinks in the bin. - - immediate seeking with low latency (FLUSH seek) - - seeking without flush, playback will start from the new - position after all the queues are emptied with old data. - - segment seeking with and without FLUSH, this can be used to - implement seamless looping or NLE functionality. +When performing a seek, the start and stop values of the segment can be +specified as absoulte positions or relative to the currently configured +playback segment. Note that it is not possible to seek relative to the current +playback position. + +Feedback of the seek operation can be immediatly using the GST_SEEK_FLAG_FLUSH +flag. With this flag, all pending data in the pipeline is discarded and playback +starts from the new position immediatly. + +When the FLUSH flag is not set, the seek will be queued and executed as +soon as possible, which might be after all queues are emptied. Seeking can be performed in different formats such as time, frames or samples. -Seeking can be performed to an absolute position or relative to the -currently configured segment. +The seeking can be performed to a nearby key unit or to the exact +(estimated) unit in the media (GST_SEEK_FLAG_KEY_UNIT). -For seeking to work reliably, all plugins in the pipeline need to follow -the well-defined rules in this document. +The seeking can be performed by using an estimated target position or in an +accurate way (GST_SEEK_FLAG_ACCURATE). For some formats this can result in +having to scan the complete file in order to accurately find the target unit. Non segment seeking will make the pipeline emit EOS when the configured segment has been played. -Segment seeking will not emit an EOS at the end of the range but will -post a SEGMENT_DONE message on the bus. This message is posted by the -earliest element in the pipeline, typically a demuxer. After receiving -the message, the application can reconnect the pipeline or issue other -seek events in the pipeline. Since the message is posted as early as -possible in the pipeline, the application has some time to issue a new -seek to make the transition seamless. Typically the allowed delay is -defined by the buffer sizes of the sinks as well as the size of any -queues in the pipeline. +Segment seeking (using the GST_SEEK_FLAG_SEGMENT) will not emit an EOS at +the end of the playback segment but will post a SEGMENT_DONE message on the +bus. This message is posted by the element driving the playback in the +pipeline, typically a demuxer. After receiving the message, the application +can reconnect the pipeline or issue other seek events in the pipeline. +Since the message is posted as early as possible in the pipeline, the +application has some time to issue a new seek to make the transition seamless. +Typically the allowed delay is defined by the buffer sizes of the sinks as well +as the size of any queues in the pipeline. The seek can also change the playback speed of the configured segment. A speed of 1.0 is normal speed, 2.0 is double speed. Negative values mean backward playback. +When performing a seek with a playback rate different from 1.0, the +GST_SEEK_FLAG_SKIP flag can be used to instruct decoders and demuxers that they +are allowed to skip decoding. This can be useful when resource consumption is +more important than accurately producing all frames. + Generating seeking events ------------------------- +A seek event is created with gst_event_new_seek (). diff --git a/docs/design/part-segments.txt b/docs/design/part-segments.txt index 7d57b71fad..afd0eb4cc9 100644 --- a/docs/design/part-segments.txt +++ b/docs/design/part-segments.txt @@ -38,6 +38,13 @@ Use case: FLUSHING seek When doing a seek in this pipeline for a segment 1 to 5 seconds, avidemux will perform the seek. + Avidemux starts by sending a FLUSH_START event downstream and upstream. This + will cause its streaming task to PAUSED because _pad_pull_range() and + _pad_push() will return WRONG_STATE. It then waits for the STREAM_LOCK, + which will be unlocked when the streaming task pauses. At this point no + streaming is happening anymore in the pipeline and a FLUSH_STOP is sent + upstream and downstream. + When avidemux starts playback of the segment from second 1 to 5, it pushes out a newsegment with 1 and 5 as start and stop times. The stream_time in the newsegment is also 1 as this is the position we seek to. @@ -57,18 +64,21 @@ Use case: FLUSHING seek When it reaches timestamp 5, it does not decode and push frames anymore. The video sink receives a frame of timestamp 1. It takes the start value of - the previous newsegment and aplies the folowing formula: + the previous newsegment and aplies the folowing (simplified) formula: render_time = BUFFER_TIMESTAMP - segment_start + element->base_time - It then syncs against the clock with this render_time. Not that + It then syncs against the clock with this render_time. Note that BUFFER_TIMESTAMP is always >= segment_start or else it would fall outside of the configure segment. - Videosink reports its current position as: + Videosink reports its current position as (simplified): current_position = clock_time - element->base_time + segment_time + See part-synchronisation.txt for a more detailed and accurate explanation of + synchronisation and position reporting. + Since after a flushing seek the stream_time is reset to 0, the new buffer will be rendered immediatly after the seek and the current_position will be the stream_time of the seek that was performed. diff --git a/gst/gstevent.c b/gst/gstevent.c index 8f27e908f1..f0af81dc07 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -83,6 +83,7 @@ #include "gstevent.h" #include "gstenumtypes.h" #include "gstutils.h" +#include "gstquark.h" static void gst_event_init (GTypeInstance * instance, gpointer g_class); static void gst_event_class_init (gpointer g_class, gpointer class_data); @@ -545,6 +546,9 @@ gst_event_new_new_segment_full (gboolean update, gdouble rate, gdouble applied_rate, GstFormat format, gint64 start, gint64 stop, gint64 position) { + GstEvent *event; + GstStructure *structure; + g_return_val_if_fail (rate != 0.0, NULL); g_return_val_if_fail (applied_rate != 0.0, NULL); @@ -568,15 +572,18 @@ gst_event_new_new_segment_full (gboolean update, gdouble rate, if (stop != -1) g_return_val_if_fail (start <= stop, NULL); - return gst_event_new_custom (GST_EVENT_NEWSEGMENT, - gst_structure_new ("GstEventNewsegment", - "update", G_TYPE_BOOLEAN, update, - "rate", G_TYPE_DOUBLE, rate, - "applied_rate", G_TYPE_DOUBLE, applied_rate, - "format", GST_TYPE_FORMAT, format, - "start", G_TYPE_INT64, start, - "stop", G_TYPE_INT64, stop, - "position", G_TYPE_INT64, position, NULL)); + structure = gst_structure_empty_new ("GstEventNewsegment"); + gst_structure_id_set (structure, + GST_QUARK (UPDATE), G_TYPE_BOOLEAN, update, + GST_QUARK (RATE), G_TYPE_DOUBLE, rate, + GST_QUARK (APPLIED_RATE), G_TYPE_DOUBLE, applied_rate, + GST_QUARK (FORMAT), GST_TYPE_FORMAT, format, + GST_QUARK (START), G_TYPE_INT64, start, + GST_QUARK (STOP), G_TYPE_INT64, stop, + GST_QUARK (POSITION), G_TYPE_INT64, position, NULL); + event = gst_event_new_custom (GST_EVENT_NEWSEGMENT, structure); + + return event; } /** @@ -609,22 +616,32 @@ gst_event_parse_new_segment_full (GstEvent * event, gboolean * update, structure = gst_event_get_structure (event); if (G_LIKELY (update)) *update = - g_value_get_boolean (gst_structure_get_value (structure, "update")); + g_value_get_boolean (gst_structure_id_get_value (structure, + GST_QUARK (UPDATE))); if (G_LIKELY (rate)) - *rate = g_value_get_double (gst_structure_get_value (structure, "rate")); + *rate = + g_value_get_double (gst_structure_id_get_value (structure, + GST_QUARK (RATE))); if (G_LIKELY (applied_rate)) *applied_rate = - g_value_get_double (gst_structure_get_value (structure, - "applied_rate")); + g_value_get_double (gst_structure_id_get_value (structure, + GST_QUARK (APPLIED_RATE))); if (G_LIKELY (format)) - *format = g_value_get_enum (gst_structure_get_value (structure, "format")); + *format = + g_value_get_enum (gst_structure_id_get_value (structure, + GST_QUARK (FORMAT))); if (G_LIKELY (start)) - *start = g_value_get_int64 (gst_structure_get_value (structure, "start")); + *start = + g_value_get_int64 (gst_structure_id_get_value (structure, + GST_QUARK (START))); if (G_LIKELY (stop)) - *stop = g_value_get_int64 (gst_structure_get_value (structure, "stop")); + *stop = + g_value_get_int64 (gst_structure_id_get_value (structure, + GST_QUARK (STOP))); if (G_LIKELY (position)) *position = - g_value_get_int64 (gst_structure_get_value (structure, "position")); + g_value_get_int64 (gst_structure_id_get_value (structure, + GST_QUARK (POSITION))); } /** @@ -679,17 +696,23 @@ GstEvent * gst_event_new_buffer_size (GstFormat format, gint64 minsize, gint64 maxsize, gboolean async) { + GstEvent *event; + GstStructure *structure; + GST_CAT_INFO (GST_CAT_EVENT, "creating buffersize format %s, minsize %" G_GINT64_FORMAT ", maxsize %" G_GINT64_FORMAT ", async %d", gst_format_get_name (format), minsize, maxsize, async); - return gst_event_new_custom (GST_EVENT_BUFFERSIZE, - gst_structure_new ("GstEventBufferSize", - "format", GST_TYPE_FORMAT, format, - "minsize", G_TYPE_INT64, minsize, - "maxsize", G_TYPE_INT64, maxsize, - "async", G_TYPE_BOOLEAN, async, NULL)); + structure = gst_structure_empty_new ("GstEventBufferSize"); + gst_structure_id_set (structure, + GST_QUARK (FORMAT), GST_TYPE_FORMAT, format, + GST_QUARK (MINSIZE), G_TYPE_INT64, minsize, + GST_QUARK (MAXSIZE), G_TYPE_INT64, maxsize, + GST_QUARK (ASYNC), G_TYPE_BOOLEAN, async, NULL); + event = gst_event_new_custom (GST_EVENT_BUFFERSIZE, structure); + + return event; } /** @@ -713,15 +736,21 @@ gst_event_parse_buffer_size (GstEvent * event, GstFormat * format, structure = gst_event_get_structure (event); if (format) - *format = g_value_get_enum (gst_structure_get_value (structure, "format")); + *format = + g_value_get_enum (gst_structure_id_get_value (structure, + GST_QUARK (FORMAT))); if (minsize) *minsize = - g_value_get_int64 (gst_structure_get_value (structure, "minsize")); + g_value_get_int64 (gst_structure_id_get_value (structure, + GST_QUARK (MINSIZE))); if (maxsize) *maxsize = - g_value_get_int64 (gst_structure_get_value (structure, "maxsize")); + g_value_get_int64 (gst_structure_id_get_value (structure, + GST_QUARK (MAXSIZE))); if (async) - *async = g_value_get_boolean (gst_structure_get_value (structure, "async")); + *async = + g_value_get_boolean (gst_structure_id_get_value (structure, + GST_QUARK (ASYNC))); } /** @@ -770,6 +799,9 @@ GstEvent * gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff, GstClockTime timestamp) { + GstEvent *event; + GstStructure *structure; + /* diff must be positive or timestamp + diff must be positive */ g_return_val_if_fail (diff >= 0 || -diff <= timestamp, NULL); @@ -778,11 +810,14 @@ gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff, ", timestamp %" GST_TIME_FORMAT, proportion, diff, GST_TIME_ARGS (timestamp)); - return gst_event_new_custom (GST_EVENT_QOS, - gst_structure_new ("GstEventQOS", - "proportion", G_TYPE_DOUBLE, proportion, - "diff", G_TYPE_INT64, diff, - "timestamp", G_TYPE_UINT64, timestamp, NULL)); + structure = gst_structure_empty_new ("GstEventQOS"); + gst_structure_id_set (structure, + GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion, + GST_QUARK (DIFF), G_TYPE_INT64, diff, + GST_QUARK (TIMESTAMP), G_TYPE_UINT64, timestamp, NULL); + event = gst_event_new_custom (GST_EVENT_QOS, structure); + + return event; } /** @@ -807,12 +842,16 @@ gst_event_parse_qos (GstEvent * event, gdouble * proportion, structure = gst_event_get_structure (event); if (proportion) *proportion = - g_value_get_double (gst_structure_get_value (structure, "proportion")); + g_value_get_double (gst_structure_id_get_value (structure, + GST_QUARK (PROPORTION))); if (diff) - *diff = g_value_get_int64 (gst_structure_get_value (structure, "diff")); + *diff = + g_value_get_int64 (gst_structure_id_get_value (structure, + GST_QUARK (DIFF))); if (timestamp) *timestamp = - g_value_get_uint64 (gst_structure_get_value (structure, "timestamp")); + g_value_get_uint64 (gst_structure_id_get_value (structure, + GST_QUARK (TIMESTAMP))); } /** @@ -841,9 +880,9 @@ gst_event_parse_qos (GstEvent * event, gdouble * proportion, * configured playback segment can be queried with #GST_QUERY_SEGMENT. * * @start_type and @stop_type specify how to adjust the currently configured - * start and stop fields in @segment. Adjustments can be made relative or - * absolute to the last configured values. A type of #GST_SEEK_TYPE_NONE means - * that the position should not be updated. + * start and stop fields in playback segment. Adjustments can be made relative + * or absolute to the last configured values. A type of #GST_SEEK_TYPE_NONE + * means that the position should not be updated. * * When the rate is positive and @start has been updated, playback will start * from the newly configured start position. @@ -855,7 +894,7 @@ gst_event_parse_qos (GstEvent * event, gdouble * proportion, * It is not possible to seek relative to the current playback position, to do * this, PAUSE the pipeline, query the current playback position with * #GST_QUERY_POSITION and update the playback segment current position with a - * #GST_SEEK_TYPE_SET to the desired position. + * #GST_SEEK_TYPE_SET to the desired position. * * Returns: A new seek event. */ @@ -863,6 +902,9 @@ GstEvent * gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags, GstSeekType start_type, gint64 start, GstSeekType stop_type, gint64 stop) { + GstEvent *event; + GstStructure *structure; + g_return_val_if_fail (rate != 0.0, NULL); if (format == GST_FORMAT_TIME) { @@ -881,14 +923,18 @@ gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags, stop); } - return gst_event_new_custom (GST_EVENT_SEEK, - gst_structure_new ("GstEventSeek", "rate", G_TYPE_DOUBLE, rate, - "format", GST_TYPE_FORMAT, format, - "flags", GST_TYPE_SEEK_FLAGS, flags, - "cur_type", GST_TYPE_SEEK_TYPE, start_type, - "cur", G_TYPE_INT64, start, - "stop_type", GST_TYPE_SEEK_TYPE, stop_type, - "stop", G_TYPE_INT64, stop, NULL)); + structure = gst_structure_empty_new ("GstEventSeek"); + gst_structure_id_set (structure, + GST_QUARK (RATE), G_TYPE_DOUBLE, rate, + GST_QUARK (FORMAT), GST_TYPE_FORMAT, format, + GST_QUARK (FLAGS), GST_TYPE_SEEK_FLAGS, flags, + GST_QUARK (CUR_TYPE), GST_TYPE_SEEK_TYPE, start_type, + GST_QUARK (CUR), G_TYPE_INT64, start, + GST_QUARK (STOP_TYPE), GST_TYPE_SEEK_TYPE, stop_type, + GST_QUARK (STOP), G_TYPE_INT64, stop, NULL); + event = gst_event_new_custom (GST_EVENT_SEEK, structure); + + return event; } /** @@ -916,21 +962,33 @@ gst_event_parse_seek (GstEvent * event, gdouble * rate, structure = gst_event_get_structure (event); if (rate) - *rate = g_value_get_double (gst_structure_get_value (structure, "rate")); + *rate = + g_value_get_double (gst_structure_id_get_value (structure, + GST_QUARK (RATE))); if (format) - *format = g_value_get_enum (gst_structure_get_value (structure, "format")); + *format = + g_value_get_enum (gst_structure_id_get_value (structure, + GST_QUARK (FORMAT))); if (flags) - *flags = g_value_get_flags (gst_structure_get_value (structure, "flags")); + *flags = + g_value_get_flags (gst_structure_id_get_value (structure, + GST_QUARK (FLAGS))); if (start_type) *start_type = - g_value_get_enum (gst_structure_get_value (structure, "cur_type")); + g_value_get_enum (gst_structure_id_get_value (structure, + GST_QUARK (CUR_TYPE))); if (start) - *start = g_value_get_int64 (gst_structure_get_value (structure, "cur")); + *start = + g_value_get_int64 (gst_structure_id_get_value (structure, + GST_QUARK (CUR))); if (stop_type) *stop_type = - g_value_get_enum (gst_structure_get_value (structure, "stop_type")); + g_value_get_enum (gst_structure_id_get_value (structure, + GST_QUARK (STOP_TYPE))); if (stop) - *stop = g_value_get_int64 (gst_structure_get_value (structure, "stop")); + *stop = + g_value_get_int64 (gst_structure_id_get_value (structure, + GST_QUARK (STOP))); } /** @@ -968,12 +1026,18 @@ gst_event_new_navigation (GstStructure * structure) GstEvent * gst_event_new_latency (GstClockTime latency) { + GstEvent *event; + GstStructure *structure; + GST_CAT_INFO (GST_CAT_EVENT, "creating latency event %" GST_TIME_FORMAT, GST_TIME_ARGS (latency)); - return gst_event_new_custom (GST_EVENT_LATENCY, - gst_structure_new ("GstEventLatency", - "latency", G_TYPE_UINT64, latency, NULL)); + structure = gst_structure_empty_new ("GstEventLatency"); + gst_structure_id_set (structure, + GST_QUARK (LATENCY), G_TYPE_UINT64, latency, NULL); + event = gst_event_new_custom (GST_EVENT_LATENCY, structure); + + return event; } /** @@ -996,5 +1060,6 @@ gst_event_parse_latency (GstEvent * event, GstClockTime * latency) structure = gst_event_get_structure (event); if (latency) *latency = - g_value_get_uint64 (gst_structure_get_value (structure, "latency")); + g_value_get_uint64 (gst_structure_id_get_value (structure, + GST_QUARK (LATENCY))); } diff --git a/gst/gstquark.c b/gst/gstquark.c index e6f5b1c8a6..05ee10caa8 100644 --- a/gst/gstquark.c +++ b/gst/gstquark.c @@ -34,7 +34,10 @@ static const gchar *_quark_strings[] = { "avg-in-rate", "avg-out-rate", "buffering-left", "estimated-total", "old-state", "new-state", "pending-state", "clock", "ready", "position", "new-base-time", "live", "min-latency", - "max-latency", "busy", "type", "owner" + "max-latency", "busy", "type", "owner", "update", "applied-rate", + "start", "stop", "minsize", "maxsize", "async", "proportion", + "diff", "timestamp", "flags", "cur-type", "cur", "stop-type", + "latency" }; GQuark _priv_gst_quark_table[GST_QUARK_MAX]; @@ -44,6 +47,10 @@ _priv_gst_quarks_initialize (void) { gint i; + if (G_N_ELEMENTS (_quark_strings) != GST_QUARK_MAX) + g_warning ("the quark table is not consistent! %ld != %d", + G_N_ELEMENTS (_quark_strings), GST_QUARK_MAX); + for (i = 0; i < GST_QUARK_MAX; i++) { _priv_gst_quark_table[i] = g_quark_from_static_string (_quark_strings[i]); } diff --git a/gst/gstquark.h b/gst/gstquark.h index 86b6549f71..10b0a443b4 100644 --- a/gst/gstquark.h +++ b/gst/gstquark.h @@ -62,8 +62,23 @@ typedef enum _GstQuarkId GST_QUARK_BUSY = 33, GST_QUARK_TYPE = 34, GST_QUARK_OWNER = 35, + GST_QUARK_UPDATE = 36, + GST_QUARK_APPLIED_RATE = 37, + GST_QUARK_START = 38, + GST_QUARK_STOP = 39, + GST_QUARK_MINSIZE = 40, + GST_QUARK_MAXSIZE = 41, + GST_QUARK_ASYNC = 42, + GST_QUARK_PROPORTION = 43, + GST_QUARK_DIFF = 44, + GST_QUARK_TIMESTAMP = 45, + GST_QUARK_FLAGS = 46, + GST_QUARK_CUR_TYPE = 47, + GST_QUARK_CUR = 48, + GST_QUARK_STOP_TYPE = 49, + GST_QUARK_LATENCY = 50, - GST_QUARK_MAX = 36 + GST_QUARK_MAX = 51 } GstQuarkId; extern GQuark _priv_gst_quark_table[GST_QUARK_MAX]; diff --git a/tests/check/gst/gstbus.c b/tests/check/gst/gstbus.c index 544479eb3c..169d380496 100644 --- a/tests/check/gst/gstbus.c +++ b/tests/check/gst/gstbus.c @@ -165,6 +165,7 @@ GST_START_TEST (test_watch) main_loop = g_main_loop_new (NULL, FALSE); id = gst_bus_add_watch (test_bus, gst_bus_async_signal_func, NULL); + fail_if (id == 0); g_signal_connect (test_bus, "message::eos", (GCallback) message_func_eos, NULL); g_signal_connect (test_bus, "message::application",