mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
tutorials: time-management: improve the example walkthrough
Additionally: fix missing markup
This commit is contained in:
parent
57b225749e
commit
6513190384
1 changed files with 31 additions and 34 deletions
|
@ -7,8 +7,7 @@ particular:
|
||||||
|
|
||||||
- How to query the pipeline for information like stream position or
|
- How to query the pipeline for information like stream position or
|
||||||
duration.
|
duration.
|
||||||
|
- How to seek (jump) to a different position (time) inside the
|
||||||
- How to seek (jump) to a different position (time instant) inside the
|
|
||||||
stream.
|
stream.
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
@ -20,11 +19,11 @@ is allowed, then, once the movie has been running for ten seconds, we
|
||||||
skip to a different position using a seek.
|
skip to a different position using a seek.
|
||||||
|
|
||||||
In the previous tutorials, once we had the pipeline setup and running,
|
In the previous tutorials, once we had the pipeline setup and running,
|
||||||
our main function just sat and waited to receive an ERROR or an EOS
|
our main function just sat and waited to receive an `ERROR` or an `EOS`
|
||||||
through the bus. Here we modify this function to periodically wake up
|
through the bus. Here, we modify this function to periodically wake up
|
||||||
and query the pipeline for the stream position, so we can print it on
|
and query the pipeline for the stream position, so we can print it on
|
||||||
screen. This is similar to what a media player would do, updating the
|
the screen. This is similar to what a media player would do, updating the
|
||||||
User Interface on a periodic basis.
|
user Interface on a periodic basis.
|
||||||
|
|
||||||
Finally, the stream duration is queried and updated whenever it changes.
|
Finally, the stream duration is queried and updated whenever it changes.
|
||||||
|
|
||||||
|
@ -229,11 +228,11 @@ can pass it around to other functions. In particular, in this example we
|
||||||
move the message handling code to its own function
|
move the message handling code to its own function
|
||||||
`handle_message` because it is growing a bit too big.
|
`handle_message` because it is growing a bit too big.
|
||||||
|
|
||||||
We would then build a pipeline composed of a single element, a
|
We then build a pipeline composed of a single element, a
|
||||||
`playbin`, which we already saw in [Basic tutorial 1: Hello
|
`playbin`, which we already saw in [Basic tutorial 1: Hello
|
||||||
world!](tutorials/basic/hello-world.md). However,
|
world!](tutorials/basic/hello-world.md). However,
|
||||||
`playbin` is in itself a pipeline, and in this case it is the only
|
`playbin` is in itself a pipeline, and in this case it is the only
|
||||||
element in the pipeline, so we use directly the `playbin` element. We
|
element in the pipeline, so we directly use the `playbin` element. We
|
||||||
will skip the details: the URI of the clip is given to `playbin` via
|
will skip the details: the URI of the clip is given to `playbin` via
|
||||||
the URI property and the pipeline is set to the playing state.
|
the URI property and the pipeline is set to the playing state.
|
||||||
|
|
||||||
|
@ -245,11 +244,13 @@ msg = gst_bus_timed_pop_filtered (bus, 100 * GST_MSECOND,
|
||||||
Previously we did not provide a timeout to
|
Previously we did not provide a timeout to
|
||||||
`gst_bus_timed_pop_filtered()`, meaning that it didn't return until a
|
`gst_bus_timed_pop_filtered()`, meaning that it didn't return until a
|
||||||
message was received. Now we use a timeout of 100 milliseconds, so, if
|
message was received. Now we use a timeout of 100 milliseconds, so, if
|
||||||
no message is received, 10 times per second the function will return
|
no message is received during one tenth of a second, the function will return
|
||||||
with a NULL instead of a `GstMessage`. We are going to use this to
|
`NULL`. We are going to use this logic to update our “UI”.
|
||||||
update our “UI”. Note that the timeout period is specified in
|
|
||||||
nanoseconds, so usage of the `GST_SECOND` or `GST_MSECOND` macros is
|
Note that the desired timeout must be specified as a `GstClockTime`, hence,
|
||||||
highly recommended.
|
in nanoseconds. Numbers expressing different time units then, should be
|
||||||
|
multiplied by macros like `GST_SECOND` or `GST_MSECOND`. This also makes
|
||||||
|
your code more readable.
|
||||||
|
|
||||||
If we got a message, we process it in the `handle_message`` `function
|
If we got a message, we process it in the `handle_message`` `function
|
||||||
(next subsection), otherwise:
|
(next subsection), otherwise:
|
||||||
|
@ -261,9 +262,9 @@ If we got a message, we process it in the `handle_message`` `function
|
||||||
if (data.playing) {
|
if (data.playing) {
|
||||||
```
|
```
|
||||||
|
|
||||||
First off, if we are not in the `PLAYING` state, we do not want to do
|
If the pipeline is in `PLAYING` state, it is time to refresh the screen.
|
||||||
anything here, since most queries would fail. Otherwise, it is time to
|
We don't want to do anything if we are not in `PLAYING` state, because
|
||||||
refresh the screen.
|
most queries would fail.
|
||||||
|
|
||||||
We get here approximately 10 times per second, a good enough refresh
|
We get here approximately 10 times per second, a good enough refresh
|
||||||
rate for our UI. We are going to print on screen the current media
|
rate for our UI. We are going to print on screen the current media
|
||||||
|
@ -301,8 +302,7 @@ g_print ("Position %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "\r",
|
||||||
```
|
```
|
||||||
|
|
||||||
Note the usage of the `GST_TIME_FORMAT` and `GST_TIME_ARGS` macros to
|
Note the usage of the `GST_TIME_FORMAT` and `GST_TIME_ARGS` macros to
|
||||||
provide user-friendly representation of GStreamer
|
provide a user-friendly representation of GStreamer times.
|
||||||
times.
|
|
||||||
|
|
||||||
``` c
|
``` c
|
||||||
/* If seeking is enabled, we have not done it yet, and the time is right, seek */
|
/* If seeking is enabled, we have not done it yet, and the time is right, seek */
|
||||||
|
@ -322,9 +322,9 @@ thing!
|
||||||
Let's review the parameters:
|
Let's review the parameters:
|
||||||
|
|
||||||
`GST_FORMAT_TIME` indicates that we are specifying the destination in
|
`GST_FORMAT_TIME` indicates that we are specifying the destination in
|
||||||
time, as opposite to bytes (and other more obscure mechanisms).
|
time units. Other seek-formats use different units.
|
||||||
|
|
||||||
Then come the GstSeekFlags, let's review the most common:
|
Then come the `GstSeekFlags`, let's review the most common:
|
||||||
|
|
||||||
`GST_SEEK_FLAG_FLUSH`: This discards all data currently in the pipeline
|
`GST_SEEK_FLAG_FLUSH`: This discards all data currently in the pipeline
|
||||||
before doing the seek. Might pause a bit while the pipeline is refilled
|
before doing the seek. Might pause a bit while the pipeline is refilled
|
||||||
|
@ -333,14 +333,13 @@ and the new data starts to show up, but greatly increases the
|
||||||
“stale” data might be shown for a while until the new position appears
|
“stale” data might be shown for a while until the new position appears
|
||||||
at the end of the pipeline.
|
at the end of the pipeline.
|
||||||
|
|
||||||
`GST_SEEK_FLAG_KEY_UNIT`: Most encoded video streams cannot seek to
|
`GST_SEEK_FLAG_KEY_UNIT`: With most encoded video streams, seeking to
|
||||||
arbitrary positions, only to certain frames called Key Frames. When this
|
arbitrary positions is not possible but only to certain frames called Key Frames. When this
|
||||||
flag is used, the seek will actually move to the closest key frame and
|
flag is used, the seek will actually move to the closest key frame and
|
||||||
start producing data straight away. If this flag is not used, the
|
start producing data straight away. If this flag is not used, the
|
||||||
pipeline will move internally to the closest key frame (it has no other
|
pipeline will move internally to the closest key frame (it has no other
|
||||||
alternative) but data will not be shown until it reaches the requested
|
alternative) but data will not be shown until it reaches the requested
|
||||||
position. Not providing the flag is more accurate, but might take longer
|
position. This last alternative is more accurate, but might take longer.
|
||||||
to react.
|
|
||||||
|
|
||||||
`GST_SEEK_FLAG_ACCURATE`: Some media clips do not provide enough
|
`GST_SEEK_FLAG_ACCURATE`: Some media clips do not provide enough
|
||||||
indexing information, meaning that seeking to arbitrary positions is
|
indexing information, meaning that seeking to arbitrary positions is
|
||||||
|
@ -350,14 +349,14 @@ enough for your case (you see seeks not going to the exact time you
|
||||||
asked for), then provide this flag. Be warned that it might take longer
|
asked for), then provide this flag. Be warned that it might take longer
|
||||||
to calculate the seeking position (very long, on some files).
|
to calculate the seeking position (very long, on some files).
|
||||||
|
|
||||||
And finally we provide the position to seek to. Since we asked
|
Finally, we provide the position to seek to. Since we asked
|
||||||
for `GST_FORMAT_TIME` , this position is in nanoseconds, so we use
|
for `GST_FORMAT_TIME`, the value must be in nanoseconds so we express
|
||||||
the `GST_SECOND` macro for simplicity.
|
the time in seconds, for simplicity, and then multiply by `GST_SECOND`.
|
||||||
|
|
||||||
### Message Pump
|
### Message Pump
|
||||||
|
|
||||||
The `handle_message` function processes all messages received through
|
The `handle_message` function processes all messages received through
|
||||||
the pipeline's bus. ERROR and EOS handling is the same as in previous
|
the pipeline's bus. `ERROR` and `EOS` handling is the same as in previous
|
||||||
tutorials, so we skip to the interesting part:
|
tutorials, so we skip to the interesting part:
|
||||||
|
|
||||||
``` c
|
``` c
|
||||||
|
@ -384,12 +383,10 @@ case GST_MESSAGE_STATE_CHANGED: {
|
||||||
```
|
```
|
||||||
|
|
||||||
Seeks and time queries generally only get a valid reply when in the
|
Seeks and time queries generally only get a valid reply when in the
|
||||||
PAUSED or PLAYING state, since all elements have had a chance to
|
`PAUSED` or `PLAYING` state, since all elements have had a chance to
|
||||||
receive information and configure themselves. Here we take note of
|
receive information and configure themselves. Here, we use the `playing`
|
||||||
whether we are in the PLAYING state or not with the `playing`
|
variable to keep track of whether the pipeline is in `PLAYING` state.
|
||||||
variable.
|
Also, if we have just entered the `PLAYING` state, we do our first query.
|
||||||
|
|
||||||
Also, if we have just entered the PLAYING state, we do our first query.
|
|
||||||
We ask the pipeline if seeking is allowed on this stream:
|
We ask the pipeline if seeking is allowed on this stream:
|
||||||
|
|
||||||
``` c
|
``` c
|
||||||
|
|
Loading…
Reference in a new issue