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_MEDIA_PIPELINE_SERVER_INTERNAL_H_
21 : #define FIREBOLT_RIALTO_SERVER_MEDIA_PIPELINE_SERVER_INTERNAL_H_
22 :
23 : #include "DataReaderFactory.h"
24 : #include "IActiveRequests.h"
25 : #include "IGstGenericPlayer.h"
26 : #include "IMainThread.h"
27 : #include "IMediaPipelineServerInternal.h"
28 : #include "ITimer.h"
29 : #include <map>
30 : #include <memory>
31 : #include <string>
32 : #include <unordered_map>
33 : #include <vector>
34 :
35 : namespace firebolt::rialto::server
36 : {
37 : /**
38 : * @brief IMediaPipelineServerInternal factory class definition.
39 : */
40 : class MediaPipelineServerInternalFactory : public server::IMediaPipelineServerInternalFactory
41 : {
42 : public:
43 2 : MediaPipelineServerInternalFactory() = default;
44 2 : ~MediaPipelineServerInternalFactory() override = default;
45 :
46 : std::unique_ptr<IMediaPipeline> createMediaPipeline(std::weak_ptr<IMediaPipelineClient> client,
47 : const VideoRequirements &videoRequirements) const override;
48 :
49 : std::unique_ptr<server::IMediaPipelineServerInternal> createMediaPipelineServerInternal(
50 : std::weak_ptr<IMediaPipelineClient> client, const VideoRequirements &videoRequirements, int sessionId,
51 : const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer, IDecryptionService &decryptionService) const override;
52 :
53 : /**
54 : * @brief Create the generic media player factory object.
55 : *
56 : * @retval the generic media player factory instance or null on error.
57 : */
58 : static std::shared_ptr<MediaPipelineServerInternalFactory> createFactory();
59 : };
60 :
61 : /**
62 : * @brief The definition of the MediaPipelineServerInternal.
63 : */
64 : class MediaPipelineServerInternal : public IMediaPipelineServerInternal, public IGstGenericPlayerClient
65 : {
66 : public:
67 : /**
68 : * @brief The constructor.
69 : *
70 : * @param[in] client : The Rialto media player client.
71 : * @param[in] videoRequirements : The video decoder requirements for the MediaPipeline session.
72 : * @param[in] gstPlayerFactory : The gstreamer player factory.
73 : * @param[in] sessionId : The session id
74 : * @param[in] shmBuffer : The shared memory buffer
75 : * @param[in] mainThreadFactory : The main thread factory.
76 : * @param[in] dataReaderFactory : The data reader factory
77 : * @param[in] activeRequests : The active requests
78 : * @param[in] decryptionService : The decryption service
79 : */
80 : MediaPipelineServerInternal(std::shared_ptr<IMediaPipelineClient> client, const VideoRequirements &videoRequirements,
81 : const std::shared_ptr<IGstGenericPlayerFactory> &gstPlayerFactory, int sessionId,
82 : const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer,
83 : const std::shared_ptr<IMainThreadFactory> &mainThreadFactory,
84 : std::shared_ptr<common::ITimerFactory> timerFactory,
85 : std::unique_ptr<IDataReaderFactory> &&dataReaderFactory,
86 : std::unique_ptr<IActiveRequests> &&activeRequests, IDecryptionService &decryptionService);
87 :
88 : /**
89 : * @brief Virtual destructor.
90 : */
91 : virtual ~MediaPipelineServerInternal();
92 :
93 : bool load(MediaType type, const std::string &mimeType, const std::string &url) override;
94 :
95 : bool attachSource(const std::unique_ptr<MediaSource> &source) override;
96 :
97 : bool removeSource(int32_t id) override;
98 :
99 : bool allSourcesAttached() override;
100 :
101 : bool play() override;
102 :
103 : bool pause() override;
104 :
105 : bool stop() override;
106 :
107 : bool setPlaybackRate(double rate) override;
108 :
109 : bool setPosition(int64_t position) override;
110 :
111 : bool getPosition(int64_t &position) override;
112 :
113 : bool setImmediateOutput(int32_t sourceId, bool immediateOutput) override;
114 :
115 : bool getImmediateOutput(int32_t sourceId, bool &immediateOutput) override;
116 :
117 : bool getStats(int32_t sourceId, uint64_t &renderedFrames, uint64_t &droppedFrames) override;
118 :
119 : bool setVideoWindow(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override;
120 :
121 : bool haveData(MediaSourceStatus status, uint32_t needDataRequestId) override;
122 :
123 : bool haveData(MediaSourceStatus status, uint32_t numFrames, uint32_t needDataRequestId) override;
124 :
125 : void ping(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler) override;
126 :
127 : bool renderFrame() override;
128 :
129 : bool setVolume(double targetVolume, uint32_t volumeDuration, EaseType easeType) override;
130 :
131 : bool getVolume(double ¤tVolume) override;
132 :
133 : bool setMute(std::int32_t sourceId, bool mute) override;
134 :
135 : bool getMute(std::int32_t sourceId, bool &mute) override;
136 :
137 : bool setTextTrackIdentifier(const std::string &textTrackIdentifier) override;
138 :
139 : bool getTextTrackIdentifier(std::string &textTrackIdentifier) override;
140 :
141 : bool setLowLatency(bool lowLatency) override;
142 :
143 : bool setSync(bool sync) override;
144 :
145 : bool getSync(bool &sync) override;
146 :
147 : bool setSyncOff(bool syncOff) override;
148 :
149 : bool setStreamSyncMode(int32_t sourceId, int32_t streamSyncMode) override;
150 :
151 : bool getStreamSyncMode(int32_t &streamSyncMode) override;
152 :
153 : bool flush(int32_t sourceId, bool resetTime) override;
154 :
155 : bool setSourcePosition(int32_t sourceId, int64_t position, bool resetTime, double appliedRate,
156 : uint64_t stopPosition) override;
157 :
158 : bool processAudioGap(int64_t position, uint32_t duration, int64_t discontinuityGap, bool audioAac) override;
159 :
160 : bool setBufferingLimit(uint32_t limitBufferingMs) override;
161 :
162 : bool getBufferingLimit(uint32_t &limitBufferingMs) override;
163 :
164 : bool setUseBuffering(bool useBuffering) override;
165 :
166 : bool getUseBuffering(bool &useBuffering) override;
167 :
168 : bool switchSource(const std::unique_ptr<MediaSource> &source) override;
169 :
170 : AddSegmentStatus addSegment(uint32_t needDataRequestId, const std::unique_ptr<MediaSegment> &mediaSegment) override;
171 :
172 : std::weak_ptr<IMediaPipelineClient> getClient() override;
173 :
174 : void notifyPlaybackState(PlaybackState state) override;
175 :
176 : bool notifyNeedMediaData(MediaSourceType mediaSourceType) override;
177 :
178 : void notifyPosition(std::int64_t position) override;
179 :
180 : void notifyNetworkState(NetworkState state) override;
181 :
182 : void clearActiveRequestsCache() override;
183 :
184 : void invalidateActiveRequests(const MediaSourceType &type) override;
185 :
186 : void notifyQos(MediaSourceType mediaSourceType, const QosInfo &qosInfo) override;
187 :
188 : void notifyBufferUnderflow(MediaSourceType mediaSourceType) override;
189 :
190 : void notifyPlaybackError(MediaSourceType mediaSourceType, PlaybackError error) override;
191 :
192 : void notifySourceFlushed(MediaSourceType mediaSourceType) override;
193 :
194 : protected:
195 : /**
196 : * @brief The media player client.
197 : */
198 : std::shared_ptr<IMediaPipelineClient> m_mediaPipelineClient;
199 :
200 : /**
201 : * @brief The mainThread object.
202 : */
203 : std::shared_ptr<IMainThread> m_mainThread;
204 :
205 : /**
206 : * @brief The gstreamer player factory object.
207 : */
208 : const std::shared_ptr<IGstGenericPlayerFactory> m_kGstPlayerFactory;
209 :
210 : /**
211 : * @brief The gstreamer player.
212 : */
213 : std::unique_ptr<IGstGenericPlayer> m_gstPlayer;
214 :
215 : /**
216 : * @brief The video decoder requirements for the MediaPipeline session.
217 : */
218 : const VideoRequirements m_kVideoRequirements;
219 :
220 : /**
221 : * @brief ID of a session represented by this MediaPipeline
222 : */
223 : int m_sessionId;
224 :
225 : /**
226 : * @brief Shared memory buffer
227 : */
228 : std::shared_ptr<ISharedMemoryBuffer> m_shmBuffer;
229 :
230 : /**
231 : * @brief DataReader factory
232 : */
233 : std::unique_ptr<IDataReaderFactory> m_dataReaderFactory;
234 :
235 : /**
236 : * @brief Factory creating timers
237 : */
238 : std::shared_ptr<common::ITimerFactory> m_timerFactory;
239 :
240 : /**
241 : * @brief Object containing all active NeedDataRequests
242 : */
243 : std::unique_ptr<IActiveRequests> m_activeRequests;
244 :
245 : /**
246 : * @brief This objects id registered on the main thread
247 : */
248 : uint32_t m_mainThreadClientId;
249 :
250 : /**
251 : * @brief Decryption service
252 : */
253 : IDecryptionService &m_decryptionService;
254 :
255 : /**
256 : * @brief Current playback state
257 : */
258 : PlaybackState m_currentPlaybackState;
259 :
260 : /**
261 : * @brief Map containing scheduled need media data requests.
262 : */
263 : std::unordered_map<MediaSourceType, std::unique_ptr<firebolt::rialto::common::ITimer>> m_needMediaDataTimers;
264 :
265 : /**
266 : * @brief Currently attached sources
267 : */
268 : std::map<MediaSourceType, std::int32_t> m_attachedSources;
269 :
270 : /**
271 : * @brief Map to keep track of the count of MediaSourceStatus with the value NO_AVAILABLE_SAMPLES for each MediaSource
272 : */
273 : std::map<MediaSourceType, unsigned int> m_noAvailableSamplesCounter;
274 :
275 : /**
276 : * @brief Flag used to check if allSourcesAttached was already called
277 : */
278 : bool m_wasAllSourcesAttachedCalled;
279 :
280 : /**
281 : * @brief Map of flags used to check if Eos has been set on the media type for this playback
282 : */
283 : std::map<MediaSourceType, bool> m_isMediaTypeEosMap;
284 :
285 : /**
286 : * @brief Load internally, only to be called on the main thread.
287 : *
288 : * @param[in] type : The media type.
289 : * @param[in] mimeType : The MIME type.
290 : * @param[in] url : The URL.
291 : *
292 : * @retval true on success.
293 : */
294 : bool loadInternal(MediaType type, const std::string &mimeType, const std::string &url);
295 :
296 : /**
297 : * @brief Attach source internally, only to be called on the main thread.
298 : *
299 : * @param[in] source : The source.
300 : *
301 : * @retval true on success.
302 : */
303 : bool attachSourceInternal(const std::unique_ptr<MediaSource> &source);
304 :
305 : /**
306 : * @brief Remove source internally, only to be called on the main thread.
307 : *
308 : * @param[in] id : The source id.
309 : *
310 : * @retval true on success.
311 : */
312 : bool removeSourceInternal(int32_t id);
313 :
314 : /**
315 : * @brief Notify all sources attached internally, only to be called on the main thread.
316 : *
317 : * @retval true on success.
318 : */
319 : bool allSourcesAttachedInternal();
320 :
321 : /**
322 : * @brief Play internally, only to be called on the main thread.
323 : *
324 : * @retval true on success.
325 : */
326 : bool playInternal();
327 :
328 : /**
329 : * @brief Pause internally, only to be called on the main thread.
330 : *
331 : * @retval true on success.
332 : */
333 : bool pauseInternal();
334 :
335 : /**
336 : * @brief Stop internally, only to be called on the main thread.
337 : *
338 : * @retval true on success.
339 : */
340 : bool stopInternal();
341 :
342 : /**
343 : * @brief Set the playback rate internally, only to be called on the main thread.
344 : *
345 : * @param[in] rate : The playback rate.
346 : *
347 : * @retval true on success.
348 : */
349 : bool setPlaybackRateInternal(double rate);
350 :
351 : /**
352 : * @brief Set the position internally, only to be called on the main thread.
353 : *
354 : * @param[in] position : The playback position in nanoseconds.
355 : *
356 : * @retval true on success.
357 : */
358 : bool setPositionInternal(int64_t position);
359 :
360 : /**
361 : * @brief Get position internally, only to be called on the main thread.
362 : *
363 : * @param[out] position : The playback position in nanoseconds
364 : *
365 : * @retval true on success.
366 : */
367 : bool getPositionInternal(int64_t &position);
368 :
369 : /**
370 : * @brief Sets the "Immediate Output" property for this source.
371 : *
372 : * This method is asynchronous
373 : *
374 : * @param[in] sourceId : The source id. Value should be set to the MediaSource.id returned after attachSource()
375 : * @param[in] immediateOutput : The desired immediate output mode on the sink
376 : *
377 : * @retval true on success.
378 : */
379 : bool setImmediateOutputInternal(int32_t sourceId, bool immediateOutput);
380 :
381 : /**
382 : * @brief Gets the "Immediate Output" property for this source.
383 : *
384 : * This method is sychronous
385 : *
386 : * @param[in] sourceId : The source id. Value should be set to the MediaSource.id returned after attachSource()
387 : * @param[out] immediateOutput : Returns the immediate output mode on the sink
388 : *
389 : * @retval true on success.
390 : */
391 : bool getImmediateOutputInternal(int32_t sourceId, bool &immediateOutput);
392 :
393 : /**
394 : * @brief Get stats for this source.
395 : *
396 : * This method is sychronous, it returns dropped frames and rendered frames
397 : *
398 : * @param[in] sourceId : The source id. Value should be set to the MediaSource.id returned after attachSource()
399 : * @param[out] renderedFrames : The number of rendered frames
400 : * @param[out] droppedFrames : The number of dropped frames
401 : *
402 : * @retval true on success.
403 : */
404 : bool getStatsInternal(int32_t sourceId, uint64_t &renderedFrames, uint64_t &droppedFrames);
405 :
406 : /**
407 : * @brief Set video window internally, only to be called on the main thread.
408 : *
409 : * @param[in] x : The x position in pixels.
410 : * @param[in] y : The y position in pixels.
411 : * @param[in] width : The width in pixels.
412 : * @param[in] height : The height in pixels.
413 : *
414 : * @retval true on success.
415 : */
416 : bool setVideoWindowInternal(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
417 :
418 : /**
419 : * @brief Have data internally, only to be called on the main thread.
420 : *
421 : * @param[in] status : The status
422 : * @param[in] needDataRequestId : Need data request id
423 : *
424 : * @retval true on success.
425 : */
426 : bool haveDataInternal(MediaSourceStatus status, uint32_t needDataRequestId);
427 :
428 : /**
429 : * @brief Render frame internally, only to be called on the main thread.
430 : *
431 : * @retval true on success.
432 : */
433 : bool renderFrameInternal();
434 :
435 : /**
436 : * @brief Have data internally, only to be called on the main thread.
437 : *
438 : * @param[in] status : The status
439 : * @param[in] numFrames : The number of frames written.
440 : * @param[in] needDataRequestId : Need data request id
441 : *
442 : * @retval true on success.
443 : */
444 : bool haveDataInternal(MediaSourceStatus status, uint32_t numFrames, uint32_t needDataRequestId);
445 :
446 : /**
447 : * @brief Add segment internally, only to be called on the main thread.
448 : *
449 : * @param[in] needDataRequestId : The status
450 : * @param[in] mediaSegment : The data returned.
451 : *
452 : * @retval status of adding segment
453 : */
454 : AddSegmentStatus addSegmentInternal(uint32_t needDataRequestId, const std::unique_ptr<MediaSegment> &mediaSegment);
455 :
456 : /**
457 : * @brief Notify need media data internally, only to be called on the main thread.
458 : *
459 : * @param[in] mediaSourceType : The media source type.
460 : */
461 : bool notifyNeedMediaDataInternal(MediaSourceType mediaSourceType);
462 :
463 : /**
464 : * @brief Schedules resending of NeedMediaData after a short delay. Used when no segments were received in the
465 : * haveData() call to prevent a storm of needData()/haveData() calls, only to be called on the main thread.
466 : *
467 : * @param[in] mediaSourceType : The media source type.
468 : */
469 : void scheduleNotifyNeedMediaData(MediaSourceType mediaSourceType);
470 :
471 : /**
472 : * @brief Set the target volume level with a transition internally, only to be called on the main thread.
473 : *
474 : * @param[in] targetVolume : Target volume level (0.0 - 1.0)
475 : * @param[in] volumeDuration : Duration of the volume transition in milliseconds
476 : * @param[in] ease_type : Easing type for the volume transition
477 : *
478 : * @retval true on success, false otherwise
479 : */
480 : bool setVolumeInternal(double targetVolume, uint32_t volumeDuration, EaseType easeType);
481 :
482 : /**
483 : * @brief Get the current volume level internally, only to be called on the main thread.
484 : * Fetches the current volume level for the pipeline.
485 : *
486 : * @param[out] currentVolume : Current volume level (range 0.0 - 1.0)
487 : *
488 : * @retval true on success, false otherwise
489 : */
490 : bool getVolumeInternal(double ¤tVolume);
491 :
492 : /**
493 : * @brief Set mute internally, only to be called on the main thread.
494 : *
495 : * @param[in] mute Desired mute state, true=muted, false=not muted
496 : *
497 : * @retval true on success false otherwise
498 : */
499 : bool setMuteInternal(std::int32_t sourceId, bool mute);
500 :
501 : /**
502 : * @brief Get mute internally, only to be called on the main thread.
503 : *
504 : * @param[out] mute Current mute state
505 : *
506 : * @retval true on success false otherwise
507 : */
508 : bool getMuteInternal(std::int32_t sourceId, bool &mute);
509 :
510 : /**
511 : * @brief Change Text Track Identifier
512 : *
513 : * @param[in] textTrackIdentifier Text track identifier of subtitle stream
514 : *
515 : * @retval true on success false otherwise
516 : */
517 : bool setTextTrackIdentifierInternal(const std::string &textTrackIdentifier);
518 :
519 : /**
520 : * @brief Get Text Track Identifier
521 : *
522 : * @param[in] textTrackIdentifier Text track identifier of subtitle stream
523 : *
524 : * @retval true on success false otherwise
525 : */
526 : bool getTextTrackIdentifierInternal(std::string &textTrackIdentifier);
527 :
528 : /**
529 : * @brief Set low latency internally, only to be called on the main thread.
530 : *
531 : * @param[in] lowLatency : The low latency value to set.
532 : *
533 : * @retval true on success false otherwise
534 : */
535 : bool setLowLatencyInternal(bool lowLatency);
536 :
537 : /**
538 : * @brief Set sync internally, only to be called on the main thread.
539 : *
540 : * @param[in] sync : The sync value to set.
541 : *
542 : * @retval true on success false otherwise
543 : */
544 : bool setSyncInternal(bool sync);
545 :
546 : /**
547 : * @brief Get sync internally, only to be called on the main thread.
548 : *
549 : * @param[out] sync : Current sync value.
550 : *
551 : * @retval true on success false otherwise
552 : */
553 : bool getSyncInternal(bool &sync);
554 :
555 : /**
556 : * @brief Set sync off internally, only to be called on the main thread.
557 : *
558 : * @param[in] syncOff : The sync off value to set.
559 : *
560 : * @retval true on success false otherwise
561 : */
562 : bool setSyncOffInternal(bool syncOff);
563 :
564 : /**
565 : * @brief Set stream sync mode internally, only to be called on the main thread.
566 : *
567 : * @param[in] sourceId : The source id. Value should be set to the MediaSource.id returned after attachSource()
568 : * @param[in] streamSyncMode : The stream sync mode value to set.
569 : *
570 : * @retval true on success false otherwise
571 : */
572 : bool setStreamSyncModeInternal(int32_t sourceId, int32_t streamSyncMode);
573 :
574 : /**
575 : * @brief Get stream sync mode internally, only to be called on the main thread.
576 : *
577 : * @param[out] streamSyncMode : Current stream sync mode value.
578 : *
579 : * @retval true on success false otherwise
580 : */
581 : bool getStreamSyncModeInternal(int32_t &streamSyncMode);
582 :
583 : /**
584 : * @brief Checks if MediaPipeline threads are not deadlocked internally
585 : *
586 : * @param[out] heartbeatHandler : The heartbeat handler instance
587 : */
588 : void pingInternal(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler);
589 :
590 : /**
591 : * @brief Flushes a source.
592 : *
593 : * @param[in] sourceId : The source id. Value should be set to the MediaSource.id returned after attachSource()
594 : * @param[in] resetTime : True if time should be reset
595 : *
596 : * @retval true on success.
597 : */
598 : bool flushInternal(int32_t sourceId, bool resetTime);
599 :
600 : /**
601 : * @brief Set the source position in nanoseconds.
602 : *
603 : * This method sets the start position for a source.
604 : *
605 : * @param[in] sourceId : The source id. Value should be set to the MediaSource.id returned after attachSource()
606 : * @param[in] position : The position in nanoseconds.
607 : * @param[in] resetTime : True if time should be reset
608 : * @param[in] appliedRate : The applied rate after seek
609 : * @param[in] stopPosition : The position of last pushed buffer
610 : *
611 : * @retval true on success.
612 : */
613 : bool setSourcePositionInternal(int32_t sourceId, int64_t position, bool resetTime, double appliedRate,
614 : uint64_t stopPosition);
615 :
616 : /**
617 : * @brief Process audio gap
618 : *
619 : * This method handles audio gap in order to avoid audio pops during transitions.
620 : *
621 : * @param[in] position : Audio pts fade position
622 : * @param[in] duration : Audio pts fade duration
623 : * @param[in] discontinuityGap : Audio discontinuity gap
624 : * @param[in] audioAac : True if audio codec is AAC
625 : *
626 : * @retval true on success.
627 : */
628 : bool processAudioGapInternal(int64_t position, uint32_t duration, int64_t discontinuityGap, bool audioAac);
629 :
630 : /**
631 : * @brief Set buffering limit
632 : *
633 : * This method enables/disables limit buffering and sets millisecond threshold used.
634 : * Use kInvalidLimitBuffering to disable limit buffering
635 : *
636 : * @param[in] limitBufferingMs : buffering limit in ms
637 : *
638 : * @retval true on success.
639 : */
640 : bool setBufferingLimitInternal(uint32_t limitBufferingMs);
641 :
642 : /**
643 : * @brief Get buffering limit
644 : *
645 : * This method returns current value of buffering limit in milliseconds
646 : * Method will return kInvalidLimitBuffering limit buffering is disabled
647 : *
648 : * @param[out] limitBufferingMs : buffering limit in ms
649 : *
650 : * @retval true on success.
651 : */
652 : bool getBufferingLimitInternal(uint32_t &limitBufferingMs);
653 :
654 : /**
655 : * @brief Enables/disables the buffering option
656 : *
657 : * This method enables the buffering option so that BUFFERING messages are
658 : * emitted based on low-/high-percent thresholds.
659 : *
660 : * @param[in] useBuffering : true if buffering option enabled.
661 : *
662 : * @retval true on success.
663 : */
664 : bool setUseBufferingInternal(bool useBuffering);
665 :
666 : /**
667 : * @brief Checks, if buffering is enabled
668 : *
669 : * This method returns true, if buffering is enabled
670 : *
671 : * @param[out] useBuffering : true if buffering option is enabled.
672 : *
673 : * @retval true on success.
674 : */
675 : bool getUseBufferingInternal(bool &useBuffering);
676 :
677 : /**
678 : * @brief Switches a source.
679 : *
680 : * @param[in] mediaSource : The media source.
681 : *
682 : */
683 : bool switchSourceInternal(const std::unique_ptr<MediaSource> &source);
684 : };
685 :
686 : }; // namespace firebolt::rialto::server
687 :
688 : #endif // FIREBOLT_RIALTO_SERVER_MEDIA_PIPELINE_SERVER_INTERNAL_H_
|