6 - must operate chain based.
7 Most simple playback pipelines will push audio from the decoders
10 - must operate getrange based
11 Most professional audio applications will operate in a mode where
12 the audio sink pulls samples from the pipeline. This is typically
13 done in a callback from the audiosink requesting N samples. The
14 callback is either scheduled from a thread or from an interrupt
15 from the audio hardware device.
17 - Exact sample accurate clocks.
18 the audiosink must be able to provide a clock that is sample
19 accurate even if samples are dropped or when discontinuities are
22 - Exact timing of playback.
23 The audiosink must be able to play samples at their exact times.
25 - use DMA access when possible.
26 When the hardware can do DMA we should use it. This should also
27 work over bufferpools to avoid data copying to/from kernel space.
32 The design is based on a set of base classes and the concept of a
33 ringbuffer of samples.
35 +-----------+ - provide preroll, rendering, timing
36 + basesink + - caps nego
39 +-----V----------+ - manages ringbuffer
40 + baseaudiosink + - manages scheduling (push/pull)
41 +-----+----------+ - manages clock/query/seek
42 | - manages scheduling of samples in the ringbuffer
43 | - manages caps parsing
45 +-----V------+ - default ringbuffer implementation with a GThread
46 + audiosink + - subclasses provide open/read/close methods
49 The ringbuffer is a contiguous piece of memory divided into segtotal
50 pieces of segments. Each segment has segsize bytes.
54 +---+---+---+-------------------------------------+----------+
55 + 0 | 1 | 2 | .... | segtotal |
56 +---+---+---+-------------------------------------+----------+
58 segsize bytes = N samples * bytes_per_sample.
61 The ringbuffer has a play position, which is expressed in
62 segments. The play position is where the device is currently reading
63 samples from the buffer.
65 The ringbuffer can be put to the PLAYING or STOPPED state.
67 In the STOPPED state no samples are played to the device and the play
68 pointer does not advance.
70 In the PLAYING state samples are written to the device and the ringbuffer
71 should call a configurable callback after each segment is written to the
72 device. In this state the play pointer is advanced after each segment is
75 A write operation to the ringbuffer will put new samples in the ringbuffer.
76 If there is not enough space in the ringbuffer, the write operation will
77 block. The playback of the buffer never stops, even if the buffer is
78 empty. When the buffer is empty, silence is played by the device.
80 The ringbuffer is implemented with lockfree atomic operations, especially
81 on the reading side so that low-latency operations are possible.
83 Whenever new samples are to be put into the ringbuffer, the position of the
84 read pointer is taken. The required write position is taken and the diff
85 is made between the required qnd actual position. If the defference is <0,
86 the sample is too late. If the difference is bigger than segtotal, the
87 writing part has to wait for the play pointer to advance.
94 In chain based mode, bytes are written into the ringbuffer. This operation
95 will eventually block when the ringbuffer is filled.
97 When no samples arrive in time, the ringbuffer will play silence. Each
98 buffer that arrives will be placed into the ringbuffer at the correct
99 times. This means that dropping samples or inserting silence is done
100 automatically and very accurate and independend of the play pointer.
102 In this mode, the ringbuffer is usually kept as full as possible. When
103 using a small buffer (small segsize and segtotal), the latency for audio
104 to start from the sink to when it is played can be kept low but at least
105 one context switch has to be made between read and write.
107 - getrange based mode
109 In getrange based mode, the baseaudiosink will use the callback function
110 of the ringbuffer to get a segsize samples from the peer element. These
111 samples will then be placed in the ringbuffer at the next play position.
112 It is assumed that the getrange function returns fast enough to fill the
113 ringbuffer before the play pointer reaches the write pointer.
115 In this mode, the ringbuffer is usually kept as empty as possible. There
116 is no context switch needed between the elements that create the samples
117 and the actual writing of the samples to the device.
122 - Elements that can do DMA based access to the audio device have to subclass
123 from the GstBaseAudioSink class and wrap the DMA ringbuffer in a subclass
126 The ringbuffer subclass should trigger a callback after writing or playing
127 each sample to the device. This callback can be triggered from a thread or
128 from a signal from the audio device.
133 The GstBaseAudioSink class will use the ringbuffer to act as a clock provider.
134 It can do this by using the play pointer and the delay to calculate the