From fc0bf09d96c28d1774086a464e1d4123adae3bc8 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 22 Mar 2005 11:32:59 +0000 Subject: [PATCH] Docs updates Original commit message from CVS: * docs/design/part-TODO.txt: * docs/design/part-events.txt: * docs/design/part-gstbin.txt: * docs/design/part-gstbus.txt: * docs/design/part-gstpipeline.txt: * docs/design/part-messages.txt: * gst/gstbus.c: * gst/gstmessage.c: Docs updates --- ChangeLog | 12 +++ docs/design/part-TODO.txt | 35 +++++++ docs/design/part-events.txt | 175 +++++++++++++++++++++++++++++++ docs/design/part-gstbin.txt | 53 ++++++++++ docs/design/part-gstbus.txt | 28 +++++ docs/design/part-gstpipeline.txt | 88 ++++++++++++++++ docs/design/part-messages.txt | 6 ++ gst/gstbus.c | 7 +- gst/gstmessage.c | 4 +- 9 files changed, 405 insertions(+), 3 deletions(-) create mode 100644 docs/design/part-TODO.txt create mode 100644 docs/design/part-events.txt create mode 100644 docs/design/part-gstbin.txt create mode 100644 docs/design/part-gstbus.txt create mode 100644 docs/design/part-gstpipeline.txt create mode 100644 docs/design/part-messages.txt diff --git a/ChangeLog b/ChangeLog index cfc6d9db19..82ddf758f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2005-03-22 Wim Taymans + + * docs/design/part-TODO.txt: + * docs/design/part-events.txt: + * docs/design/part-gstbin.txt: + * docs/design/part-gstbus.txt: + * docs/design/part-gstpipeline.txt: + * docs/design/part-messages.txt: + * gst/gstbus.c: + * gst/gstmessage.c: + Docs updates + 2005-03-21 Wim Taymans * gst/gstbus.c: (gst_bus_post): diff --git a/docs/design/part-TODO.txt b/docs/design/part-TODO.txt new file mode 100644 index 0000000000..b426e342db --- /dev/null +++ b/docs/design/part-TODO.txt @@ -0,0 +1,35 @@ + +- changing an object's name after construction is not allowed. Checks are performed + when adding objects to parents that no duplicate names are used, changing the name + to a duplicate name after adding it is therefore allowed and voids internal + consistency. + +- check for race in _task_pause()/_stop() since the TASK_LOCK is not held by the + calling thread and the STREAM_LOCK not by the task code. + +- only emit EOS in PLAYING. Make sure elements reemit the EOS message when going to + PLAYING again. + +- implement return values from events in addition to the gboolean. + +- implement query ala events as opposed to the current return value of only a + guint64. I don't have a use case where this a problem yet, though. + +- implement state change order on get<->loop-get<->loop elements. This probably + requires a backtracking algorithm. + +- implement iterators for traversing elements upstream or dowstream. + +- unlinking pads in the PAUSED state needs to make sure the stream thread is not + executing code. Can this be done with a flush to unlock all downstream chain + functions? + +- implement seek in GstPipeline. + +- make events use GstStructure like GstMessage instead of the current union. + +- make the seek event return the time where the seek will happen so that GstPipeline + can update the stream time. + +- implement clock selection as explained in part-gstpipeline.txt + diff --git a/docs/design/part-events.txt b/docs/design/part-events.txt new file mode 100644 index 0000000000..8e3e4ac182 --- /dev/null +++ b/docs/design/part-events.txt @@ -0,0 +1,175 @@ +Events +------ + +Events are objects passed around in parallel to the buffer dataflow to +notify elements of various events. + +Events are received on pads using the event function. Some events should +be interleaved with the data stream so they require taking the STREAM_LOCK, +others don't. + +Different types of events exist to implement various functionalities. + + GST_EVENT_EOS: no more data is to be expected on a pad. + GST_EVENT_FLUSH: data is to be discarded or allowed again + GST_EVENT_DISCONTINUOUS: A new group of buffers with common start time + GST_EVENT_QOS: A notification of the quality of service of the stream + GST_EVENT_SEEK: A seek should be performed to a new position in the stream + GST_EVENT_SIZE: Notification of suggested buffer size. + GST_EVENT_RATE: Notification to change the processing speed of a stream + GST_EVENT_NAVIGATION: A navigation event. + GST_EVENT_TAG: Stream metadata. + + +EOS +--- + +The EOS event can only be sent on a sinkpad. It is typically emited by the +source element when it has finished sending data. This event is mainly sent +in the streaming thread but can also be sent from the application thread. + +The downstream element should forward the EOS event to its downstream peer +elements. This way the event will eventually reach the renderers which should +then post an EOS message on the bus. + +For elements with multiple sink pads it might be possible to wait for EOS on +all the pads before forwarding the event. + +The EOS event should always be interleaved with the data flow, therefore the +STREAM_LOCK should be taken. + +Sometimes the EOS event is generated by another element than the source, for +example a demuxer filter can generate an EOS event before the source element. +This is not a problem, the demuxer does not send an EOS event to the upstream +element but returns GST_FLOW_UNEXPECTED, causing the source element to stop +sending data. + +An element that sends EOS on a pad should stop sending data on that pad. Source +elements typically pause() their task for that purpose. + +By default, the pipeline collects all EOS events from all the sinks before +passing the EOS message to the application. + +The EOS is only posted on the bus by the sink elements in the PLAYING state. If +the EOS event is received in the PAUSED state, it is queued until the element +goes to PLAYING. + + +FLUSH +----- + +A flush event is sent both downstream and upstream to clear any pending data +from the pipeline. This might be needed to make the graph more responsive +when the normal dataflow gets interrupted by for example a seek event. + +Flushing happens in two stages. + + 1) a source filter sends the flush event to the downstream peer element. The + downstream element starts rejecting buffers from the upstream elements. It + sends the flush event further downstream and discards any buffers it is + holding as well as return from the chain function as soon as possible. + This makes sure that all upstream elements get unblocked. + This event is not synchronized with the STREAM_LOCK and can be done in the + application thread. + + 2) a source filter sends the flush event with the done flag set to indicate + that the downstream element can accept buffers again. The downstream + element sends the flush event to its peer elements. After this step dataflow + continues. The endflush call is synchronized with the STREAM_LOCK so any + data used by the chain function can safely freed here if needed. Any + pending EOS events should be discarded too. + +After the flush completes the second stage, data is flowing again in the pipeline +and all buffers are more recent than those before the flush. + +For elements that use the pullregion function, they send both flush events to +the upstream pads in the same way top make sure that the pullregion function +unlocks and any pending buffers are cleared in the upstream elements. + + +DISCONTINUOUS +------------- + +A discont event is sent downstream by an element to indicate that the following +group of buffers start and end at the specified time. + +After a seek event for example, a discont event is sent. + + +SEEK +---- + +A seek event is issued by the application to start playback of a new +position in the stream. It is called form the application thread and +travels upstream. + +The seek event contains the new start end end position of playback +after the seek is performed. Optionally the end position can be left +at -1 to continue playback to the end of the stream. + +A stream usually flushes the graph to minimize latency after the seek. + +The seek event is passed along from element to element until it reaches +an element that can perform the seek. No intermediate element is allowed +to assume that a seek to this location will happen. It is allowed to +modify the start and stop times if it needs to do so. + +The actual seek is performed in the application thread so that success +or failure can be reported as a return value of the seek event. It is +therefore important that before executing the seek, the element acquires +the STREAM_LOCK so that the streaming thread and the seek gets serialized. + +The general flow of executing the seek is as follows: + + 1) unblock the streaming threads, they could be blocked in a chain + function. This is done by sending a flush on all srcpads. + The flush will make sure that all downstream elements unlock and + that control will return to this element chain/loop function. + We cannot lock the STREAM_LOCK before doing this since it might + cause a deadlock. + + 2) lock the STREAM_LOCK. This will work since the chain/loop function + was unlocked in step 1). + + 3) perform the seek. + + 4) send a flush event with the done flag set to allow streaming again. + + 5) start stopped tasks and unlock the STREAM_LOCK, dataflow will continue + now from the new position. + + +SIZE +---- + +Some demuxers know an optimal size for any downstream buffers. They can +use this event to signal this fact. Similary an element can signal an +upstream element of a prefered buffer size. + + +RATE +---- + +When the application wants to change the playback rate of the stream, it +issues a rate event. A rate of 1.0 is the normal playback rate, 2.0 plays +at twice the speed and negative values play backwards. + +Note that the clock speed does not change. + + +NAVIGATION +---------- + +A navigation event is generated by a sink element to signal the elements +of a navigation event such as a mouse movement or button click. +Navigation events travel downstream. + + +TAG +--- + +The tag event is sent downstream when an element has discovered metadata +tags in a media file. Encoders can use this event to adjust their tagging +system. + + diff --git a/docs/design/part-gstbin.txt b/docs/design/part-gstbin.txt new file mode 100644 index 0000000000..c6a0721567 --- /dev/null +++ b/docs/design/part-gstbin.txt @@ -0,0 +1,53 @@ +GstBin +------ + +GstBin is a container element for other GstElements. This makes it possible +to group elements together so that they can be treated as one single +GstElement. + + +Add/removing elements +--------------------- + +The basic functionality of a bin is to add and remove GstElements to/from it. +gst_bin_add() and gst_bin_remove() perform these operations respectively. + +The bin maintains a parent-child relationship with its elements (see part- +relations.txt). + + +Retrieving elements +------------------- + +GstBin provides a number of functions to retrieve one or more children from +itself. A few examples of the provided functions: + +gst_bin_get_by_name() retrieves an element by name. + +gst_bin_iterate_elements() returns an iterator to all the children. + + +element management +------------------ + +The most important function of the GstBin is to distribute all GstElement +operations on itself to all of its children. This includes: + + - state changes + - index get/set + - clock gst/set + - bus set/get + - scheduler set/get + +The state change distribution is the most complex and is explained in +part-states.txt. + + +Subclassing +----------- + +Subclasses of GstBin are free to implement their own add/remove implementations. +It is a good idea to update the GList of children so that the _iterate() functions +can still be used. + + diff --git a/docs/design/part-gstbus.txt b/docs/design/part-gstbus.txt new file mode 100644 index 0000000000..1d7f71886d --- /dev/null +++ b/docs/design/part-gstbus.txt @@ -0,0 +1,28 @@ +GstBus +------ + +The GstBus is an object responsible for delivering GstMessages in +a first-in first-out way from the streaming threads to the application. + +Since the application typically only wants to deal with delivery of these +messages from one thread, the GstBus will marshall the messages between +different threads. + +The GstBus provides support for GSource based notifications. This makes it +possible to handle the delivery in the glib mainloop. + +A message is posted on the bus with the gst_bus_post() method. With the +gst_bus_peek() and _pop() methods one can look at or retrieve a previously +posted message. + +The bus can be polled with the gst_bus_poll() method. This methods blocks +up to the specified timeout value until one of the specified messages types +is posted on the bus. The application can then _pop() the messages from the +bus to handle them. + +It is also possible to get messages from the bus without any thread +marshalling with the gst_bus_set_sync_handler() method. This makes it +possible to react to a message in the same thread that posted the +message on the bus. This should only be used if the application is able +to deal with messages from different threads. + diff --git a/docs/design/part-gstpipeline.txt b/docs/design/part-gstpipeline.txt new file mode 100644 index 0000000000..9d58f57b3f --- /dev/null +++ b/docs/design/part-gstpipeline.txt @@ -0,0 +1,88 @@ +GstPipeline +----------- + +A GstPipeline is usually a toplevel bin an provides all of its +children with a clock and a bus. + +The GstPipeline will also collect EOS messages from its children and +will forward the EOS message to the application when all of the +sinks are in EOS. + +The pipeline also calculates the stream time based on the selected +clock (see part-clocks.txt). + +The pipeline manages the seek operation for the application. + + +GstBus +------ + +The pipeline creates a GstBus and attaches a sync handler to receive +the EOS events. + +Since the pipeline subclasses GstBin, all of its children will receive +the same bus when added to the Gstbin. + +The application can retrieve the GstBus and integrate it in the +mainloop or it can just _pop() messages off in its own thread. + + +Clock selection +--------------- + +Since all of the children of a GstPipeline must use the same clock, the +pipeline must select a clock. + +The default clock selection algorithm works as follows: + + - If the application selected a clock, use that clock. (see below) + - use clock of source elements (*) + - use clock of other element, starting from the sinks going upstream. + (+) + - use GstSystemClock. + +(*) currently not implemented. +(+) traversing the graph upstream to find the best clock is not implemented, + currently the first element found that provides a clock is used. + +The application can influence this clock selection with two methods: +gst_pipeline_use_clock() and gst_pipeline_auto_clock(). + +The _use_clock() method forces the use of a specific clock on the pipeline +regardless of what clock providers are children of the pipeline. Setting +NULL disables the clock completely and makes the pipeline run as fast as +possible. + +The _auto_clock() method removes the fixed clock and reactivates the auto- +matic clock selection algorithm described above. + + +EOS +--- + +The sink elements will post an EOS event on the bus when they reach EOS. The +EOS message is only posted to the bus when the element is in PLAYING. + +The pipeline collects all EOS messages and forwards it to the application as +soon as all the sinks have posted an EOS. + +The list of queued EOS messages is cleared when the pipeline goes to PAUSED +again. This means that all elements should repost the EOS message when going +to PLAYING again. + + +Seeking +------- + +When performing a seek on the pipeline element using gst_element_send_event(), +the pipeline performs the following actions: + + - record the current state of the pipeline. + - set the pipeline to paused + - send the seek event to all sinks + - update the stream time with the time of the seek + - restore old state of the pipeline. + + + + diff --git a/docs/design/part-messages.txt b/docs/design/part-messages.txt new file mode 100644 index 0000000000..ffc53e9ae0 --- /dev/null +++ b/docs/design/part-messages.txt @@ -0,0 +1,6 @@ +Messages +-------- + +Messages are refcounted lightweight objects to signal the application +of pipeline events. + diff --git a/gst/gstbus.c b/gst/gstbus.c index 36392b51f1..600e7d9b64 100644 --- a/gst/gstbus.c +++ b/gst/gstbus.c @@ -482,8 +482,11 @@ bus_watch_destroy (GstBusWatch * watch) /** * gst_bus_add_watch_full: - * @bus: a #GstBus to create the watch for + * @bus: a #GstBus to create the watch for. + * @priority: The priority of the watch. * @handler: A function to call when a message is received. + * @user_data: user data passed to @handler. + * @notify: the function to call when the source is removed. * * Adds the bus to the mainloop with the given priority. If the handler returns * TRUE, the message will then be popped off the queue. When the handler is @@ -528,6 +531,8 @@ gst_bus_add_watch_full (GstBus * bus, gint priority, /** * gst_bus_add_watch: * @bus: a #GstBus to create the watch for + * @handler: A function to call when a message is received. + * @user_data: user data passed to @handler. * * Adds the bus to the mainloop with the default priority. * diff --git a/gst/gstmessage.c b/gst/gstmessage.c index 5aa38f8d74..f48c386b41 100644 --- a/gst/gstmessage.c +++ b/gst/gstmessage.c @@ -356,7 +356,7 @@ gst_message_parse_state_changed (GstMessage * message, GstElementState * old, * gst_message_parse_error: * @message: A valid #GstMessage of type GST_MESSAGE_ERROR. * - * Extracts the GError and debug strung from the GstMessage. The values returned + * Extracts the GError and debug string from the GstMessage. The values returned * in the output arguments are copies; the caller must free them when done. * * MT safe. @@ -381,7 +381,7 @@ gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug) * gst_message_parse_warning: * @message: A valid #GstMessage of type GST_MESSAGE_WARNING. * - * Extracts the GError and debug strung from the GstMessage. The values returned + * Extracts the GError and debug string from the GstMessage. The values returned * in the output arguments are copies; the caller must free them when done. * * MT safe.