mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 20:05:38 +00:00
docs: add draft idea for progress reporting
This commit is contained in:
parent
041d33e5f5
commit
22e64c80d2
1 changed files with 206 additions and 0 deletions
206
docs/design/draft-progress.txt
Normal file
206
docs/design/draft-progress.txt
Normal file
|
@ -0,0 +1,206 @@
|
|||
Progress Reporting
|
||||
------------------
|
||||
|
||||
This document describes the design and use cases for the progress reporting
|
||||
messages.
|
||||
|
||||
PROGRESS messages are ported on the bus to inform the application about the
|
||||
progress of asynchonous operations in the pipeline. This should not be confused
|
||||
with asynchronous state changes.
|
||||
|
||||
We accomodate for the following requirements:
|
||||
|
||||
- Application is informed when an async operation starts and completes.
|
||||
- It should be possible for the application to generically detect common
|
||||
operations and incorporate their progress into the GUI.
|
||||
- Applications can cancel pending operations by doing regular state changes.
|
||||
- Applications should be abe able to wait for completion of async operations.
|
||||
|
||||
We allow for the following scenarios:
|
||||
|
||||
- Elements want to inform the application about asynchronous DNS lookups and
|
||||
pending network requests. This includes starting and completing the lookup.
|
||||
- Elements opening devices and resources assynchronously.
|
||||
- Applications having more freedom to implement timeout and cancelation of
|
||||
operations that currently block the state changes or happen invisibly behind
|
||||
the scenes.
|
||||
|
||||
|
||||
Rationale
|
||||
~~~~~~~~~
|
||||
|
||||
The main reason for adding these extra progress notifications is twofold:
|
||||
|
||||
1) to give the application more information of what is going on
|
||||
|
||||
When there are well defined progress information categories, applications
|
||||
can let the user know about the status of the progress. We anticipate to
|
||||
have at least DNS resolving and server connections and requests be well
|
||||
defined.
|
||||
|
||||
2) To make the state changes non-blocking and cancelable.
|
||||
|
||||
Currently state changes such as going to the READY or PAUSED state often do
|
||||
blocking calls such as resolving DNS or connecting to a remote server. These
|
||||
operations often block the main thread and are often not cancelable, causing
|
||||
application lockups.
|
||||
|
||||
We would like to make the state change function, instead, start a separate
|
||||
thread that performs the blocking operations in a cancelable way. When going
|
||||
back to the NULL state, all pending operations would be canceled immediately.
|
||||
|
||||
For downward state changes, we want to let the application implement its own
|
||||
timeout mechanism. For example: when stopping an RTSP stream, the clients
|
||||
needs to send a TEARDOWN request to the server. This can however take an
|
||||
unlimited amount of time in case of network problems. We want to give the
|
||||
application an opportunity to wait (and timeout) for the completion of the
|
||||
async operation before setting the element to the final NULL state.
|
||||
|
||||
|
||||
Async state changes
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
GStreamer currently has a GST_STATE_CHANGE_ASYNC return value to note to the
|
||||
application that a state change is happening assynchronously.
|
||||
|
||||
The main purpose of this return value is to make the pipeline wait for preroll
|
||||
and delay a future (upwards) state changes until the sinks are prerolled.
|
||||
|
||||
In the case of async operations on source, this will automatically force sinks
|
||||
to stay async because they will not preroll before the source can produce data.
|
||||
|
||||
The fact that other asynchonous operations happen behind the scnes is irrelevant
|
||||
for the prerolling process so it is not implemented with the ASYNC state change
|
||||
return value in order to not complicate the state changes and mix concepts.
|
||||
|
||||
|
||||
Use cases
|
||||
~~~~~~~~~
|
||||
|
||||
* RTSP client (but also HTTP, MMS, ...)
|
||||
|
||||
When the client goes from the READY to the PAUSED state, it opens a socket,
|
||||
performs a DNS lookup, retieves the SDP and negotiates the streams. All these
|
||||
operations currently block the state change function for an undefinite amount
|
||||
of time and while they are blocking cannot be canceled.
|
||||
|
||||
Instead, a thread would be started to perform these operations assynchronously
|
||||
and the state change would complete with the usual NO_PREROLL return value.
|
||||
Before starting the thread a PROGRESS message would be posted to mark the
|
||||
start of the async operation.
|
||||
|
||||
As the DNS lookup completes and the connection is established, PROGRESS messages
|
||||
are posted on the bus to inform the application of the progress. When
|
||||
something fails, an error is posted and a PROGRESS CANCELED message is posted.
|
||||
The application can then stop the pipeline.
|
||||
|
||||
If there are no errors and the setup of the streams completed successfully, a
|
||||
PROGRESS COMPLETED is posted on the bus. The thread then goes to sleep and the
|
||||
assynchronous operation completed.
|
||||
|
||||
The RTSP protocol requires to send a TEARDOWN request to the server
|
||||
before closing the connection and destroying the socket. A state change to the
|
||||
READY state will issue the TEARDOWN request in the background and notify the
|
||||
application of this pending request with a PROGRESS message.
|
||||
|
||||
The application might want to only go to the NULL state after it got confirmation
|
||||
that the TEARDOWN request completed or it might choose to go to NULL after a
|
||||
timeout. It might also be possible that the application just want to close the
|
||||
socket as fast as possible without waiting for completion of the TEARDOWN request.
|
||||
|
||||
* Network performance measuring
|
||||
|
||||
DNS lookup and connection times can be measured by calculating the elapsed
|
||||
time between the various PROGRESS messages.
|
||||
|
||||
|
||||
|
||||
Messages
|
||||
~~~~~~~~
|
||||
|
||||
A new PROGRESS message will be created.
|
||||
The following fields will be contained in the message:
|
||||
|
||||
- "type", GST_TYPE_PROGRESS_TYPE
|
||||
|
||||
- a set of types to define the type of progress
|
||||
|
||||
GST_PROGRESS_TYPE_START: A new task is started in the background
|
||||
GST_PROGRESS_TYPE_CONTINUE: The previous tasks completed and a new
|
||||
one continues. This is done so that the application can follow
|
||||
a set of continuous tasks and react to COMPLETE only when the
|
||||
element completely finished.
|
||||
GST_PROGRESS_TYPE_CANCELED: A task is stopped, this can either be
|
||||
because the user canceled it or there was an error. In case of
|
||||
an error, an error message will have been posted before.
|
||||
GST_PROGRESS_TYPE_COMPLETE: A task completed successfully.
|
||||
|
||||
- "category", G_TYPE_STRING
|
||||
|
||||
A generic extensible string that can be used to programatically determine the
|
||||
action that is in progress. Some standard predefined categories will be
|
||||
defined.
|
||||
|
||||
- "message", G_TYPE_STRING
|
||||
|
||||
A user visible string detailing the action.
|
||||
|
||||
- "progress", GST_TYPE_FRACTION
|
||||
|
||||
A value indicating the current progress. The denominator contains the total
|
||||
amount of steps, the numerator contains the current step. This is purely
|
||||
informational and can change for each posted message.
|
||||
|
||||
- ....
|
||||
|
||||
Depending on the category, more fields can be put here.
|
||||
|
||||
|
||||
Implementation
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Elements should not do blocking operations from the state change function.
|
||||
Instead, elements should post an appropriate progress message with the right
|
||||
category and of type GST_PROGRESS_TYPE_START and then start a thread to perform
|
||||
the blocking calls in a cancelable manner.
|
||||
|
||||
The progress message needs to be posted from the state change function so that
|
||||
the application can immediately take appropriate action after setting the state.
|
||||
|
||||
The threads will usually perform many blocking calls with different categories
|
||||
in a row, a client might first do a DNS query and then continue with
|
||||
establishing a connection to the server. For this purpose the
|
||||
GST_PROGRESS_TYPE_CONTINUE must be used.
|
||||
|
||||
Usually, the thread used to perform the blocking operations can be used to
|
||||
implement the streaming threads when needed.
|
||||
|
||||
Upon downward state changes, operations that are busy in the thread are canceled
|
||||
and GST_PROGRESS_TYPE_CANCELED is posted.
|
||||
|
||||
The application can know about pending tasks because they received the
|
||||
GST_PROGRESS_TYPE_START messages that didn't complete with a
|
||||
GST_PROGRESS_TYPE_COMPLETE message or got canceled with a
|
||||
GST_PROGRESS_TYPE_CANCELED. Applications should be able to choose if
|
||||
they wait for the pending operation or cancel them.
|
||||
|
||||
If an async operation fails, an error message is posted first before the
|
||||
GST_PROGRESS_TYPE_CANCELED progress message.
|
||||
|
||||
|
||||
Categories
|
||||
~~~~~~~~~~
|
||||
|
||||
We want to propose some standard categories here:
|
||||
|
||||
"name-lookup" : A DNS lookup.
|
||||
|
||||
"connect" : A socket connection is established
|
||||
|
||||
"disconnect" : a socket connection is closed
|
||||
|
||||
"mount" : A volume is being mounted
|
||||
|
||||
"unmount" : A volume is being unmounted
|
||||
|
||||
More categories can be posted by elements and can be made official later.
|
Loading…
Reference in a new issue