docs/design/: Some more tweeks and additions to the docs.

Original commit message from CVS:
* docs/design/part-clocks.txt:
* docs/design/part-element-sink.txt:
* docs/design/part-events.txt:
* docs/design/part-preroll.txt:
* docs/design/part-states.txt:
Some more tweeks and additions to the docs.
This commit is contained in:
Wim Taymans 2005-06-30 09:33:45 +00:00
parent 092745b46d
commit 41b9a5264d
6 changed files with 91 additions and 25 deletions

View file

@ -1,3 +1,12 @@
2005-06-30 Wim Taymans <wim@fluendo.com>
* docs/design/part-clocks.txt:
* docs/design/part-element-sink.txt:
* docs/design/part-events.txt:
* docs/design/part-preroll.txt:
* docs/design/part-states.txt:
Some more tweeks and additions to the docs.
2005-06-30 Wim Taymans <wim@fluendo.com>
* gst/gstpad.c: (_gst_do_pass_data_accumulator),

View file

@ -30,7 +30,7 @@ is defined as follows:
- 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.
- after a seek, the stream time is set to 0 (see part-seeking.txt)
The stream time is completely managed by the GstPipeline object using the
GstClock absolute time.
@ -83,7 +83,10 @@ not possible, the callback will only be called once.
None of the wait operations unref the GstClockID, the owner is
responsible for unreffing the ids itself. This holds for both periodic and
single shot notifications.
single shot notifications. The reason being that the owner of the ClockID
has to keep a handle to the ID to unblock the wait on FLUSHING events
or state changes and if we unref it automatically, the handle might be
invalid.
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

View file

@ -12,4 +12,20 @@ typical sink elements include:
Sinks are harder to construct than other element types as they are
treated specially by the GStreamer core.
state changes
-------------
A sink always returns ASYNC from the state change to PAUSED, this
includes a state change from READY->PAUSED and PLAYING->PAUSED. The
reason for this is that this way we can detect when the first buffer
or event arrives in the sink when the state change completes.
A sink should block on the first event or buffer received in the
PAUSED state before commiting the state to PAUSED.
FLUSHING events have to be handled out of sync with the buffer flow
and take no part in the preroll procedure.

View file

@ -39,7 +39,7 @@ 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.
example a demuxer element 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.
@ -91,9 +91,28 @@ 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.
group of buffers start and end at the specified time. The discont event
also contains the playback speed of the stream.
Since the stream time is always set to 0 at start and after a seek, a 0
point for all next buffer's timestamps has to be propagated through the
pipeline using the DISCONT event.
Elements that sync to the clock should store the DISCONT start and end values
and substract the start value from the buffer timestamp before comparing
it against the stream time.
An element is allowed to send out buffers with the DISCONT start time already
substracted from the timestamp. If it does so, it needs to send a corrected
DISCONT downstream, ie, one with start time 0.
A DISCONT event should be generated as soon as possible in the pipeline and
is usually generated by a demuxer. The event is generated before pushing the
first buffer and after a seek, right before pushing the new buffer.
The DISCONT event can be send from both the application and the streaming
thread.
After a seek event for example, a discont event is sent.
SEEK
@ -107,12 +126,13 @@ The seek event contains the new start and 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.
A seek 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.
modify the start and stop times if it needs to do so. this is typically
the case if a seek is requested for a non-time position.
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
@ -132,11 +152,14 @@ The general flow of executing the seek is as follows:
was unlocked in step 1).
3) perform the seek. since the STREAM_LOCK is held, the streaming thread
will wait for the seek to complete.
will wait for the seek to complete. Most likely, the stream thread
will pause because the peer elements are flushing.
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
5) send a DISCONT event to signal the new buffer timestamp base time.
6) start stopped tasks and unlock the STREAM_LOCK, dataflow will continue
now from the new position.
@ -145,17 +168,22 @@ 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.
upstream element for 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.
issues a rate event on the sinks. 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.
The rate event travels upstream. After the rate event reaches an element
that can handle the rate event, it issues a flush and generates a new
DISCONT event with the updated rate.
Note that the clock speed does not change. More specific information about
changing the playback rate are to be thought out and written down.
NAVIGATION
@ -163,7 +191,7 @@ 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.
Navigation events travel upstream.
TAG
@ -171,6 +199,6 @@ 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.
system. A tag is serialized with buffers.

View file

@ -32,6 +32,10 @@ The state is commited in the following conditions:
We require the state change to be commited in EOS as well since an EOS means
by definition that no buffer is going to arrive anymore.
After the state is commited, a blocking wait should be performed for the
next event. Some sinks might render the preroll buffer before starting this
blocking wait.
Unlocking the preroll
---------------------
@ -41,15 +45,13 @@ The following conditions unlock the preroll:
- a state change
- a flush event
When the preroll is unlocked by one of these events, a return value of
When the preroll is unlocked by a flush event, a return value of
GST_FLOW_WRONG_STATE is to be returned to the peer pad.
Result of the preroll
---------------------
When preroll is unlocked by a state change to PLAYING, playback and
rendering of the buffers shall start.
After the preroll is unlocked, the element can be in the following states:
- in a state that disallows it to process the data (flushing, pad inactive)
- in a state that allows it to process the data.
When preroll is unlocked by a state change to READY, the buffer is
to be discarded and a GST_FLOW_WRONG_STATE shall be returned to the
peer element.

View file

@ -34,12 +34,16 @@ The STATE_LOCK protects 3 element variables:
- STATE
- PENDING_STATE
- STATE_ERROR flag
- NO_PREROLL flag
The STATE always reflects the current state of the element. The PENDING_STATE
always reflects the required state of the element. The PENDING_STATE can be
VOID_PENDING if the element is in the right state. The STATE_ERROR flag
indicates that an error occured while doing the last state change.
The NO_PREROLL flag indicates that the element said it was not able to preroll
in its last state change. This flag is used in live sources.
Setting state on elements
-------------------------
@ -83,7 +87,11 @@ function returns a GstElementStateReturn.
- If the element returned SUCCESS to the previous _set_state() function, this
function will return the last state set on the element and VOID_PENDING in
the pending state value.
the pending state value. The function returns GST_STATE_SUCCESS.
- If the element returned NO_PREROLL to the previous _set_state() function, this
function will return the last state set on the element and VOID_PENDING in
the pending state value. The function returns GST_STATE_NO_PREROLL.
- If the element returned FAILURE to the previous _set_state() call, this
funciton will return FAILURE with the state set to the current state of
@ -139,7 +147,7 @@ The current state of the bin can be retrieved with _get_state(). This function w
call the _get_state() function on all the elements.
First the bin will perform a _get_state() on all children with a 0 timeout. This
is to find any children with an ERROR/NO_PREROLL result value.
is to find any children with an ERROR/NO_PREROLL result value.
Then the bin performs the _get_state() with the requested timeout. The reason for
the 2 phases is that when an ERROR or NO_PREROLL result is found, a blocking