Update theme submodule
[platform/upstream/gstreamer.git] / pwg-advanced-qos.md
1 ---
2 title: Quality Of Service (QoS)
3 ...
4
5 # Quality Of Service (QoS)
6
7 Quality of Service in GStreamer is about measuring and adjusting the
8 real-time performance of a pipeline. The real-time performance is always
9 measured relative to the pipeline clock and typically happens in the
10 sinks when they synchronize buffers against the clock.
11
12 When buffers arrive late in the sink, i.e. when their running-time is
13 smaller than that of the clock, we say that the pipeline is having a
14 quality of service problem. These are a few possible reasons:
15
16   - High CPU load, there is not enough CPU power to handle the stream,
17     causing buffers to arrive late in the sink.
18
19   - Network problems
20
21   - Other resource problems such as disk load, memory bottlenecks etc
22
23 The measurements result in QOS events that aim to adjust the datarate in
24 one or more upstream elements. Two types of adjustments can be made:
25
26   - Short time "emergency" corrections based on latest observation in
27     the sinks.
28     
29     Long term rate corrections based on trends observed in the sinks.
30
31 It is also possible for the application to artificially introduce delay
32 between synchronized buffers, this is called throttling. It can be used
33 to limit or reduce the framerate, for example.
34
35 ## Measuring QoS
36
37 Elements that synchronize buffers on the pipeline clock will usually
38 measure the current QoS. They will also need to keep some statistics in
39 order to generate the QOS event.
40
41 For each buffer that arrives in the sink, the element needs to calculate
42 how late or how early it was. This is called the jitter. Negative jitter
43 values mean that the buffer was early, positive values mean that the
44 buffer was late. the jitter value gives an indication of how early/late
45 a buffer was.
46
47 A synchronizing element will also need to calculate how much time
48 elapsed between receiving two consecutive buffers. We call this the
49 processing time because that is the amount of time it takes for the
50 upstream element to produce/process the buffer. We can compare this
51 processing time to the duration of the buffer to have a measurement of
52 how fast upstream can produce data, called the proportion. If, for
53 example, upstream can produce a buffer in 0.5 seconds of 1 second long,
54 it is operating at twice the required speed. If, on the other hand, it
55 takes 2 seconds to produce a buffer with 1 seconds worth of data,
56 upstream is producing buffers too slow and we won't be able to keep
57 synchronization. Usually, a running average is kept of the proportion.
58
59 A synchronizing element also needs to measure its own performance in
60 order to figure out if the performance problem is upstream of itself.
61
62 These measurements are used to construct a QOS event that is sent
63 upstream. Note that a QoS event is sent for each buffer that arrives in
64 the sink.
65
66 ## Handling QoS
67
68 An element will have to install an event function on its source pads in
69 order to receive QOS events. Usually, the element will need to store the
70 value of the QOS event and use them in the data processing function. The
71 element will need to use a lock to protect these QoS values as shown in
72 the example below. Also make sure to pass the QoS event upstream.
73
74 ``` c
75
76     [...]
77
78     case GST_EVENT_QOS:
79     {
80       GstQOSType type;
81       gdouble proportion;
82       GstClockTimeDiff diff;
83       GstClockTime timestamp;
84
85       gst_event_parse_qos (event, &type, &proportion, &diff, &timestamp);
86
87       GST_OBJECT_LOCK (decoder);
88       priv->qos_proportion = proportion;
89       priv->qos_timestamp = timestamp;
90       priv->qos_diff = diff;
91       GST_OBJECT_UNLOCK (decoder);
92
93       res = gst_pad_push_event (decoder->sinkpad, event);
94       break;
95     }
96
97     [...]
98
99     
100 ```
101
102 With the QoS values, there are two types of corrections that an element
103 can do:
104
105 ### Short term correction
106
107 The timestamp and the jitter value in the QOS event can be used to
108 perform a short term correction. If the jitter is positive, the previous
109 buffer arrived late and we can be sure that a buffer with a timestamp \<
110 timestamp + jitter is also going to be late. We can thus drop all
111 buffers with a timestamp less than timestamp + jitter.
112
113 If the buffer duration is known, a better estimation for the next likely
114 timestamp as: timestamp + 2 \* jitter + duration.
115
116 A possible algorithm typically looks like this:
117
118 ``` c
119
120   [...]
121
122   GST_OBJECT_LOCK (dec);
123   qos_proportion = priv->qos_proportion;
124   qos_timestamp = priv->qos_timestamp;
125   qos_diff = priv->qos_diff;
126   GST_OBJECT_UNLOCK (dec);
127
128   /* calculate the earliest valid timestamp */
129   if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (qos_timestamp))) {
130     if (G_UNLIKELY (qos_diff > 0)) {
131       earliest_time = qos_timestamp + 2 * qos_diff + frame_duration;
132     } else {
133       earliest_time = qos_timestamp + qos_diff;
134     }
135   } else {
136     earliest_time = GST_CLOCK_TIME_NONE;
137   }
138
139   /* compare earliest_time to running-time of next buffer */
140   if (earliest_time > timestamp)
141     goto drop_buffer;
142
143   [...]
144
145       
146 ```
147
148 ### Long term correction
149
150 Long term corrections are a bit more difficult to perform. They rely on
151 the value of the proportion in the QOS event. Elements should reduce the
152 amount of resources they consume by the proportion field in the QoS
153 message.
154
155 Here are some possible strategies to achieve this:
156
157   - Permanently dropping frames or reducing the CPU or bandwidth
158     requirements of the element. Some decoders might be able to skip
159     decoding of B frames.
160
161   - Switch to lower quality processing or reduce the algorithmic
162     complexity. Care should be taken that this doesn't introduce
163     disturbing visual or audible glitches.
164
165   - Switch to a lower quality source to reduce network bandwidth.
166
167   - Assign more CPU cycles to critical parts of the pipeline. This
168     could, for example, be done by increasing the thread priority.
169
170 In all cases, elements should be prepared to go back to their normal
171 processing rate when the proportion member in the QOS event approaches
172 the ideal proportion of 1.0 again.
173
174 ## Throttling
175
176 Elements synchronizing to the clock should expose a property to
177 configure them in throttle mode. In throttle mode, the time distance
178 between buffers is kept to a configurable throttle interval. This means
179 that effectively the buffer rate is limited to 1 buffer per throttle
180 interval. This can be used to limit the framerate, for example.
181
182 When an element is configured in throttling mode (this is usually only
183 implemented on sinks) it should produce QoS events upstream with the
184 jitter field set to the throttle interval. This should instruct upstream
185 elements to skip or drop the remaining buffers in the configured
186 throttle interval.
187
188 The proportion field is set to the desired slowdown needed to get the
189 desired throttle interval. Implementations can use the QoS Throttle
190 type, the proportion and the jitter member to tune their
191 implementations.
192
193 The default sink base class, has the “throttle-time” property for this
194 feature. You can test this with: `gst-launch-1.0 videotestsrc !
195 xvimagesink throttle-time=500000000`
196
197 ## QoS Messages
198
199 In addition to the QOS events that are sent between elements in the
200 pipeline, there are also QOS messages posted on the pipeline bus to
201 inform the application of QoS decisions. The QOS message contains the
202 timestamps of when something was dropped along with the amount of
203 dropped vs processed items. Elements must post a QOS message under these
204 conditions:
205
206   - The element dropped a buffer because of QoS reasons.
207
208   - An element changes its processing strategy because of QoS reasons
209     (quality). This could include a decoder that decides to drop every B
210     frame to increase its processing speed or an effect element
211     switching to a lower quality algorithm.
212