mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
docs: remove obsolete part-block document
Merge the part-block document into part-probes
This commit is contained in:
parent
d630a115f9
commit
b549918c83
3 changed files with 75 additions and 160 deletions
|
@ -4,7 +4,6 @@ EXTRA_DIST = \
|
||||||
draft-push-pull.txt \
|
draft-push-pull.txt \
|
||||||
draft-tagreading.txt \
|
draft-tagreading.txt \
|
||||||
part-activation.txt \
|
part-activation.txt \
|
||||||
part-block.txt \
|
|
||||||
part-buffering.txt \
|
part-buffering.txt \
|
||||||
part-caps.txt \
|
part-caps.txt \
|
||||||
part-clocks.txt \
|
part-clocks.txt \
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
Pad block
|
|
||||||
---------
|
|
||||||
|
|
||||||
The purpose of blocking a pad is to be notified of downstream dataflow
|
|
||||||
and events. The notification can be used for
|
|
||||||
|
|
||||||
- (Re)connecting/disconnecting the pad.
|
|
||||||
- performing a seek
|
|
||||||
- inspecting the data/events on the pad
|
|
||||||
|
|
||||||
The pad block is performed on a source pad (push based) or sink pad (pull based)
|
|
||||||
and will succeed when the following events happen on the pad:
|
|
||||||
|
|
||||||
- gst_pad_push()
|
|
||||||
- gst_pad_alloc_buffer()
|
|
||||||
- gst_pad_push_event() except for FLUSH_START and FLUSH_STOP events.
|
|
||||||
- gst_pad_pull_range () (on a sinkpad)
|
|
||||||
|
|
||||||
|
|
||||||
Flushing
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
The flushing event is used to clear any data out of the
|
|
||||||
downstream elements.
|
|
||||||
|
|
||||||
Generic case
|
|
||||||
^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Consider the following pipeline:
|
|
||||||
|
|
||||||
.-----. .-------. .-------.
|
|
||||||
| src | | elem1 |\/ | elem2 |
|
|
||||||
| src -> sink src -> sink src ....
|
|
||||||
'-----' '-------'/\ '-------'
|
|
||||||
|
|
||||||
Where elem1.src is blocked. If the pad block is taken (the callback
|
|
||||||
is called or the sync block returned) no data is flowing in elem2.sink.
|
|
||||||
In this situation, the streaming thread is blocked on a GCond and is
|
|
||||||
waiting to be unblocked.
|
|
||||||
|
|
||||||
When sending a flushing seek upstream on elem1.src, the FLUSH_START event
|
|
||||||
will temporary unblock the streaming thread and make all pad functions that
|
|
||||||
can trigger a block (_push/_query/_push_event/_pull_range) return
|
|
||||||
GST_FLOW_FLUSHING. This will then eventually pause the streaming thread
|
|
||||||
and release the STREAM_LOCK.
|
|
||||||
|
|
||||||
Since no STREAM lock is taken after the pad block it is not needed to send
|
|
||||||
the FLUSH_START event further downstream.
|
|
||||||
|
|
||||||
The FLUSH_STOP will set the srcpad to non-flushing again and is dropped
|
|
||||||
for the same reason. From then on, the new data after the flushing seek
|
|
||||||
will be queued when the pad block is taken again.
|
|
||||||
|
|
||||||
Case where the stream is blocking downstream
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
The example above is only valid if the elem1.src pad is really blocking
|
|
||||||
(callback called or sync block returned).
|
|
||||||
|
|
||||||
In the case where the stream is blocking further downstream (on elem2.src
|
|
||||||
for example, or on a blocking queue), extra care has to be taken.
|
|
||||||
|
|
||||||
Consider the following pipeline:
|
|
||||||
|
|
||||||
.-----. .-------. .-------.
|
|
||||||
| src | | elem1 |\/ | elem2 |
|
|
||||||
| src -> sink src -> sink src .... Blocking somewhere downstream
|
|
||||||
'-----' '-------'/\ '-------'
|
|
||||||
|
|
||||||
A pad block has been requested by the user on elem1.src , but since the stream
|
|
||||||
is blocking somewhere downstream, the callback is not called or the sync block
|
|
||||||
does not return.
|
|
||||||
|
|
||||||
In order for the block to happen, a FLUSH_START needs to be sent directly on
|
|
||||||
the downstream blocking element/pad so that it releases the stream lock, and it
|
|
||||||
gives a chance for the elem1.src pad to block.
|
|
||||||
|
|
||||||
|
|
||||||
Use cases
|
|
||||||
~~~~~~~~~
|
|
||||||
|
|
||||||
Prerolling a partial pipeline
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
.---------. .---------. .----------.
|
|
||||||
| filesrc | | demuxer | .-----. | decoder1 |
|
|
||||||
| src -> sink src1 ->|queue|-> sink src
|
|
||||||
'---------' | | '-----' '----------' X
|
|
||||||
| | .----------.
|
|
||||||
| | .-----. | decoder2 |
|
|
||||||
| src2 ->|queue|-> sink src
|
|
||||||
'---------' '-----' '----------' X
|
|
||||||
|
|
||||||
|
|
||||||
The purpose is to create the pipeline dynamically up to the
|
|
||||||
decoders but not yet connect them to a sink and without losing
|
|
||||||
any data.
|
|
||||||
|
|
||||||
To do this, the source pads of the decoders is blocked so that no
|
|
||||||
events or buffers can escape and we don't interrupt the stream.
|
|
||||||
|
|
||||||
When all of the dynamic pad are created (no-more-pads emited by the
|
|
||||||
branching point, ie, the demuxer or the queues filled) and the pads
|
|
||||||
are blocked (blocked callback received) the pipeline is completely
|
|
||||||
prerolled.
|
|
||||||
|
|
||||||
It should then be possible to perform the following actions on the
|
|
||||||
prerolled pipeline:
|
|
||||||
|
|
||||||
- query duration/position
|
|
||||||
- perform a flushing seek to preroll a new position
|
|
||||||
- connect other elements and unblock the blocked pads.
|
|
||||||
|
|
||||||
|
|
||||||
dynamically switching an element in a PLAYING pipeline
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
|
||||||
.----------. .----------. .----------.
|
|
||||||
| element1 | | element2 | | element3 |
|
|
||||||
... src -> sink src -> sink ...
|
|
||||||
'----------' '----------' '----------'
|
|
||||||
.----------.
|
|
||||||
| element4 |
|
|
||||||
sink src
|
|
||||||
'----------'
|
|
||||||
|
|
||||||
The purpose is to replace element2 with element4 in the PLAYING
|
|
||||||
pipeline.
|
|
||||||
|
|
||||||
1) block element1 src pad. This can be done async.
|
|
||||||
2) wait for block to happen. at that point nothing is flowing between
|
|
||||||
element1 and element2 and nothing will flow until unblocked.
|
|
||||||
3) unlink element1 and element2
|
|
||||||
4) optional step: make sure data is flushed out of element2:
|
|
||||||
4a) pad event probe on element2 src
|
|
||||||
4b) send EOS to element2, this makes sure that element2 flushes
|
|
||||||
out the last bits of data it holds.
|
|
||||||
4c) wait for EOS to appear in the probe, drop the EOS.
|
|
||||||
4d) remove the EOS pad event probe.
|
|
||||||
5) unlink element2 and element3
|
|
||||||
5a) optionally element2 can now be set to NULL and/or removed from the
|
|
||||||
pipeline.
|
|
||||||
6) link element4 and element3
|
|
||||||
7) link element1 and element4 (FIXME, how about letting element4 know
|
|
||||||
about the currently running segment?, see issues.)
|
|
||||||
8) make sure element4 is in the same state as the rest of the elements. The
|
|
||||||
element should at least be PAUSED.
|
|
||||||
9) unblock element1 src
|
|
||||||
|
|
||||||
The same flow can be used to replace an element in a PAUSED pipeline. Only
|
|
||||||
special care has to be taken when performing step 2) which has to be done
|
|
||||||
async or it might deadlock. In the async callback one can then perform the
|
|
||||||
steps from 3). In a playing pipeline one can of course use the async block
|
|
||||||
as well, so that there is a generic method for both PAUSED and PLAYING.
|
|
||||||
|
|
||||||
The same flow works as well for any chain of multiple elements and might
|
|
||||||
be implemented with a helper function in the future.
|
|
||||||
|
|
|
@ -285,3 +285,78 @@ Query probes have the GST_PAD_PROBE_TYPE_QUERY_* flag set in the callbacks.
|
||||||
For queries, the PUSH ProbeType is set when the query is traveling to the object
|
For queries, the PUSH ProbeType is set when the query is traveling to the object
|
||||||
that will answer the query and the PULL type is set when the query contains the
|
that will answer the query and the PULL type is set when the query contains the
|
||||||
answer.
|
answer.
|
||||||
|
|
||||||
|
Use-cases
|
||||||
|
---------
|
||||||
|
|
||||||
|
Prerolling a partial pipeline
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.---------. .---------. .----------.
|
||||||
|
| filesrc | | demuxer | .-----. | decoder1 |
|
||||||
|
| src -> sink src1 ->|queue|-> sink src
|
||||||
|
'---------' | | '-----' '----------' X
|
||||||
|
| | .----------.
|
||||||
|
| | .-----. | decoder2 |
|
||||||
|
| src2 ->|queue|-> sink src
|
||||||
|
'---------' '-----' '----------' X
|
||||||
|
|
||||||
|
|
||||||
|
The purpose is to create the pipeline dynamically up to the
|
||||||
|
decoders but not yet connect them to a sink and without losing
|
||||||
|
any data.
|
||||||
|
|
||||||
|
To do this, the source pads of the decoders is blocked so that no
|
||||||
|
events or buffers can escape and we don't interrupt the stream.
|
||||||
|
|
||||||
|
When all of the dynamic pad are created (no-more-pads emited by the
|
||||||
|
branching point, ie, the demuxer or the queues filled) and the pads
|
||||||
|
are blocked (blocked callback received) the pipeline is completely
|
||||||
|
prerolled.
|
||||||
|
|
||||||
|
It should then be possible to perform the following actions on the
|
||||||
|
prerolled pipeline:
|
||||||
|
|
||||||
|
- query duration/position
|
||||||
|
- perform a flushing seek to preroll a new position
|
||||||
|
- connect other elements and unblock the blocked pads.
|
||||||
|
|
||||||
|
|
||||||
|
dynamically switching an element in a PLAYING pipeline
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
||||||
|
.----------. .----------. .----------.
|
||||||
|
| element1 | | element2 | | element3 |
|
||||||
|
... src -> sink src -> sink ...
|
||||||
|
'----------' '----------' '----------'
|
||||||
|
.----------.
|
||||||
|
| element4 |
|
||||||
|
sink src
|
||||||
|
'----------'
|
||||||
|
|
||||||
|
The purpose is to replace element2 with element4 in the PLAYING
|
||||||
|
pipeline.
|
||||||
|
|
||||||
|
1) block element1 src pad.
|
||||||
|
2) inside the block callback nothing is flowing between
|
||||||
|
element1 and element2 and nothing will flow until unblocked.
|
||||||
|
3) unlink element1 and element2
|
||||||
|
4) optional step: make sure data is flushed out of element2:
|
||||||
|
4a) pad event probe on element2 src
|
||||||
|
4b) send EOS to element2, this makes sure that element2 flushes
|
||||||
|
out the last bits of data it holds.
|
||||||
|
4c) wait for EOS to appear in the probe, drop the EOS.
|
||||||
|
4d) remove the EOS pad event probe.
|
||||||
|
5) unlink element2 and element3
|
||||||
|
5a) optionally element2 can now be set to NULL and/or removed from the
|
||||||
|
pipeline.
|
||||||
|
6) link element4 and element3
|
||||||
|
7) link element1 and element4
|
||||||
|
8) make sure element4 is in the same state as the rest of the elements. The
|
||||||
|
element should at least be PAUSED.
|
||||||
|
9) unblock element1 src
|
||||||
|
|
||||||
|
The same flow can be used to replace an element in a PAUSED pipeline. Of
|
||||||
|
course in a PAUSED pipeline there might not be dataflow so the block might
|
||||||
|
not immediately happen.
|
||||||
|
|
Loading…
Reference in a new issue