Line data Source code
1 : /*
2 : * If not stated otherwise in this file or this component's LICENSE file the
3 : * following copyright and licenses apply:
4 : *
5 : * Copyright 2022 Sky UK
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : #ifndef FIREBOLT_RIALTO_SERVER_GENERIC_PLAYER_CONTEXT_H_
21 : #define FIREBOLT_RIALTO_SERVER_GENERIC_PLAYER_CONTEXT_H_
22 :
23 : #include "FlushOnPrerollController.h"
24 : #include "IGstProfiler.h"
25 : #include "IGstSrc.h"
26 : #include "IRdkGstreamerUtilsWrapper.h"
27 : #include "ITimer.h"
28 : #include "MediaCommon.h"
29 : #include <atomic>
30 : #include <gst/gst.h>
31 : #include <list>
32 : #include <map>
33 : #include <memory>
34 : #include <mutex>
35 : #include <optional>
36 : #include <unordered_map>
37 : #include <vector>
38 :
39 : namespace firebolt::rialto::server
40 : {
41 : constexpr double kNoPendingPlaybackRate{0.0};
42 :
43 : enum class EosState
44 : {
45 : PENDING,
46 : SET
47 : };
48 :
49 : /**
50 : * @brief Structure used for video geometry
51 : */
52 : struct Rectangle
53 : {
54 : int x, y, width, height;
55 1092 : constexpr Rectangle() : x(0), y(0), width(0), height(0) {}
56 1 : constexpr Rectangle(int x_, int y_, int w_, int h_) : x(x_), y(y_), width(w_), height(h_) {}
57 : Rectangle(const Rectangle &rhs) = default;
58 23 : inline constexpr bool empty() { return (width == 0) || (height == 0); }
59 2 : inline void clear() { x = y = width = height = 0; }
60 : };
61 :
62 : /**
63 : * @brief Structure used for set source position
64 : */
65 : struct SegmentData
66 : {
67 : int64_t position;
68 : bool resetTime;
69 : double appliedRate;
70 : uint64_t stopPosition;
71 : };
72 :
73 : struct GenericPlayerContext
74 : {
75 : /**
76 : * @brief The rialto src object.
77 : */
78 : std::shared_ptr<IGstSrc> gstSrc{nullptr};
79 :
80 : /**
81 : * @brief The gstreamer pipeline.
82 : */
83 : GstElement *pipeline{nullptr};
84 :
85 : /**
86 : * @brief The gstreamer source.
87 : */
88 : GstElement *source{nullptr};
89 :
90 : /**
91 : * @brief A map of streams attached to the source.
92 : */
93 : StreamInfoMap streamInfo{};
94 :
95 : /**
96 : * @brief Child sink of the autovideosink.
97 : */
98 : GstElement *autoVideoChildSink{nullptr};
99 :
100 : /**
101 : * @brief Child sink of the autoaudiosink.
102 : */
103 : GstElement *autoAudioChildSink{nullptr};
104 :
105 : /**
106 : * @brief The subtitle sink
107 : */
108 : GstElement *subtitleSink{nullptr};
109 :
110 : /**
111 : * @brief The video sink
112 : */
113 : GstElement *videoSink{nullptr};
114 :
115 : /**
116 : * @brief Flag used to check, if video decoder handle has been set.
117 : */
118 : bool isVideoHandleSet{false};
119 :
120 : /**
121 : * @brief Flag used to check, if BUFFERED notification has been sent.
122 : *
123 : * Flag can be used only in worker thread
124 : */
125 : bool bufferedNotificationSent{false};
126 :
127 : /**
128 : * @brief Flag used to check, if the playback is in the playing state
129 : *
130 : * Flag can be used only in worker thread
131 : */
132 : bool isPlaying{false};
133 :
134 : /**
135 : * @brief Flag used to check, if EOS has been notified to the client
136 : *
137 : * Flag can be used only in worker thread
138 : */
139 : bool eosNotified{false};
140 :
141 : /**
142 : * @brief Pending video geometry
143 : */
144 : Rectangle pendingGeometry;
145 :
146 : /**
147 : * @brief Fallback video geometry used only when setVideoWindow() was not called.
148 : */
149 : Rectangle defaultVideoGeometry;
150 :
151 : /**
152 : * @brief True once geometry has been supplied through setVideoWindow().
153 : */
154 : std::atomic_bool videoGeometrySetByApi{false};
155 :
156 : /**
157 : * @brief Current playback rate
158 : */
159 : double playbackRate{1.0};
160 :
161 : /**
162 : * @brief Pending playback rate
163 : */
164 : double pendingPlaybackRate{kNoPendingPlaybackRate};
165 :
166 : /**
167 : * @brief Pending immediate output for MediaSourceType::VIDEO
168 : */
169 : std::optional<bool> pendingImmediateOutputForVideo{};
170 :
171 : /**
172 : * @brief Pending report decode errors for MediaSourceType::VIDEO
173 : */
174 : std::optional<bool> pendingReportDecodeErrorsForVideo{};
175 :
176 : /**
177 : * @brief Pending low latency
178 : */
179 : std::optional<bool> pendingLowLatency{};
180 :
181 : /**
182 : * @brief Pending sync
183 : */
184 : std::optional<bool> pendingSync{};
185 :
186 : /**
187 : * @brief Pending sync off
188 : */
189 : std::optional<bool> pendingSyncOff{};
190 :
191 : /**
192 : * @brief Pending buffering limit
193 : */
194 : std::optional<uint32_t> pendingBufferingLimit{};
195 :
196 : /**
197 : * @brief Pending use buffering
198 : */
199 : std::optional<bool> pendingUseBuffering{};
200 :
201 : /**
202 : * @brief Pending stream sync mode
203 : */
204 : std::map<MediaSourceType, int32_t> pendingStreamSyncMode{};
205 :
206 : /**
207 : * @brief Pending render frame
208 : */
209 : bool pendingRenderFrame{false};
210 :
211 : /**
212 : * @brief Pending show video window
213 : */
214 : std::optional<bool> pendingShowVideoWindow{};
215 :
216 : /**
217 : * @brief Last audio sample timestamps
218 : * TODO(LLDEV-31012) Needed to detect audio stream underflow
219 : */
220 : int64_t lastAudioSampleTimestamps{0};
221 :
222 : /**
223 : * @brief The decryption service.
224 : */
225 : IDecryptionService *decryptionService{nullptr};
226 :
227 : /**
228 : * @brief Flag used to check, if audio source has been recently removed
229 : *
230 : * Flag can be used only in worker thread
231 : */
232 : bool audioSourceRemoved{false};
233 :
234 : /**
235 : * @brief Audio elements of gst pipeline.
236 : *
237 : * Attribute can be used only in worker thread
238 : */
239 : firebolt::rialto::wrappers::PlaybackGroupPrivate playbackGroup;
240 :
241 : /**
242 : * @brief A map of streams that have ended.
243 : */
244 : std::unordered_map<MediaSourceType, EosState> endOfStreamInfo{};
245 :
246 : /**
247 : * @brief Flag used to check if client already notified server that all sources were attached
248 : *
249 : * Attribute can be used only in worker thread
250 : */
251 : bool wereAllSourcesAttached{false};
252 :
253 : /**
254 : * @brief Flag used to check if FinishSetupSource is finished. It is needed to avoid need data overwriting.
255 : *
256 : * Attribute can be used only in worker thread
257 : */
258 : bool setupSourceFinished{false};
259 :
260 : /**
261 : * @brief Queued source positions. Used by SetSourcePosition task to request pushing new sample.
262 : *
263 : * Attribute can be used only in worker thread
264 : */
265 : std::map<GstElement *, std::vector<SegmentData>> initialPositions;
266 :
267 : /**
268 : * @brief Currently set position of a source. Used to check, if additional segment should be pushed.
269 : *
270 : * Attribute can be used only in worker thread
271 : */
272 : std::map<GstElement *, SegmentData> currentPosition;
273 :
274 : /**
275 : * @brief The mutex, which protects properties, which are read/written by main/worker thread.
276 : * This mutex should be removed in future, when we find out better solution for
277 : * property read-write.
278 : */
279 : std::mutex propertyMutex;
280 :
281 : /**
282 : * @brief Flag used to check if audio fade is enabled
283 : *
284 : * Attribute can be used only in worker thread
285 : */
286 : std::atomic_bool audioFadeEnabled{false};
287 :
288 : /**
289 : * @brief The last known fade volume value used for PlaybackInfo messages.
290 : * The "fade-volume" property must not be queried too frequently as it can cause decoder issues.
291 : */
292 : std::atomic<double> audioFadeVolume{1.0};
293 :
294 : /**
295 : * @brief Workaround for the gstreamer flush issue
296 : */
297 : std::shared_ptr<IFlushOnPrerollController> flushOnPrerollController{std::make_shared<FlushOnPrerollController>()};
298 :
299 : /**
300 : * @brief Flag used to check if the stream is live
301 : * This is a workaround for Broadcom decoder issue with audio cuts during playback rate change.
302 : */
303 : bool isLive{false};
304 :
305 : /**
306 : * @brief Profiler for player pipeline
307 : */
308 : std::unique_ptr<IGstProfiler> gstProfiler;
309 :
310 : /**
311 : * @brief True when first audio frame has already been scheduled for the current audio source lifecycle.
312 : */
313 : bool firstAudioFrameReceived{false};
314 :
315 : /**
316 : * @brief Fallback probe id for first audio frame detection on sink pad.
317 : */
318 : gulong audioFirstFrameProbeId{0};
319 :
320 : /**
321 : * @brief Fallback sink pad that owns audio first frame probe.
322 : */
323 : GstPad *audioFirstFrameProbePad{nullptr};
324 :
325 : /**
326 : * @brief The audio position set in the GstSegment.
327 : */
328 : int64_t audioGstSegmentPosition{-1};
329 :
330 : /**
331 : * @brief Current position of the stream in nanoseconds.
332 : */
333 : std::atomic<int64_t> streamPosition{-1};
334 : };
335 : } // namespace firebolt::rialto::server
336 :
337 : #endif // FIREBOLT_RIALTO_SERVER_GENERIC_PLAYER_CONTEXT_H_
|