aboutsummaryrefslogtreecommitdiff
path: root/docs/design/part-segments.txt
blob: e05ec5b9e79d1b71ee769bb476f3b0dc9d599528 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
Segments
--------

A segment in GStreamer denotes a set of media samples that must be
processed. A segment has a start time, a stop time and a processing
rate. 

A media stream has a start and a stop time. The start time is
always 0 and the stop time is the total duration (or -1 if unknown, 
for example a live stream). We call this the complete media stream.

The segment of the complete media stream can be played by issuing a seek
on the stream. The seek has a start time, a stop time and a processing rate.


               complete stream
  +------------------------------------------------+
  0                                              duration
         segment
     |--------------------------|
   start                       stop


The playback of a segment starts with a source or demuxer element pushing a
segment event containing the start time, stop time and rate of the segment.
The purpose of this segment is to inform downstream elements of the 
requested segment positions. Some elements might produce buffers that fall
outside of the segment and that might therefore be discarded or clipped.


Use case: FLUSHING seek
~~~~~~~~~~~~~~~~~~~~~~~

  ex.

    filesrc ! avidemux ! videodecoder ! videosink

    When doing a seek in this pipeline for a segment 1 to 5 seconds, avidemux
    will perform the seek.

    Avidemux starts by sending a FLUSH_START event downstream and upstream. This
    will cause its streaming task to PAUSED because _pad_pull_range() and
    _pad_push() will return WRONG_STATE. It then waits for the STREAM_LOCK,
    which will be unlocked when the streaming task pauses. At this point no
    streaming is happening anymore in the pipeline and a FLUSH_STOP is sent
    upstream and downstream.

    When avidemux starts playback of the segment from second 1 to 5, it pushes
    out a segment with 1 and 5 as start and stop times. The stream_time in
    the segment is also 1 as this is the position we seek to.

    The video decoder stores these values internally and forwards them to the
    next downstream element (videosink, which also stores the values)

    Since second 1 does not contain a keyframe, the avi demuxer starts sending
    data from the previous keyframe which is at timestamp 0.

    The video decoder decodes the keyframe but knows it should not push the 
    video frame yet as it falls outside of the configured segment.

    When the video decoder receives the frame with timestamp 1, it is able to
    decode this frame as it received and decoded the data up to the previous 
    keyframe. It then continues to decode and push frames with timestamps >= 1.
    When it reaches timestamp 5, it does not decode and push frames anymore.

    The video sink receives a frame of timestamp 1. It takes the start value of 
    the previous segment and aplies the folowing (simplified) formula:

        render_time = BUFFER_TIMESTAMP - segment_start + element->base_time

    It then syncs against the clock with this render_time. Note that 
    BUFFER_TIMESTAMP is always >= segment_start or else it would fall outside of
    the configure segment.

    Videosink reports its current position as (simplified):

        current_position = clock_time - element->base_time + segment_time

    See part-synchronisation.txt for a more detailed and accurate explanation of
    synchronisation and position reporting.

    Since after a flushing seek the stream_time is reset to 0, the new buffer
    will be rendered immediately after the seek and the current_position will be
    the stream_time of the seek that was performed.

    The stop time is important when the video format contains B frames. The
    video decoder receives a P frame first, which is can decode but not push yet.
    When it receives a B frame, it can decode the B frame and push the B frame
    followed by the previously decoded P frame. If the P frame is outside of the
    segment, the decoder knows it should not send the P frame.

    Avidemux stops sending data after pushing a frame with timestamp 5 and
    returns GST_FLOW_UNEXPECTED from the chain function to make the upstream
    elements perform the EOS logic.


Use case: live stream
~~~~~~~~~~~~~~~~~~~~~




Use case: segment looping
~~~~~~~~~~~~~~~~~~~~~~~~~

  Consider the case of a wav file with raw audio.

    filesrc ! wavparse ! alsasink