Timestamps guide - #1033
Conversation
7548f9e to
b8872bf
Compare
304ef61 to
0bd2ef7
Compare
b8872bf to
3262a1e
Compare
9841fae to
b4539b0
Compare
0bd2ef7 to
a62cba5
Compare
mat-hek
left a comment
There was a problem hiding this comment.
Sounds great. I'm missing some summary/guidelines, that would emphasise that:
- DTS should always be monotonic, while PTS for video with B-frames can be non-monotonic
- Filters should always forward timestamps
- If a filter doesn't use timestamps, it should forward them, but not rely on them being set
- Sources should attach timestamps to buffers whenever they're known
- Whenever possible, elements should rely on timestamps instead of framerate or audio duration calculated from the stream
- If an element queues buffers in its state (or uses a library that does so), it should make sure that the timestamps for the output buffers are the same as for the corresponding input buffers
- You should make sure that calculations on timestamps don't introduce an accumulating error. Prefer using rationals (Ratio library) to floats.
- Elements should generate deterministic output timestamps for better testability
- If an element transforms N input buffers into M output buffers, each of the output buffers should have either:
- the timestamp of the first of the input buffers (even if only a part of it was used to construct the output buffers)
- more precise timestamps, if it's possible to calculate them
- Timestamps are harder than they seem and are the source of many bugs, including:
- Audio/video desynchronization
- Stream hanging (due to waiting indefinitely to process/play a buffer because of a wrong timestamp)
- Stream stalls (e.g. due to processing a real-time stream slightly faster than real time)
- Memory leaks (e.g. due to processing a real-time stream slightly slower than real time and indefinite buffering)
- Video flickering (due to incorrect handling of B-frames)
- Audio cracking
Therefore, the operations on timestamps should be given a lot of care and be well-tested
| @@ -0,0 +1,100 @@ | |||
| # Timestamps | |||
|
|
|||
| In a nutshell, timestamps determine when a given event occurred in time. For | |||
There was a problem hiding this comment.
| In a nutshell, timestamps determine when a given event occurred in time. For | |
| In a nutshell, timestamps determine when a given event occurred (or should occur) in time. For |
| send them over as fast as possible, which is not something we want. We want the receiver | ||
| to get the stream in realtime, so that they can display it as it comes. | ||
|
|
||
| ## Decoding Time Stamps |
There was a problem hiding this comment.
| ## Decoding Time Stamps | |
| ## Decode Time Stamps (DTS) |
| [Realtimer](https://hexdocs.pm/membrane_realtimer_plugin/Membrane.Realtimer.html) | ||
| is an element from | ||
| [membrane_realtimer_plugin](https://hex.pm/packages/membrane_realtimer_plugin). | ||
| It takes in a stream and limits its flow according to its PTSs. For example, if |
There was a problem hiding this comment.
Not really, it will take dts || pts
| should make sure that the timestamps for the output buffers are the same as for | ||
| the corresponding input buffers. | ||
| * You should ensure that calculations on timestamps don't introduce an | ||
| accumulating error. Prefer using rationals (Ratio library) to floats. |
There was a problem hiding this comment.
it could also state 'prefer using integers or rationals' (yes I know who wrote this :P)
| to create a term representing three seconds, we call `Membrane.Time.seconds(3)`. | ||
| * To read the amount of time represented, we can use `Membrane.Time.as_<unit>/2` | ||
| functions. For example, to get an amount of milliseconds represented by a time, | ||
| we call `Membrane.Time.as_milliseconds(some_time)` |
There was a problem hiding this comment.
Membrane.Time.as_milliseconds/1? It would generate a link to as_milliseconds docs, I guess
| * If a filter doesn't use timestamps, it should forward them, but not rely on | ||
| them being set. |
There was a problem hiding this comment.
It's a little bit vague to me, how could a filter "rely on" timestamps being set and not use them?
There was a problem hiding this comment.
This was my idea, and indeed it doesn't make much sense :P
| * If a filter doesn't use timestamps, it should forward them, but not rely on | |
| them being set. | |
| * If a filter doesn't use timestamps, it should still forward them. | |
| * If an element relies on timestamps and they are not set, it should raise a meaningful error. |
| to round the result to the nearest integer or `:exact` mode to get the result | ||
| as a [rational number](https://hexdocs.pm/ratio/Ratio.html#t:t/0). |
There was a problem hiding this comment.
You can mention that :exact is a default value
3841945 to
7ac230f
Compare
No description provided.