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