diff --git a/ChangeLog b/ChangeLog index 2c03dfe083..842322802d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2005-03-10 Wim Taymans + + * docs/design/part-MT-refcounting.txt: + * docs/design/part-clocks.txt: + * docs/design/part-gstelement.txt: + * docs/design/part-gstobject.txt: + * docs/design/part-standards.txt: + * gst/gstbin.c: (gst_bin_add_func), (gst_bin_add), + (gst_bin_remove_func), (gst_bin_remove): + * gst/gstbin.h: + * gst/gstbuffer.c: + * gst/gstcaps.h: + * testsuite/clock/clock1.c: (main): + * testsuite/clock/clock2.c: (gst_clock_debug), (element_wait), + (main): + * testsuite/dlopen/loadgst.c: (do_test): + * testsuite/refcounting/bin.c: (add_remove_test1), + (add_remove_test2), (main): + * testsuite/refcounting/element.c: (main): + * testsuite/refcounting/element_pad.c: (main): + * testsuite/refcounting/pad.c: (main): + * tools/gst-launch.c: (sigint_handler_sighandler): + * tools/gst-typefind.c: (main): + Doc updates. + Added doc about clock. + removed gst_bin_iterate_recurse_up(), marked methods + for removal. + Fix more testsuites. + 2005-03-09 Wim Taymans * gst/gstpad.c: (gst_pad_get_direction), diff --git a/docs/design/part-MT-refcounting.txt b/docs/design/part-MT-refcounting.txt index 3d45064ec1..27654dc454 100644 --- a/docs/design/part-MT-refcounting.txt +++ b/docs/design/part-MT-refcounting.txt @@ -123,6 +123,15 @@ Atomic operations Atomic operations are generally used for refcounting and for the allocation of small fixed size objects in a memchunk. They can also be used to implement a lockfree list or stack. + +Compare and swap + + As part of the atomic operations, compare-and-swap (CAS) can be used to access + or update a single property or pointer in an object without having to take a + lock. + + This technique is currently not used in GStreamer but might be added in the + future in performance critical places. Objects diff --git a/docs/design/part-clocks.txt b/docs/design/part-clocks.txt new file mode 100644 index 0000000000..feb23f8ea1 --- /dev/null +++ b/docs/design/part-clocks.txt @@ -0,0 +1,106 @@ +Clocks +------ + +To synchronize the different elements, the GstPipeline is responsible for +selecting and distributing a global GstClock for all the elements in it. + +This selection happens whenever an element is added or removed from the +pipeline. Whever the clock changes in a pipeline, a message is posted on +the bus signaling the new clock to the application. + +The GstClock returns a monotonically increasing time with the method +_get_time(). Its accuracy and base time depends on the specific clock +implementation but time is always expessed in nanoseconds. Since the +baseline of the clock is undefined, the clock time returned is not +meaningfull in itself, what matters are the deltas between two clock +times. +The time reported by the clock is called the absolute time. + + +Time in GStreamer +----------------- + +The absolute time is used to calculate the stream time. The stream time +is defined as follows: + + - If the pipeline is NULL/READY, the stream time is undefined. + - In PAUSED, the stream time remains at the time when it was last + PAUSED. When the stream is PAUSED for the first time, the stream time + is 0. + - In PLAYING, the stream time is the delta between the absolute time + and the base time. The base time is defined as the absolute time minus + the stream time at the time when the pipeline is set to PLAYING. + - after a seek, the stream time is set to seek time. + +The stream time is completely managed by the GstPipeline object using the +GstClock absolute time. + + +Timestamps +---------- + +Timestamps on buffers are always expressed in stream time. This means that +all elements that require synchronizing to the clock need to be aware of +the clock base time in order to know the absolute time of the timestamp. +Converting a timestamp (in stream time) to absolute time is performed using +the following formula: + + AT = BT + ST where: AT = absolute time + BT = base time + ST = stream time + +The pipeline base time is propagated to all the element during the PAUSED +to PLAYING state change. All elements are therefore able to convert the +stream time to the absolute time. It is possible to specify an aditional +delay to the base time to compensate for the delay it takes to perform +the state change. + + +Clock features +-------------- + +The clock supports periodic and single shot clock notifications both +synchronous and asynchronous. + +One first needs to create a GstClockID for the periodic or single shot +notification using _clock_new_single_shot_id() or _clock_new_periodic_id(). + +To perform a blocking wait for the specific time of the GstClockID use the +gst_clock_id_wait(). To receive a callback when the specific time is reached +in the clock use gst_clock_id_wait_async(). Both these calls can be interrupted +with the gst_clock_id_unschedule() call. If the blocking wait is unscheduled +a return value of GST_CLOCK_UNSCHEDULED is returned. + +The async callbacks can happen from any thread, either provided by the +core or from a streaming thread. The application should be prepared for this. + +A GstClockID that has been unscheduled cannot be used again for any wait +operation. + +It is possible to perform a blocking wait on the same ID from multiple +threads. However, registering the same ID for multiple async notifications is +not possible, the callback will only be called once. + +None of the wait operations unref the GstClockID, the application is +responsible for unreffing the ids itself. This holds for both periodic and +single shot notifications. + +These clock operations do not operate on the stream time, so the callbacks +will also occur when not in PLAYING state as if the clock just keeps on +running. + + +Clock implementations +--------------------- + +The GStreamer core provides a GstSystemClock based on the system time. +Asynchronous callbacks are scheduled from an internal thread. + +Clock implementors are encouraged to subclass this systemclock as it +implements the async notification. + +Subclasses can however override all of the important methods for sync and +async notifications to implement their own callback methods or blocking +wait operations. + + diff --git a/docs/design/part-gstelement.txt b/docs/design/part-gstelement.txt index 9cb57eceb7..139bf65da4 100644 --- a/docs/design/part-gstelement.txt +++ b/docs/design/part-gstelement.txt @@ -10,15 +10,20 @@ GstElement ========== -The Element is the most important object in the entire GStreamer system, as it defines the structure of the pipeline. -Elements include sources, filters, sinks, and containers (Bins). They may be an intrinsic part of the core GStreamer -library, or may be loaded from a plugin. In some cases they're even fabricated from completely different systems (see -the LADSPA plugin). They are generally created from a GstElementFactory, which will be covered in another chapter, but -for the intrinsic types they can be created with specific functions. +The Element is the most important object in the entire GStreamer system, as it +defines the structure of the pipeline. Elements include sources, filters, +sinks, and containers (Bins). They may be an intrinsic part of the core +GStreamer library, or may be loaded from a plugin. In some cases they're even +fabricated from completely different systems (see the LADSPA plugin). They +are generally created from a GstElementFactory, which will be covered in +another chapter, but for the intrinsic types they can be created with specific +functions. -Elements contains GstPads (also covered in another chapter), which are subsequently used to connect the Elements -together to form a pipeline capable of passing and processing data. They have a parent, which must be another Element. -This allows deeply nested pipelines, and the possibility of "black-box" meta-elements. +Elements contains GstPads (also covered in another chapter), which are +subsequently used to connect the Elements together to form a pipeline capable +of passing and processing data. They have a parent, which must be another +Element. This allows deeply nested pipelines, and the possibility of +"black-box" meta-elements. Name ---- diff --git a/docs/design/part-gstobject.txt b/docs/design/part-gstobject.txt index 9e1d9f8787..093f2f58d3 100644 --- a/docs/design/part-gstobject.txt +++ b/docs/design/part-gstobject.txt @@ -50,6 +50,9 @@ The GstObject contains the necessary primitives to lock the object in a thread-safe manner. This will be used to provide general thread-safety as needed. However, this lock is generic, i.e. it covers the whole object. +The object LOCK is a very lowlevel lock that should only be held to access +the object properties for short periods of code. + All members of the GstObject structure marked as /*< public >*/ /* with LOCK */ are protected by this lock. These members can only be accessed for reading @@ -66,6 +69,20 @@ reasonable, since they are the only possible things to protect in the GstObject. +Locking order +------------- + +In parent-child situations the lock of the parent must always be taken first +before taking the lock of the child. It is NOT allowed to hold the child +lock before taking the parent lock. + +This policy allows for parents to iterate their children and setting properties +on them. + +Whenever a nested lock needs to be taken on objects not involved in a +parent-child relation (eg. pads), an explictic locking order has to be defined. + + Path Generation --------------- diff --git a/docs/design/part-standards.txt b/docs/design/part-standards.txt index 27eac4cd23..37eaf3d666 100644 --- a/docs/design/part-standards.txt +++ b/docs/design/part-standards.txt @@ -1,12 +1,54 @@ Ownership of dynamic objects ---------------------------- -Any object-oriented system or language that doesn't have automatic garbage collection has many potential pitfalls as -far as the pointers go. Therefore, some standards must be adhered to as far as who owns what. +Any object-oriented system or language that doesn't have automatic garbage +collection has many potential pitfalls as far as the pointers go. Therefore, +some standards must be adhered to as far as who owns what. -Strings: -Arguments passed into a function are owned by the caller, and the function will make a copy of the string for its own -internal use. The string should be const gchar *. Strings returned from a function are always a copy of the +Strings +------- + +Arguments passed into a function are owned by the caller, and the function +will make a copy of the string for its own internal use. The string should +be const gchar *. Strings returned from a function are always a copy of the original and should be freed after usage by the caller. -Objects: + ex: + + name = gst_element_get_name (element); /* copy of name is made */ + .. use name .. + g_free (name); /* free after usage */ + + +Objects +------- + +Objects passed into a function are owned by the caller, any additional +reference held to the object after leaving the function should increase the +refcount of that object. + +Objects returned from a function are owned by the caller. This means that the +called should _free() or _unref() the object after usage. + + ex: + + peer = gst_pad_get_peer (pad); /* peer with increased refcount */ + if (peer) { + .. use peer .. + gst_object_unref (GST_OBJECT (peer)); /* unref peer after usage */ + } + + +Iterators +--------- + +When retrieving multiple objects from an object an iterator should be used. +The iterator allows you to access the objects one after another while making +sure that the set of objects retrieved remains consistent. + +Each object retrieved from an iterator has its refcount increased or is a +copy of the original. In any case the object should be unreffed or freed +after usage. + + + diff --git a/gst/gstbin.c b/gst/gstbin.c index 70d15b1ed5..c433befb7d 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -300,6 +300,7 @@ gst_bin_get_clock_func (GstElement * element) return result; } +/* will be removed */ static void gst_bin_set_element_sched (GstElement * element, GstScheduler * sched) { @@ -359,6 +360,7 @@ gst_bin_set_element_sched (GstElement * element, GstScheduler * sched) } } +/* will be removed */ static void gst_bin_unset_element_sched (GstElement * element, GstScheduler * sched) { @@ -452,8 +454,8 @@ gst_bin_add_func (GstBin * bin, GstElement * element) goto duplicate_name; /* set the element's parent and add the element to the bin's list of children */ - if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT (element), - GST_OBJECT (bin)))) + if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (element), + GST_OBJECT_CAST (bin)))) goto had_parent; bin->children = g_list_prepend (bin->children, element); @@ -573,12 +575,12 @@ gst_bin_remove_func (GstBin * bin, GstElement * element) /* we ref here because after the _unparent() the element can be disposed * and we still need it to fire a signal. */ - gst_object_ref (GST_OBJECT (element)); - gst_object_unparent (GST_OBJECT (element)); + gst_object_ref (GST_OBJECT_CAST (element)); + gst_object_unparent (GST_OBJECT_CAST (element)); g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_REMOVED], 0, element); /* element is really out of our control now */ - gst_object_unref (GST_OBJECT (element)); + gst_object_unref (GST_OBJECT_CAST (element)); return TRUE; @@ -731,12 +733,6 @@ gst_bin_iterate_recurse (GstBin * bin) return result; } -GstIterator * -gst_bin_iterate_recurse_up (GstBin * bin) -{ - return NULL; -} - /* returns 0 if the element is a sink, this is made so that * we can use this function as a filter * @@ -820,6 +816,8 @@ bin_element_is_sink (GstElement * child, GstBin * bin) * Each element will have its refcount increased, so unref * after usage. * + * The sink elements are those without any linked srcpads. + * * Returns: a #GstIterator of #GstElements. gst_iterator_free after use. * * MT safe. @@ -848,6 +846,8 @@ gst_bin_iterate_sinks (GstBin * bin) * * An internal function to inform the parent bin about a state change * of a child. + * + * Marked for removal. */ void gst_bin_child_state_change (GstBin * bin, GstElementState oldstate, @@ -873,6 +873,7 @@ gst_bin_child_state_change (GstBin * bin, GstElementState oldstate, } } +/* will be removed */ static void gst_bin_child_state_change_func (GstBin * bin, GstElementState oldstate, GstElementState newstate, GstElement * child) @@ -937,6 +938,8 @@ typedef gboolean (*GstBinForeachFunc) (GstBin * bin, GstElement * element, * called, and that are still in @bin when the child is reached. * * Returns: TRUE if @func always returned TRUE, FALSE otherwise + * + * Marked for removal. **/ static gboolean gst_bin_foreach (GstBin * bin, GstBinForeachFunc func, gpointer data) @@ -1283,6 +1286,7 @@ gst_bin_get_by_interface (GstBin * bin, GType interface) * * Returns: An iterator for the elements inside the bin implementing the interface. * + * MT safe. */ GstIterator * gst_bin_iterate_all_by_interface (GstBin * bin, GType interface) diff --git a/gst/gstbin.h b/gst/gstbin.h index 7dfbe18e10..c6ab722ee7 100644 --- a/gst/gstbin.h +++ b/gst/gstbin.h @@ -129,7 +129,6 @@ GstElement* gst_bin_get_by_interface (GstBin *bin, GType interface); /* retrieve multiple children */ GstIterator* gst_bin_iterate_elements (GstBin *bin); GstIterator* gst_bin_iterate_recurse (GstBin *bin); -GstIterator* gst_bin_iterate_recurse_up (GstBin *bin); GstIterator* gst_bin_iterate_sinks (GstBin *bin); GstIterator* gst_bin_iterate_all_by_interface (GstBin *bin, GType interface); diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index af4c87ed1f..fd3feadd26 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -271,7 +271,8 @@ gst_buffer_new_and_alloc (guint size) * Returns: the #GstCaps, or NULL if there was an error or there * were no caps on this buffer. */ -/* FIXME can we make this threadsafe without a lock on the buffer? */ +/* FIXME can we make this threadsafe without a lock on the buffer? + * We can use compare and swap and atomic reads. */ GstCaps * gst_buffer_get_caps (GstBuffer * buffer) { @@ -289,7 +290,10 @@ gst_buffer_get_caps (GstBuffer * buffer) * be increased and any previous caps on the buffer will be * unreffed. */ -/* FIXME can we make this threadsafe without a lock on the buffer? */ +/* FIXME can we make this threadsafe without a lock on the buffer? + * We can use compare and swap and atomic reads. Another idea is to + * not attach the caps to the buffer but use an event to signal a caps + * change. */ void gst_buffer_set_caps (GstBuffer * buffer, GstCaps * caps) { diff --git a/gst/gstcaps.h b/gst/gstcaps.h index 84eb9204d8..e0c21f7e5d 100644 --- a/gst/gstcaps.h +++ b/gst/gstcaps.h @@ -148,13 +148,6 @@ void gst_caps_replace (GstCaps gchar * gst_caps_to_string (const GstCaps *caps); GstCaps * gst_caps_from_string (const gchar *string); -gboolean gst_caps_structure_fixate_field_nearest_int (GstStructure *structure, - const char *field_name, - int target); -gboolean gst_caps_structure_fixate_field_nearest_double (GstStructure *structure, - const char *field_name, - double target); - G_END_DECLS #endif /* __GST_CAPS_H__ */ diff --git a/tests/old/testsuite/clock/clock1.c b/tests/old/testsuite/clock/clock1.c index 7aa9856457..2e260858e1 100644 --- a/tests/old/testsuite/clock/clock1.c +++ b/tests/old/testsuite/clock/clock1.c @@ -43,13 +43,12 @@ main (int argc, char *argv[]) gst_bin_add_many (GST_BIN (pipeline), src, id, sink, NULL); gst_element_link_many (src, id, sink, NULL); - clock = gst_bin_get_clock (GST_BIN (pipeline)); + clock = gst_pipeline_get_clock (GST_PIPELINE (pipeline)); g_assert (clock != NULL); gst_clock_debug (clock); gst_clock_debug (clock); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); - gst_bin_iterate (GST_BIN (pipeline)); gst_clock_debug (clock); gst_clock_debug (clock); gst_clock_debug (clock); diff --git a/tests/old/testsuite/clock/clock2.c b/tests/old/testsuite/clock/clock2.c index 303b9c20f4..8271291962 100644 --- a/tests/old/testsuite/clock/clock2.c +++ b/tests/old/testsuite/clock/clock2.c @@ -7,12 +7,26 @@ */ #include + void gst_clock_debug (GstClock * clock, GstElement * fakesink) { - g_print ("Clock info: time %" G_GUINT64_FORMAT " - Element info: time %" - G_GUINT64_FORMAT "\n", gst_clock_get_time (clock), - gst_element_get_time (fakesink)); + GstClockTime time; + + time = gst_clock_get_time (clock); + + g_print ("Clock info: time %" G_GUINT64_FORMAT " Element %" GST_TIME_FORMAT + "\n", time, GST_TIME_ARGS (time - fakesink->base_time)); +} + +static void +element_wait (GstElement * element, GstClockTime time) +{ + GstClockID id; + + id = gst_clock_new_single_shot_id (clock, time + element->base_time); + gst_clock_id_wait (id, NULL); + gst_clock_id_unref (id); } int @@ -41,10 +55,10 @@ main (int argc, char *argv[]) g_usleep (G_USEC_PER_SEC); gst_clock_debug (clock, fakesink); - gst_element_wait (fakesink, 2 * GST_SECOND); + element_wait (fakesink, 2 * GST_SECOND); gst_clock_debug (clock, fakesink); - gst_element_wait (fakesink, 5 * GST_SECOND); + element_wait (fakesink, 5 * GST_SECOND); gst_clock_debug (clock, fakesink); g_usleep (G_USEC_PER_SEC); diff --git a/tests/old/testsuite/dlopen/loadgst.c b/tests/old/testsuite/dlopen/loadgst.c index 9bfbd0a12c..59d6e72c61 100644 --- a/tests/old/testsuite/dlopen/loadgst.c +++ b/tests/old/testsuite/dlopen/loadgst.c @@ -7,22 +7,20 @@ do_test (void) { GstElement *pipeline; int i; - gboolean ret; gst_init (NULL, NULL); pipeline = gst_parse_launch ("fakesrc ! fakesink", NULL); g_assert (pipeline != NULL); - gst_element_set_state (pipeline, GST_STATE_PLAYING); for (i = 0; i < 100; i++) { - ret = gst_bin_iterate (GST_BIN (pipeline)); - g_assert (ret); + g_usleep (1000); g_print ("%s", (i & 1) ? "+" : "-"); } g_print ("\n"); + gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (GST_OBJECT (pipeline)); } diff --git a/tests/old/testsuite/refcounting/bin.c b/tests/old/testsuite/refcounting/bin.c index 4d437b2efe..5d502689d0 100644 --- a/tests/old/testsuite/refcounting/bin.c +++ b/tests/old/testsuite/refcounting/bin.c @@ -50,9 +50,9 @@ add_remove_test1 (void) bin = gst_bin_new ("testbin"); element = gst_element_factory_make ("fakesrc", NULL); gst_element_set_name (element, "test1"); - g_assert (GST_OBJECT_FLOATING (element)); + g_assert (GST_OBJECT_IS_FLOATING (element)); gst_bin_add (GST_BIN (bin), element); - g_assert (!GST_OBJECT_FLOATING (element)); + g_assert (!GST_OBJECT_IS_FLOATING (element)); gst_bin_remove (GST_BIN (bin), element); gst_object_unref (GST_OBJECT (bin)); @@ -68,16 +68,16 @@ add_remove_test2 (void) element = gst_element_factory_make ("fakesrc", NULL); gst_element_set_name (element, "test1"); gst_object_ref (GST_OBJECT (element)); - g_assert (GST_OBJECT_FLOATING (element)); + g_assert (GST_OBJECT_IS_FLOATING (element)); gst_bin_add (GST_BIN (bin), element); - g_assert (!GST_OBJECT_FLOATING (element)); + g_assert (!GST_OBJECT_IS_FLOATING (element)); gst_bin_remove (GST_BIN (bin), element); - g_assert (!GST_OBJECT_FLOATING (element)); - g_assert (!GST_OBJECT_DESTROYED (element)); + g_assert (!GST_OBJECT_IS_FLOATING (element)); + g_assert (!GST_OBJECT_IS_DESTROYED (element)); gst_object_unref (GST_OBJECT (element)); #if 0 - g_assert (GST_OBJECT_DESTROYED (element)); + g_assert (GST_OBJECT_IS_DESTROYED (element)); gst_object_unref (GST_OBJECT (element)); #endif @@ -169,10 +169,10 @@ main (int argc, gchar * argv[]) gst_alloc_trace_live_all () - usage1); bin = gst_bin_new ("somebin"); - g_assert (GST_OBJECT_FLOATING (bin)); + g_assert (GST_OBJECT_IS_FLOATING (bin)); gst_object_ref (GST_OBJECT (bin)); gst_object_sink (GST_OBJECT (bin)); - g_assert (!GST_OBJECT_FLOATING (bin)); + g_assert (!GST_OBJECT_IS_FLOATING (bin)); gst_object_unref (GST_OBJECT (bin)); g_print ("create/ref/sink/unref new bin %d\n", gst_alloc_trace_live_all () - usage1); @@ -188,10 +188,10 @@ main (int argc, gchar * argv[]) gst_alloc_trace_live_all () - usage1); bin = gst_bin_new ("somebin"); - g_assert (!GST_OBJECT_DESTROYED (bin)); + g_assert (!GST_OBJECT_IS_DESTROYED (bin)); gst_object_unref (GST_OBJECT (bin)); #if 0 - g_assert (GST_OBJECT_DESTROYED (bin)); + g_assert (GST_OBJECT_IS_DESTROYED (bin)); gst_object_unref (GST_OBJECT (bin)); #endif g_print ("create/destroy/unref new bin %d\n", diff --git a/tests/old/testsuite/refcounting/element.c b/tests/old/testsuite/refcounting/element.c index ed0258c32d..e4673bf03d 100644 --- a/tests/old/testsuite/refcounting/element.c +++ b/tests/old/testsuite/refcounting/element.c @@ -35,10 +35,10 @@ main (int argc, gchar * argv[]) gst_alloc_trace_live_all () - usage1); element = gst_element_factory_make ("fakesrc", NULL); - g_assert (GST_OBJECT_FLOATING (element)); + g_assert (GST_OBJECT_IS_FLOATING (element)); gst_object_ref (GST_OBJECT (element)); gst_object_sink (GST_OBJECT (element)); - g_assert (!GST_OBJECT_FLOATING (element)); + g_assert (!GST_OBJECT_IS_FLOATING (element)); gst_object_unref (GST_OBJECT (element)); g_print ("create/ref/sink/unref new element %d\n", gst_alloc_trace_live_all () - usage1); @@ -55,9 +55,9 @@ main (int argc, gchar * argv[]) #if 0 element = gst_element_factory_make ("fakesrc", NULL); - g_assert (!GST_OBJECT_DESTROYED (element)); + g_assert (!GST_OBJECT_IS_DESTROYED (element)); gst_object_unref (GST_OBJECT (element)); - g_assert (GST_OBJECT_DESTROYED (element)); + g_assert (GST_OBJECT_IS_DESTROYED (element)); gst_object_unref (GST_OBJECT (element)); g_print ("create/destroy/unref new element %d\n", gst_alloc_trace_live_all () - usage1); diff --git a/tests/old/testsuite/refcounting/element_pad.c b/tests/old/testsuite/refcounting/element_pad.c index 24b4e82f33..2f3ad1d8f5 100644 --- a/tests/old/testsuite/refcounting/element_pad.c +++ b/tests/old/testsuite/refcounting/element_pad.c @@ -27,8 +27,8 @@ main (int argc, gchar * argv[]) g_assert (GST_IS_ELEMENT (element)); pad = gst_element_get_pad (element, "sink"); g_assert (GST_IS_PAD (pad)); - g_assert (GST_OBJECT_FLOATING (element)); - g_assert (!GST_OBJECT_FLOATING (pad)); + g_assert (GST_OBJECT_IS_FLOATING (element)); + g_assert (!GST_OBJECT_IS_FLOATING (pad)); g_assert (gst_pad_get_parent (pad) == element); gst_object_unref (GST_OBJECT (element)); g_print ("create/addpad/unref 1 new element: %ld\n", vmsize () - usage1); diff --git a/tests/old/testsuite/refcounting/pad.c b/tests/old/testsuite/refcounting/pad.c index 1b8d53ed00..fe9b001b37 100644 --- a/tests/old/testsuite/refcounting/pad.c +++ b/tests/old/testsuite/refcounting/pad.c @@ -52,10 +52,10 @@ main (int argc, gchar * argv[]) pad = gst_pad_new_from_template (gst_static_pad_template_get (&templ), "padname"); - g_assert (GST_OBJECT_FLOATING (pad)); + g_assert (GST_OBJECT_IS_FLOATING (pad)); gst_object_ref (GST_OBJECT (pad)); gst_object_sink (GST_OBJECT (pad)); - g_assert (!GST_OBJECT_FLOATING (pad)); + g_assert (!GST_OBJECT_IS_FLOATING (pad)); gst_object_unref (GST_OBJECT (pad)); g_print ("create/ref/sink/unref new pad %ld\n", vmsize () - usage1); diff --git a/testsuite/clock/clock1.c b/testsuite/clock/clock1.c index 7aa9856457..2e260858e1 100644 --- a/testsuite/clock/clock1.c +++ b/testsuite/clock/clock1.c @@ -43,13 +43,12 @@ main (int argc, char *argv[]) gst_bin_add_many (GST_BIN (pipeline), src, id, sink, NULL); gst_element_link_many (src, id, sink, NULL); - clock = gst_bin_get_clock (GST_BIN (pipeline)); + clock = gst_pipeline_get_clock (GST_PIPELINE (pipeline)); g_assert (clock != NULL); gst_clock_debug (clock); gst_clock_debug (clock); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); - gst_bin_iterate (GST_BIN (pipeline)); gst_clock_debug (clock); gst_clock_debug (clock); gst_clock_debug (clock); diff --git a/testsuite/clock/clock2.c b/testsuite/clock/clock2.c index 303b9c20f4..8271291962 100644 --- a/testsuite/clock/clock2.c +++ b/testsuite/clock/clock2.c @@ -7,12 +7,26 @@ */ #include + void gst_clock_debug (GstClock * clock, GstElement * fakesink) { - g_print ("Clock info: time %" G_GUINT64_FORMAT " - Element info: time %" - G_GUINT64_FORMAT "\n", gst_clock_get_time (clock), - gst_element_get_time (fakesink)); + GstClockTime time; + + time = gst_clock_get_time (clock); + + g_print ("Clock info: time %" G_GUINT64_FORMAT " Element %" GST_TIME_FORMAT + "\n", time, GST_TIME_ARGS (time - fakesink->base_time)); +} + +static void +element_wait (GstElement * element, GstClockTime time) +{ + GstClockID id; + + id = gst_clock_new_single_shot_id (clock, time + element->base_time); + gst_clock_id_wait (id, NULL); + gst_clock_id_unref (id); } int @@ -41,10 +55,10 @@ main (int argc, char *argv[]) g_usleep (G_USEC_PER_SEC); gst_clock_debug (clock, fakesink); - gst_element_wait (fakesink, 2 * GST_SECOND); + element_wait (fakesink, 2 * GST_SECOND); gst_clock_debug (clock, fakesink); - gst_element_wait (fakesink, 5 * GST_SECOND); + element_wait (fakesink, 5 * GST_SECOND); gst_clock_debug (clock, fakesink); g_usleep (G_USEC_PER_SEC); diff --git a/testsuite/dlopen/loadgst.c b/testsuite/dlopen/loadgst.c index 9bfbd0a12c..59d6e72c61 100644 --- a/testsuite/dlopen/loadgst.c +++ b/testsuite/dlopen/loadgst.c @@ -7,22 +7,20 @@ do_test (void) { GstElement *pipeline; int i; - gboolean ret; gst_init (NULL, NULL); pipeline = gst_parse_launch ("fakesrc ! fakesink", NULL); g_assert (pipeline != NULL); - gst_element_set_state (pipeline, GST_STATE_PLAYING); for (i = 0; i < 100; i++) { - ret = gst_bin_iterate (GST_BIN (pipeline)); - g_assert (ret); + g_usleep (1000); g_print ("%s", (i & 1) ? "+" : "-"); } g_print ("\n"); + gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (GST_OBJECT (pipeline)); } diff --git a/testsuite/refcounting/bin.c b/testsuite/refcounting/bin.c index 4d437b2efe..5d502689d0 100644 --- a/testsuite/refcounting/bin.c +++ b/testsuite/refcounting/bin.c @@ -50,9 +50,9 @@ add_remove_test1 (void) bin = gst_bin_new ("testbin"); element = gst_element_factory_make ("fakesrc", NULL); gst_element_set_name (element, "test1"); - g_assert (GST_OBJECT_FLOATING (element)); + g_assert (GST_OBJECT_IS_FLOATING (element)); gst_bin_add (GST_BIN (bin), element); - g_assert (!GST_OBJECT_FLOATING (element)); + g_assert (!GST_OBJECT_IS_FLOATING (element)); gst_bin_remove (GST_BIN (bin), element); gst_object_unref (GST_OBJECT (bin)); @@ -68,16 +68,16 @@ add_remove_test2 (void) element = gst_element_factory_make ("fakesrc", NULL); gst_element_set_name (element, "test1"); gst_object_ref (GST_OBJECT (element)); - g_assert (GST_OBJECT_FLOATING (element)); + g_assert (GST_OBJECT_IS_FLOATING (element)); gst_bin_add (GST_BIN (bin), element); - g_assert (!GST_OBJECT_FLOATING (element)); + g_assert (!GST_OBJECT_IS_FLOATING (element)); gst_bin_remove (GST_BIN (bin), element); - g_assert (!GST_OBJECT_FLOATING (element)); - g_assert (!GST_OBJECT_DESTROYED (element)); + g_assert (!GST_OBJECT_IS_FLOATING (element)); + g_assert (!GST_OBJECT_IS_DESTROYED (element)); gst_object_unref (GST_OBJECT (element)); #if 0 - g_assert (GST_OBJECT_DESTROYED (element)); + g_assert (GST_OBJECT_IS_DESTROYED (element)); gst_object_unref (GST_OBJECT (element)); #endif @@ -169,10 +169,10 @@ main (int argc, gchar * argv[]) gst_alloc_trace_live_all () - usage1); bin = gst_bin_new ("somebin"); - g_assert (GST_OBJECT_FLOATING (bin)); + g_assert (GST_OBJECT_IS_FLOATING (bin)); gst_object_ref (GST_OBJECT (bin)); gst_object_sink (GST_OBJECT (bin)); - g_assert (!GST_OBJECT_FLOATING (bin)); + g_assert (!GST_OBJECT_IS_FLOATING (bin)); gst_object_unref (GST_OBJECT (bin)); g_print ("create/ref/sink/unref new bin %d\n", gst_alloc_trace_live_all () - usage1); @@ -188,10 +188,10 @@ main (int argc, gchar * argv[]) gst_alloc_trace_live_all () - usage1); bin = gst_bin_new ("somebin"); - g_assert (!GST_OBJECT_DESTROYED (bin)); + g_assert (!GST_OBJECT_IS_DESTROYED (bin)); gst_object_unref (GST_OBJECT (bin)); #if 0 - g_assert (GST_OBJECT_DESTROYED (bin)); + g_assert (GST_OBJECT_IS_DESTROYED (bin)); gst_object_unref (GST_OBJECT (bin)); #endif g_print ("create/destroy/unref new bin %d\n", diff --git a/testsuite/refcounting/element.c b/testsuite/refcounting/element.c index ed0258c32d..e4673bf03d 100644 --- a/testsuite/refcounting/element.c +++ b/testsuite/refcounting/element.c @@ -35,10 +35,10 @@ main (int argc, gchar * argv[]) gst_alloc_trace_live_all () - usage1); element = gst_element_factory_make ("fakesrc", NULL); - g_assert (GST_OBJECT_FLOATING (element)); + g_assert (GST_OBJECT_IS_FLOATING (element)); gst_object_ref (GST_OBJECT (element)); gst_object_sink (GST_OBJECT (element)); - g_assert (!GST_OBJECT_FLOATING (element)); + g_assert (!GST_OBJECT_IS_FLOATING (element)); gst_object_unref (GST_OBJECT (element)); g_print ("create/ref/sink/unref new element %d\n", gst_alloc_trace_live_all () - usage1); @@ -55,9 +55,9 @@ main (int argc, gchar * argv[]) #if 0 element = gst_element_factory_make ("fakesrc", NULL); - g_assert (!GST_OBJECT_DESTROYED (element)); + g_assert (!GST_OBJECT_IS_DESTROYED (element)); gst_object_unref (GST_OBJECT (element)); - g_assert (GST_OBJECT_DESTROYED (element)); + g_assert (GST_OBJECT_IS_DESTROYED (element)); gst_object_unref (GST_OBJECT (element)); g_print ("create/destroy/unref new element %d\n", gst_alloc_trace_live_all () - usage1); diff --git a/testsuite/refcounting/element_pad.c b/testsuite/refcounting/element_pad.c index 24b4e82f33..2f3ad1d8f5 100644 --- a/testsuite/refcounting/element_pad.c +++ b/testsuite/refcounting/element_pad.c @@ -27,8 +27,8 @@ main (int argc, gchar * argv[]) g_assert (GST_IS_ELEMENT (element)); pad = gst_element_get_pad (element, "sink"); g_assert (GST_IS_PAD (pad)); - g_assert (GST_OBJECT_FLOATING (element)); - g_assert (!GST_OBJECT_FLOATING (pad)); + g_assert (GST_OBJECT_IS_FLOATING (element)); + g_assert (!GST_OBJECT_IS_FLOATING (pad)); g_assert (gst_pad_get_parent (pad) == element); gst_object_unref (GST_OBJECT (element)); g_print ("create/addpad/unref 1 new element: %ld\n", vmsize () - usage1); diff --git a/testsuite/refcounting/pad.c b/testsuite/refcounting/pad.c index 1b8d53ed00..fe9b001b37 100644 --- a/testsuite/refcounting/pad.c +++ b/testsuite/refcounting/pad.c @@ -52,10 +52,10 @@ main (int argc, gchar * argv[]) pad = gst_pad_new_from_template (gst_static_pad_template_get (&templ), "padname"); - g_assert (GST_OBJECT_FLOATING (pad)); + g_assert (GST_OBJECT_IS_FLOATING (pad)); gst_object_ref (GST_OBJECT (pad)); gst_object_sink (GST_OBJECT (pad)); - g_assert (!GST_OBJECT_FLOATING (pad)); + g_assert (!GST_OBJECT_IS_FLOATING (pad)); gst_object_unref (GST_OBJECT (pad)); g_print ("create/ref/sink/unref new pad %ld\n", vmsize () - usage1); diff --git a/tools/gst-launch.c b/tools/gst-launch.c index af0cb9b2f4..bcda0bfb61 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -221,7 +221,7 @@ fault_handler_sighandler (int signum) fault_spin (); } -#else +#else /* USE_SIGINFO */ static void fault_handler_sigaction (int signum, siginfo_t * si, void *misc) @@ -246,7 +246,7 @@ fault_handler_sigaction (int signum, siginfo_t * si, void *misc) fault_spin (); } -#endif +#endif /* USE_SIGINFO */ static void fault_spin (void) @@ -293,7 +293,7 @@ fault_setup (void) sigaction (SIGSEGV, &action, NULL); sigaction (SIGQUIT, &action, NULL); } -#endif +#endif /* DISABLE_FAULT_HANDLER */ static void print_tag (const GstTagList * list, const gchar * tag, gpointer unused) @@ -343,6 +343,8 @@ error_cb (GObject * object, GstObject * source, GError * error, gchar * debug) static void sigint_handler_sighandler (int signum) { + g_print ("Caught interrupt -- "); + sigint_restore (); caught_intr = TRUE; diff --git a/tools/gst-typefind.c b/tools/gst-typefind.c index 7ea6034e93..bf463431b0 100644 --- a/tools/gst-typefind.c +++ b/tools/gst-typefind.c @@ -52,8 +52,10 @@ main (int argc, char *argv[]) g_assert (GST_IS_ELEMENT (source)); typefind = gst_element_factory_make ("typefind", "typefind"); g_assert (GST_IS_ELEMENT (typefind)); - gst_bin_add_many (GST_BIN (pipeline), source, typefind, NULL); - gst_element_link (source, typefind); + gst_bin_add (GST_BIN (pipeline), source); + gst_bin_add (GST_BIN (pipeline), typefind); + gst_pad_link (gst_element_get_pad (source, "src"), + gst_element_get_pad (typefind, "sink")); g_signal_connect (G_OBJECT (typefind), "have-type", G_CALLBACK (have_type_handler), NULL);