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 : #include <algorithm>
21 : #include <stdexcept>
22 :
23 : #include "ActiveRequests.h"
24 : #include "DataReaderFactory.h"
25 : #include "IDataReader.h"
26 : #include "IRdkGstreamerUtilsWrapper.h"
27 : #include "ISharedMemoryBuffer.h"
28 : #include "MediaPipelineServerInternal.h"
29 : #include "NeedMediaData.h"
30 : #include "RialtoServerLogging.h"
31 : #include "TypeConverters.h"
32 :
33 : namespace
34 : {
35 1 : const char *toString(const firebolt::rialto::MediaSourceStatus &status)
36 : {
37 1 : switch (status)
38 : {
39 0 : case firebolt::rialto::MediaSourceStatus::OK:
40 0 : return "OK";
41 0 : case firebolt::rialto::MediaSourceStatus::EOS:
42 0 : return "EOS";
43 1 : case firebolt::rialto::MediaSourceStatus::ERROR:
44 1 : return "ERROR";
45 0 : case firebolt::rialto::MediaSourceStatus::CODEC_CHANGED:
46 0 : return "CODEC_CHANGED";
47 0 : case firebolt::rialto::MediaSourceStatus::NO_AVAILABLE_SAMPLES:
48 0 : return "NO_AVAILABLE_SAMPLES";
49 0 : case firebolt::rialto::MediaSourceStatus::NO_SPACE_FOR_SAMPLES:
50 0 : return "NO_SPACE_FOR_SAMPLES";
51 : }
52 0 : return "Unknown";
53 : }
54 :
55 39 : std::int32_t generateSourceId()
56 : {
57 : static std::int32_t sourceId{1};
58 39 : return sourceId++;
59 : }
60 : } // namespace
61 :
62 : namespace firebolt::rialto
63 : {
64 1 : std::shared_ptr<IMediaPipelineFactory> IMediaPipelineFactory::createFactory()
65 : {
66 1 : return server::MediaPipelineServerInternalFactory::createFactory();
67 : }
68 : }; // namespace firebolt::rialto
69 :
70 : namespace firebolt::rialto::server
71 : {
72 0 : std::shared_ptr<server::IMediaPipelineServerInternalFactory> IMediaPipelineServerInternalFactory::createFactory()
73 : {
74 0 : return MediaPipelineServerInternalFactory::createFactory();
75 : }
76 :
77 2 : std::shared_ptr<MediaPipelineServerInternalFactory> MediaPipelineServerInternalFactory::createFactory()
78 : {
79 2 : std::shared_ptr<MediaPipelineServerInternalFactory> factory;
80 :
81 : try
82 : {
83 2 : factory = std::make_shared<MediaPipelineServerInternalFactory>();
84 : }
85 0 : catch (const std::exception &e)
86 : {
87 0 : RIALTO_SERVER_LOG_ERROR("Failed to create the media player server internal factory, reason: %s", e.what());
88 : }
89 :
90 2 : return factory;
91 : }
92 :
93 : std::unique_ptr<IMediaPipeline>
94 1 : MediaPipelineServerInternalFactory::createMediaPipeline(std::weak_ptr<IMediaPipelineClient> client,
95 : const VideoRequirements &videoRequirements) const
96 : {
97 1 : RIALTO_SERVER_LOG_ERROR(
98 : "This function can't be used by rialto server. Please use createMediaPipelineServerInternal");
99 1 : return nullptr;
100 : }
101 :
102 1 : std::unique_ptr<server::IMediaPipelineServerInternal> MediaPipelineServerInternalFactory::createMediaPipelineServerInternal(
103 : std::weak_ptr<IMediaPipelineClient> client, const VideoRequirements &videoRequirements, int sessionId,
104 : const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer, IDecryptionService &decryptionService) const
105 : {
106 1 : std::shared_ptr<IMediaPipelineClient> sharedClient = client.lock();
107 1 : if (!sharedClient)
108 : {
109 0 : RIALTO_SERVER_LOG_ERROR("Couldn't create client's shared pointer");
110 0 : return nullptr;
111 : }
112 :
113 1 : std::unique_ptr<server::MediaPipelineServerInternal> mediaPipeline;
114 : try
115 : {
116 : mediaPipeline =
117 2 : std::make_unique<server::MediaPipelineServerInternal>(sharedClient, videoRequirements,
118 2 : server::IGstGenericPlayerFactory::getFactory(),
119 : sessionId, shmBuffer,
120 2 : server::IMainThreadFactory::createFactory(),
121 2 : common::ITimerFactory::getFactory(),
122 2 : std::make_unique<DataReaderFactory>(),
123 3 : std::make_unique<ActiveRequests>(), decryptionService);
124 : }
125 0 : catch (const std::exception &e)
126 : {
127 0 : RIALTO_SERVER_LOG_ERROR("Failed to create the media player server internal, reason: %s", e.what());
128 : }
129 :
130 1 : return mediaPipeline;
131 : }
132 :
133 165 : MediaPipelineServerInternal::MediaPipelineServerInternal(
134 : const std::shared_ptr<IMediaPipelineClient> &client, const VideoRequirements &videoRequirements,
135 : const std::shared_ptr<IGstGenericPlayerFactory> &gstPlayerFactory, int sessionId,
136 : const std::shared_ptr<ISharedMemoryBuffer> &shmBuffer, const std::shared_ptr<IMainThreadFactory> &mainThreadFactory,
137 : const std::shared_ptr<common::ITimerFactory> &timerFactory, std::unique_ptr<IDataReaderFactory> &&dataReaderFactory,
138 165 : std::unique_ptr<IActiveRequests> &&activeRequests, IDecryptionService &decryptionService)
139 165 : : m_mediaPipelineClient(client), m_kGstPlayerFactory(gstPlayerFactory), m_kVideoRequirements(videoRequirements),
140 165 : m_sessionId{sessionId}, m_shmBuffer{shmBuffer}, m_dataReaderFactory{std::move(dataReaderFactory)},
141 165 : m_timerFactory{timerFactory}, m_activeRequests{std::move(activeRequests)}, m_decryptionService{decryptionService},
142 495 : m_currentPlaybackState{PlaybackState::UNKNOWN}, m_wasAllSourcesAttachedCalled{false}
143 : {
144 165 : RIALTO_SERVER_LOG_DEBUG("entry:");
145 :
146 165 : m_mainThread = mainThreadFactory->getMainThread();
147 165 : if (!m_mainThread)
148 : {
149 0 : throw std::runtime_error("Failed to get the main thread");
150 : }
151 165 : m_mainThreadClientId = m_mainThread->registerClient();
152 :
153 165 : bool result = false;
154 165 : auto task = [&]()
155 : {
156 165 : if (!m_shmBuffer->mapPartition(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId))
157 : {
158 0 : RIALTO_SERVER_LOG_ERROR("Unable to map shm partition");
159 : }
160 : else
161 : {
162 165 : result = true;
163 : }
164 330 : };
165 :
166 165 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
167 165 : if (!result)
168 : {
169 0 : throw std::runtime_error("MediaPipelineServerInternal construction failed");
170 : }
171 165 : }
172 :
173 495 : MediaPipelineServerInternal::~MediaPipelineServerInternal()
174 : {
175 165 : RIALTO_SERVER_LOG_DEBUG("entry:");
176 :
177 165 : auto task = [&]()
178 : {
179 171 : for (const auto &timer : m_needMediaDataTimers)
180 : {
181 6 : if (timer.second && timer.second->isActive())
182 : {
183 6 : timer.second->cancel();
184 : }
185 : }
186 165 : if (!m_shmBuffer->unmapPartition(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId))
187 : {
188 0 : RIALTO_SERVER_LOG_ERROR("Unable to unmap shm partition");
189 : }
190 :
191 165 : m_shmBuffer.reset();
192 165 : m_mainThread->unregisterClient(m_mainThreadClientId);
193 330 : };
194 165 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
195 330 : }
196 :
197 118 : bool MediaPipelineServerInternal::load(MediaType type, const std::string &mimeType, const std::string &url, bool isLive)
198 : {
199 118 : RIALTO_SERVER_LOG_DEBUG("entry:");
200 :
201 : bool result;
202 118 : auto task = [&]() { result = loadInternal(type, mimeType, url, isLive); };
203 :
204 118 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
205 118 : return result;
206 : }
207 :
208 118 : bool MediaPipelineServerInternal::loadInternal(MediaType type, const std::string &mimeType, const std::string &url,
209 : bool isLive)
210 : {
211 118 : std::unique_lock lock{m_getPropertyMutex};
212 : /* If gstreamer player already created, destroy the old one first */
213 118 : if (m_gstPlayer)
214 : {
215 0 : m_gstPlayer.reset();
216 : }
217 :
218 : m_gstPlayer =
219 118 : m_kGstPlayerFactory
220 354 : ->createGstGenericPlayer(this, m_decryptionService, type, m_kVideoRequirements, isLive,
221 354 : firebolt::rialto::wrappers::IRdkGstreamerUtilsWrapperFactory::getFactory());
222 118 : if (!m_gstPlayer)
223 : {
224 1 : RIALTO_SERVER_LOG_ERROR("Failed to load gstreamer player");
225 1 : return false;
226 : }
227 :
228 117 : notifyNetworkState(NetworkState::BUFFERING);
229 :
230 117 : return true;
231 118 : }
232 :
233 41 : bool MediaPipelineServerInternal::attachSource(const std::unique_ptr<MediaSource> &source)
234 : {
235 41 : RIALTO_SERVER_LOG_DEBUG("entry:");
236 :
237 : bool result;
238 41 : auto task = [&]() { result = attachSourceInternal(source); };
239 :
240 41 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
241 41 : return result;
242 : }
243 :
244 41 : bool MediaPipelineServerInternal::attachSourceInternal(const std::unique_ptr<MediaSource> &source)
245 : {
246 41 : source->setId(-1);
247 :
248 41 : if (!m_gstPlayer)
249 : {
250 1 : RIALTO_SERVER_LOG_ERROR("Gstreamer player has not been loaded");
251 1 : return false;
252 : }
253 :
254 40 : if (source->getType() == MediaSourceType::UNKNOWN)
255 : {
256 0 : RIALTO_SERVER_LOG_ERROR("Media source type unknown");
257 0 : return false;
258 : }
259 :
260 40 : m_gstPlayer->attachSource(source);
261 :
262 40 : const auto kSourceIter = m_attachedSources.find(source->getType());
263 40 : if (m_attachedSources.cend() == kSourceIter)
264 : {
265 39 : source->setId(generateSourceId());
266 39 : RIALTO_SERVER_LOG_DEBUG("New ID generated for MediaSourceType: %s: %d",
267 : common::convertMediaSourceType(source->getType()), source->getId());
268 39 : m_attachedSources.emplace(source->getType(), source->getId());
269 : }
270 : else
271 : {
272 1 : RIALTO_SERVER_LOG_WARN("SourceType '%s' already attached", common::convertMediaSourceType(source->getType()));
273 1 : return false;
274 : }
275 :
276 39 : return true;
277 : }
278 :
279 4 : bool MediaPipelineServerInternal::removeSource(int32_t id)
280 : {
281 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
282 :
283 : bool result;
284 4 : auto task = [&]() { result = removeSourceInternal(id); };
285 :
286 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
287 4 : return result;
288 : }
289 :
290 4 : bool MediaPipelineServerInternal::removeSourceInternal(int32_t id)
291 : {
292 4 : if (!m_gstPlayer)
293 : {
294 1 : RIALTO_SERVER_LOG_ERROR("Failed to remove source - Gstreamer player has not been loaded");
295 1 : return false;
296 : }
297 3 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
298 2 : [id](const auto &src) { return src.second == id; });
299 3 : if (sourceIter == m_attachedSources.end())
300 : {
301 1 : RIALTO_SERVER_LOG_ERROR("Failed to remove source with id %d- Source not found", id);
302 1 : return false;
303 : }
304 :
305 2 : MediaSourceType type = sourceIter->first;
306 :
307 2 : m_gstPlayer->removeSource(type);
308 2 : m_needMediaDataTimers.erase(type);
309 2 : m_noAvailableSamplesCounter.erase(type);
310 2 : m_isMediaTypeEosMap.erase(type);
311 :
312 2 : m_attachedSources.erase(sourceIter);
313 2 : return true;
314 : }
315 :
316 4 : bool MediaPipelineServerInternal::allSourcesAttached()
317 : {
318 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
319 :
320 : bool result;
321 4 : auto task = [&]() { result = allSourcesAttachedInternal(); };
322 :
323 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
324 4 : return result;
325 : }
326 :
327 4 : bool MediaPipelineServerInternal::allSourcesAttachedInternal()
328 : {
329 4 : if (!m_gstPlayer)
330 : {
331 1 : RIALTO_SERVER_LOG_ERROR("Failed to notify all sources attached - Gstreamer player has not been loaded");
332 1 : return false;
333 : }
334 :
335 3 : if (m_wasAllSourcesAttachedCalled)
336 : {
337 1 : RIALTO_SERVER_LOG_WARN("Failed to notify all sources attached - It was already called");
338 1 : return false;
339 : }
340 :
341 2 : m_gstPlayer->allSourcesAttached();
342 2 : m_wasAllSourcesAttachedCalled = true;
343 2 : return true;
344 : }
345 :
346 2 : bool MediaPipelineServerInternal::play(bool &async)
347 : {
348 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
349 :
350 : bool result;
351 2 : auto task = [&]() { result = playInternal(async); };
352 :
353 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
354 2 : return result;
355 : }
356 :
357 2 : bool MediaPipelineServerInternal::playInternal(bool &async)
358 : {
359 2 : if (!m_gstPlayer)
360 : {
361 1 : RIALTO_SERVER_LOG_ERROR("Failed to play - Gstreamer player has not been loaded");
362 1 : return false;
363 : }
364 :
365 1 : m_gstPlayer->play(async);
366 1 : return true;
367 : }
368 :
369 2 : bool MediaPipelineServerInternal::pause()
370 : {
371 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
372 :
373 : bool result;
374 2 : auto task = [&]() { result = pauseInternal(); };
375 :
376 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
377 2 : return result;
378 : }
379 :
380 2 : bool MediaPipelineServerInternal::pauseInternal()
381 : {
382 2 : if (!m_gstPlayer)
383 : {
384 1 : RIALTO_SERVER_LOG_ERROR("Failed to pause - Gstreamer player has not been loaded");
385 1 : return false;
386 : }
387 :
388 1 : m_gstPlayer->pause();
389 1 : return true;
390 : }
391 :
392 2 : bool MediaPipelineServerInternal::stop()
393 : {
394 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
395 :
396 : bool result;
397 2 : auto task = [&]() { result = stopInternal(); };
398 :
399 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
400 2 : return result;
401 : }
402 :
403 2 : bool MediaPipelineServerInternal::stopInternal()
404 : {
405 2 : if (!m_gstPlayer)
406 : {
407 1 : RIALTO_SERVER_LOG_ERROR("Failed to stop - Gstreamer player has not been loaded");
408 1 : return false;
409 : }
410 :
411 1 : m_gstPlayer->stop();
412 1 : return true;
413 : }
414 :
415 3 : bool MediaPipelineServerInternal::setPlaybackRate(double rate)
416 : {
417 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
418 :
419 : bool result;
420 3 : auto task = [&]() { result = setPlaybackRateInternal(rate); };
421 :
422 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
423 3 : return result;
424 : }
425 :
426 3 : bool MediaPipelineServerInternal::setPlaybackRateInternal(double rate)
427 : {
428 3 : if (!m_gstPlayer)
429 : {
430 2 : RIALTO_SERVER_LOG_ERROR("Failed to set playback rate - Gstreamer player has not been loaded");
431 2 : return false;
432 : }
433 :
434 1 : if (0.0 == rate)
435 : {
436 0 : RIALTO_SERVER_LOG_ERROR("Failed to set playback rate to 0.0 - pause method should be used instead.");
437 0 : return false;
438 : }
439 :
440 1 : m_gstPlayer->setPlaybackRate(rate);
441 1 : return true;
442 : }
443 :
444 2 : bool MediaPipelineServerInternal::setPosition(int64_t position)
445 : {
446 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
447 :
448 : bool result;
449 2 : auto task = [&]() { result = setPositionInternal(position); };
450 :
451 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
452 2 : return result;
453 : }
454 :
455 2 : bool MediaPipelineServerInternal::setPositionInternal(int64_t position)
456 : {
457 2 : if (!m_gstPlayer)
458 : {
459 1 : RIALTO_SERVER_LOG_ERROR("Failed to set position - Gstreamer player has not been loaded");
460 1 : return false;
461 : }
462 :
463 1 : m_gstPlayer->setPosition(position);
464 :
465 : // Reset Eos on seek
466 1 : for (auto &isMediaTypeEos : m_isMediaTypeEosMap)
467 : {
468 0 : isMediaTypeEos.second = false;
469 : }
470 :
471 1 : m_needDataDelayCalculator.resetMediaDataDelay();
472 :
473 1 : return true;
474 : }
475 :
476 3 : bool MediaPipelineServerInternal::getPosition(int64_t &position)
477 : {
478 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
479 :
480 3 : std::shared_lock lock{m_getPropertyMutex};
481 :
482 3 : if (!m_gstPlayer)
483 : {
484 1 : RIALTO_SERVER_LOG_ERROR("Failed to get position - Gstreamer player has not been loaded");
485 1 : return false;
486 : }
487 2 : return m_gstPlayer->getPosition(position);
488 3 : }
489 :
490 3 : bool MediaPipelineServerInternal::getDuration(int64_t &duration)
491 : {
492 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
493 :
494 3 : std::shared_lock lock{m_getPropertyMutex};
495 :
496 3 : if (!m_gstPlayer)
497 : {
498 1 : RIALTO_SERVER_LOG_ERROR("Failed to get duration - Gstreamer player has not been loaded");
499 1 : return false;
500 : }
501 2 : return m_gstPlayer->getDuration(duration);
502 3 : }
503 :
504 4 : bool MediaPipelineServerInternal::getStats(int32_t sourceId, uint64_t &renderedFrames, uint64_t &droppedFrames)
505 : {
506 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
507 :
508 : bool result;
509 4 : auto task = [&]() { result = getStatsInternal(sourceId, renderedFrames, droppedFrames); };
510 :
511 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
512 4 : return result;
513 : }
514 :
515 4 : bool MediaPipelineServerInternal::getStatsInternal(int32_t sourceId, uint64_t &renderedFrames, uint64_t &droppedFrames)
516 : {
517 4 : if (!m_gstPlayer)
518 : {
519 1 : RIALTO_SERVER_LOG_ERROR("Failed to get stats - Gstreamer player has not been loaded");
520 1 : return false;
521 : }
522 3 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
523 2 : [sourceId](const auto &src) { return src.second == sourceId; });
524 3 : if (sourceIter == m_attachedSources.end())
525 : {
526 1 : RIALTO_SERVER_LOG_ERROR("Failed to get stats - Source not found");
527 1 : return false;
528 : }
529 2 : return m_gstPlayer->getStats(sourceIter->first, renderedFrames, droppedFrames);
530 : }
531 :
532 6 : bool MediaPipelineServerInternal::setImmediateOutput(int32_t sourceId, bool immediateOutput)
533 : {
534 6 : RIALTO_SERVER_LOG_DEBUG("entry:");
535 :
536 : bool result;
537 6 : auto task = [&]() { result = setImmediateOutputInternal(sourceId, immediateOutput); };
538 :
539 6 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
540 6 : return result;
541 : }
542 :
543 6 : bool MediaPipelineServerInternal::setImmediateOutputInternal(int32_t sourceId, bool immediateOutput)
544 : {
545 6 : if (!m_gstPlayer)
546 : {
547 1 : RIALTO_SERVER_LOG_ERROR("Failed - Gstreamer player has not been loaded");
548 1 : return false;
549 : }
550 5 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
551 4 : [sourceId](const auto &src) { return src.second == sourceId; });
552 5 : if (sourceIter == m_attachedSources.end())
553 : {
554 1 : RIALTO_SERVER_LOG_ERROR("Failed - Source not found");
555 1 : return false;
556 : }
557 :
558 4 : if (sourceIter->first == MediaSourceType::VIDEO)
559 : {
560 4 : m_IsLowLatencyVideoPlayer = immediateOutput;
561 : }
562 0 : else if (sourceIter->first == MediaSourceType::AUDIO)
563 : {
564 0 : m_IsLowLatencyAudioPlayer = immediateOutput;
565 : }
566 4 : return m_gstPlayer->setImmediateOutput(sourceIter->first, immediateOutput);
567 : }
568 :
569 5 : bool MediaPipelineServerInternal::setReportDecodeErrors(int32_t sourceId, bool reportDecodeErrors)
570 : {
571 5 : RIALTO_SERVER_LOG_DEBUG("entry:");
572 :
573 : bool result;
574 5 : auto task = [&]() { result = setReportDecodeErrorsInternal(sourceId, reportDecodeErrors); };
575 :
576 5 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
577 5 : return result;
578 : }
579 :
580 5 : bool MediaPipelineServerInternal::setReportDecodeErrorsInternal(int32_t sourceId, bool reportDecodeErrors)
581 : {
582 5 : if (!m_gstPlayer)
583 : {
584 1 : RIALTO_SERVER_LOG_ERROR("Failed - Gstreamer player has not been loaded");
585 1 : return false;
586 : }
587 4 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
588 3 : [sourceId](const auto &src) { return src.second == sourceId; });
589 4 : if (sourceIter == m_attachedSources.end())
590 : {
591 1 : RIALTO_SERVER_LOG_ERROR("Failed - Source not found");
592 1 : return false;
593 : }
594 :
595 3 : return m_gstPlayer->setReportDecodeErrors(sourceIter->first, reportDecodeErrors);
596 : }
597 :
598 5 : bool MediaPipelineServerInternal::getQueuedFrames(int32_t sourceId, uint32_t &queuedFrames)
599 : {
600 5 : RIALTO_SERVER_LOG_DEBUG("entry:");
601 :
602 : bool result;
603 5 : auto task = [&]() { result = getQueuedFramesInternal(sourceId, queuedFrames); };
604 :
605 5 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
606 5 : return result;
607 : }
608 :
609 5 : bool MediaPipelineServerInternal::getQueuedFramesInternal(int32_t sourceId, uint32_t &queuedFrames)
610 : {
611 5 : if (!m_gstPlayer)
612 : {
613 1 : RIALTO_SERVER_LOG_ERROR("Failed - Gstreamer player has not been loaded");
614 1 : return false;
615 : }
616 4 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
617 3 : [sourceId](const auto &src) { return src.second == sourceId; });
618 4 : if (sourceIter == m_attachedSources.end())
619 : {
620 1 : RIALTO_SERVER_LOG_ERROR("Failed - Source not found");
621 1 : return false;
622 : }
623 3 : return m_gstPlayer->getQueuedFrames(queuedFrames);
624 : }
625 :
626 5 : bool MediaPipelineServerInternal::getImmediateOutput(int32_t sourceId, bool &immediateOutput)
627 : {
628 5 : RIALTO_SERVER_LOG_DEBUG("entry:");
629 :
630 : bool result;
631 5 : auto task = [&]() { result = getImmediateOutputInternal(sourceId, immediateOutput); };
632 :
633 5 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
634 5 : return result;
635 : }
636 :
637 5 : bool MediaPipelineServerInternal::getImmediateOutputInternal(int32_t sourceId, bool &immediateOutput)
638 : {
639 5 : if (!m_gstPlayer)
640 : {
641 1 : RIALTO_SERVER_LOG_ERROR("Failed - Gstreamer player has not been loaded");
642 1 : return false;
643 : }
644 4 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
645 3 : [sourceId](const auto &src) { return src.second == sourceId; });
646 4 : if (sourceIter == m_attachedSources.end())
647 : {
648 1 : RIALTO_SERVER_LOG_ERROR("Failed - Source not found");
649 1 : return false;
650 : }
651 3 : return m_gstPlayer->getImmediateOutput(sourceIter->first, immediateOutput);
652 : }
653 :
654 2 : bool MediaPipelineServerInternal::setVideoWindow(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
655 : {
656 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
657 :
658 : bool result;
659 2 : auto task = [&]() { result = setVideoWindowInternal(x, y, width, height); };
660 :
661 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
662 2 : return result;
663 : }
664 :
665 2 : bool MediaPipelineServerInternal::setVideoWindowInternal(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
666 : {
667 2 : if (!m_gstPlayer)
668 : {
669 1 : RIALTO_SERVER_LOG_ERROR("Failed to set video window - Gstreamer player has not been loaded");
670 1 : return false;
671 : }
672 :
673 1 : m_gstPlayer->setVideoGeometry(x, y, width, height);
674 1 : return true;
675 : }
676 :
677 13 : bool MediaPipelineServerInternal::haveData(MediaSourceStatus status, uint32_t needDataRequestId)
678 : {
679 13 : RIALTO_SERVER_LOG_DEBUG("entry:");
680 :
681 : bool result;
682 13 : auto task = [&]() { result = haveDataInternal(status, needDataRequestId); };
683 :
684 13 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
685 13 : return result;
686 : }
687 :
688 13 : bool MediaPipelineServerInternal::haveDataInternal(MediaSourceStatus status, uint32_t needDataRequestId)
689 : {
690 13 : if (!m_gstPlayer)
691 : {
692 1 : RIALTO_SERVER_LOG_ERROR("HaveData failed - Gstreamer player has not been loaded");
693 1 : return false;
694 : }
695 :
696 12 : MediaSourceType mediaSourceType = m_activeRequests->getType(needDataRequestId);
697 12 : if (MediaSourceType::UNKNOWN == mediaSourceType)
698 : {
699 1 : RIALTO_SERVER_LOG_WARN("NeedData RequestID is not valid: %u", needDataRequestId);
700 1 : return true;
701 : }
702 :
703 11 : unsigned int &counter = m_noAvailableSamplesCounter[mediaSourceType];
704 11 : if (status != MediaSourceStatus::OK && status != MediaSourceStatus::EOS)
705 : {
706 : // Incrementing the counter allows us to track the occurrences where the status is other than OK or EOS.
707 :
708 3 : ++counter;
709 3 : if (status == MediaSourceStatus::NO_AVAILABLE_SAMPLES)
710 : {
711 2 : RIALTO_SERVER_LOG_DEBUG("Data request for needDataRequestId: %u. NO_AVAILABLE_SAMPLES received: %u "
712 : "consecutively for mediaSourceType: %s",
713 : needDataRequestId, counter, common::convertMediaSourceType(mediaSourceType));
714 : }
715 : else
716 : {
717 1 : RIALTO_SERVER_LOG_WARN("%s Data request for needDataRequestId: %u received with wrong status: %s",
718 : common::convertMediaSourceType(mediaSourceType), needDataRequestId, toString(status));
719 1 : counter = 0;
720 : }
721 :
722 3 : m_activeRequests->erase(needDataRequestId);
723 3 : scheduleNotifyNeedMediaData(mediaSourceType);
724 3 : return true;
725 : }
726 : else
727 : {
728 8 : RIALTO_SERVER_LOG_DEBUG("%s Data request for needDataRequestId: %u received with correct status",
729 : common::convertMediaSourceType(mediaSourceType), needDataRequestId);
730 8 : counter = 0;
731 : }
732 :
733 : try
734 : {
735 8 : const IMediaPipeline::MediaSegmentVector &kSegments = m_activeRequests->getSegments(needDataRequestId);
736 7 : m_gstPlayer->attachSamples(kSegments);
737 : }
738 1 : catch (const std::runtime_error &e)
739 : {
740 1 : RIALTO_SERVER_LOG_ERROR("Failed to get segments %s", e.what());
741 1 : m_activeRequests->erase(needDataRequestId);
742 1 : return false;
743 : }
744 :
745 7 : m_activeRequests->erase(needDataRequestId);
746 7 : if (status == MediaSourceStatus::EOS)
747 : {
748 6 : m_gstPlayer->setEos(mediaSourceType);
749 6 : m_isMediaTypeEosMap[mediaSourceType] = true;
750 : }
751 :
752 7 : return true;
753 : }
754 :
755 15 : bool MediaPipelineServerInternal::haveData(MediaSourceStatus status, uint32_t numFrames, uint32_t needDataRequestId)
756 : {
757 15 : RIALTO_SERVER_LOG_DEBUG("entry:");
758 :
759 : bool result;
760 15 : auto task = [&]() { result = haveDataInternal(status, numFrames, needDataRequestId); };
761 :
762 15 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
763 15 : return result;
764 : }
765 :
766 15 : bool MediaPipelineServerInternal::haveDataInternal(MediaSourceStatus status, uint32_t numFrames,
767 : uint32_t needDataRequestId)
768 : {
769 15 : if (!m_gstPlayer)
770 : {
771 1 : RIALTO_SERVER_LOG_ERROR("HaveData failed - Gstreamer player has not been loaded");
772 1 : return false;
773 : }
774 14 : MediaSourceType mediaSourceType = m_activeRequests->getType(needDataRequestId);
775 14 : if (MediaSourceType::UNKNOWN == mediaSourceType)
776 : {
777 1 : RIALTO_SERVER_LOG_WARN("NeedData RequestID is not valid: %u", needDataRequestId);
778 1 : return true;
779 : }
780 13 : const std::uint32_t kMaxNumFrames = m_activeRequests->getMaxFrames(needDataRequestId);
781 13 : m_activeRequests->erase(needDataRequestId);
782 :
783 13 : unsigned int &counter = m_noAvailableSamplesCounter[mediaSourceType];
784 13 : if (status != MediaSourceStatus::OK && status != MediaSourceStatus::EOS &&
785 : status != MediaSourceStatus::NO_SPACE_FOR_SAMPLES)
786 : {
787 : // Incrementing the counter allows us to track the occurrences where the status is other than OK or EOS.
788 :
789 4 : ++counter;
790 4 : if (status == MediaSourceStatus::NO_AVAILABLE_SAMPLES)
791 : {
792 0 : RIALTO_SERVER_LOG_DEBUG("Data request for needDataRequestId: %u. NO_AVAILABLE_SAMPLES received: %u "
793 : "consecutively for mediaSourceType: %s",
794 : needDataRequestId, counter, common::convertMediaSourceType(mediaSourceType));
795 : }
796 : else
797 : {
798 4 : RIALTO_SERVER_LOG_WARN("%s Data request for needDataRequestId: %u received with wrong status",
799 : common::convertMediaSourceType(mediaSourceType), needDataRequestId);
800 4 : counter = 0;
801 : }
802 4 : scheduleNotifyNeedMediaData(mediaSourceType);
803 4 : return true;
804 : }
805 : else
806 : {
807 9 : RIALTO_SERVER_LOG_DEBUG("%s Data request for needDataRequestId: %u received with correct status",
808 : common::convertMediaSourceType(mediaSourceType), needDataRequestId);
809 9 : counter = 0;
810 : }
811 :
812 9 : uint8_t *buffer = m_shmBuffer->getBuffer();
813 9 : if (!buffer)
814 : {
815 1 : RIALTO_SERVER_LOG_ERROR("No buffer available");
816 1 : notifyPlaybackState(PlaybackState::FAILURE);
817 1 : return false;
818 : }
819 :
820 8 : std::uint32_t regionOffset = 0;
821 : try
822 : {
823 : regionOffset =
824 8 : m_shmBuffer->getDataOffset(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId, mediaSourceType);
825 : }
826 1 : catch (const std::runtime_error &e)
827 : {
828 1 : RIALTO_SERVER_LOG_ERROR("Failed to get region's buffer offset, reason: %s", e.what());
829 1 : notifyPlaybackState(PlaybackState::FAILURE);
830 1 : return false;
831 : }
832 :
833 7 : if (0 != numFrames)
834 : {
835 6 : const bool kIsBufferFull = kMaxNumFrames == numFrames || status == MediaSourceStatus::NO_SPACE_FOR_SAMPLES ||
836 : status == MediaSourceStatus::EOS;
837 : std::shared_ptr<IDataReader> dataReader =
838 6 : m_dataReaderFactory->createDataReader(mediaSourceType, buffer, regionOffset, numFrames, kIsBufferFull);
839 6 : if (!dataReader)
840 : {
841 1 : RIALTO_SERVER_LOG_ERROR("Metadata version not supported for %s request id: %u",
842 : common::convertMediaSourceType(mediaSourceType), needDataRequestId);
843 1 : notifyPlaybackState(PlaybackState::FAILURE);
844 1 : return false;
845 : }
846 5 : m_gstPlayer->attachSamples(dataReader);
847 6 : }
848 6 : if (status == MediaSourceStatus::EOS)
849 : {
850 2 : m_gstPlayer->setEos(mediaSourceType);
851 2 : m_isMediaTypeEosMap[mediaSourceType] = true;
852 : }
853 :
854 6 : return true;
855 : }
856 :
857 2 : void MediaPipelineServerInternal::ping(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler)
858 : {
859 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
860 :
861 2 : auto task = [&]() { pingInternal(std::move(heartbeatHandler)); };
862 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
863 : }
864 :
865 2 : void MediaPipelineServerInternal::pingInternal(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler)
866 : {
867 2 : if (!m_gstPlayer)
868 : {
869 : // No need to check GstPlayer worker thread, we reached this function, so main thread is working fine.
870 1 : heartbeatHandler.reset();
871 1 : return;
872 : }
873 : // Check GstPlayer worker thread
874 1 : m_gstPlayer->ping(std::move(heartbeatHandler));
875 : }
876 :
877 2 : bool MediaPipelineServerInternal::renderFrame()
878 : {
879 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
880 :
881 : bool result;
882 2 : auto task = [&]() { result = renderFrameInternal(); };
883 :
884 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
885 2 : return result;
886 : }
887 :
888 2 : bool MediaPipelineServerInternal::renderFrameInternal()
889 : {
890 2 : if (!m_gstPlayer)
891 : {
892 1 : RIALTO_SERVER_LOG_ERROR("renderFrame failed - Gstreamer player has not been loaded");
893 1 : return false;
894 : }
895 :
896 1 : m_gstPlayer->renderFrame();
897 1 : return true;
898 : }
899 :
900 2 : bool MediaPipelineServerInternal::setVolume(double targetVolume, uint32_t volumeDuration, EaseType easeType)
901 : {
902 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
903 :
904 : bool result;
905 2 : auto task = [&]() { result = setVolumeInternal(targetVolume, volumeDuration, easeType); };
906 :
907 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
908 2 : return result;
909 : }
910 :
911 2 : bool MediaPipelineServerInternal::setVolumeInternal(double targetVolume, uint32_t volumeDuration, EaseType easeType)
912 : {
913 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
914 :
915 2 : if (!m_gstPlayer)
916 : {
917 1 : RIALTO_SERVER_LOG_ERROR("Failed to set volume - Gstreamer player has not been loaded");
918 1 : return false;
919 : }
920 1 : m_gstPlayer->setVolume(targetVolume, volumeDuration, easeType);
921 1 : return true;
922 : }
923 :
924 3 : bool MediaPipelineServerInternal::getVolume(double ¤tVolume)
925 : {
926 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
927 :
928 : bool result;
929 3 : auto task = [&]() { result = getVolumeInternal(currentVolume); };
930 :
931 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
932 3 : return result;
933 : }
934 :
935 3 : bool MediaPipelineServerInternal::getVolumeInternal(double ¤tVolume)
936 : {
937 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
938 :
939 3 : if (!m_gstPlayer)
940 : {
941 1 : RIALTO_SERVER_LOG_ERROR("Failed to get volume - Gstreamer player has not been loaded");
942 1 : return false;
943 : }
944 2 : return m_gstPlayer->getVolume(currentVolume);
945 : }
946 :
947 3 : bool MediaPipelineServerInternal::setMute(std::int32_t sourceId, bool mute)
948 : {
949 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
950 :
951 : bool result;
952 3 : auto task = [&]() { result = setMuteInternal(sourceId, mute); };
953 :
954 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
955 3 : return result;
956 : }
957 :
958 3 : bool MediaPipelineServerInternal::setMuteInternal(std::int32_t sourceId, bool mute)
959 : {
960 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
961 :
962 3 : if (!m_gstPlayer)
963 : {
964 1 : RIALTO_SERVER_LOG_ERROR("Failed to set mute - Gstreamer player has not been loaded");
965 1 : return false;
966 : }
967 :
968 2 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
969 1 : [sourceId](const auto &src) { return src.second == sourceId; });
970 2 : if (sourceIter == m_attachedSources.end())
971 : {
972 1 : RIALTO_SERVER_LOG_ERROR("Failed to set mute - Source with id: %d not found", sourceId);
973 1 : return false;
974 : }
975 :
976 1 : m_gstPlayer->setMute(sourceIter->first, mute);
977 :
978 1 : return true;
979 : }
980 :
981 4 : bool MediaPipelineServerInternal::getMute(std::int32_t sourceId, bool &mute)
982 : {
983 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
984 :
985 : bool result;
986 4 : auto task = [&]() { result = getMuteInternal(sourceId, mute); };
987 :
988 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
989 4 : return result;
990 : }
991 :
992 4 : bool MediaPipelineServerInternal::getMuteInternal(std::int32_t sourceId, bool &mute)
993 : {
994 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
995 :
996 4 : if (!m_gstPlayer)
997 : {
998 1 : RIALTO_SERVER_LOG_ERROR("Failed to get mute - Gstreamer player has not been loaded");
999 1 : return false;
1000 : }
1001 :
1002 3 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
1003 2 : [sourceId](const auto &src) { return src.second == sourceId; });
1004 3 : if (sourceIter == m_attachedSources.end())
1005 : {
1006 1 : RIALTO_SERVER_LOG_ERROR("Failed to get mute - Source with id: %d not found", sourceId);
1007 1 : return false;
1008 : }
1009 :
1010 2 : return m_gstPlayer->getMute(sourceIter->first, mute);
1011 : }
1012 :
1013 2 : bool MediaPipelineServerInternal::setTextTrackIdentifier(const std::string &textTrackIdentifier)
1014 : {
1015 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1016 :
1017 : bool result;
1018 2 : auto task = [&]() { result = setTextTrackIdentifierInternal(textTrackIdentifier); };
1019 :
1020 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1021 2 : return result;
1022 : }
1023 :
1024 2 : bool MediaPipelineServerInternal::setTextTrackIdentifierInternal(const std::string &textTrackIdentifier)
1025 : {
1026 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1027 :
1028 2 : if (!m_gstPlayer)
1029 : {
1030 1 : RIALTO_SERVER_LOG_ERROR("Failed to set text track identifier - Gstreamer player has not been loaded");
1031 1 : return false;
1032 : }
1033 :
1034 1 : m_gstPlayer->setTextTrackIdentifier(textTrackIdentifier);
1035 :
1036 1 : return true;
1037 : }
1038 :
1039 3 : bool MediaPipelineServerInternal::getTextTrackIdentifier(std::string &textTrackIdentifier)
1040 : {
1041 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1042 :
1043 : bool result;
1044 3 : auto task = [&]() { result = getTextTrackIdentifierInternal(textTrackIdentifier); };
1045 :
1046 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1047 3 : return result;
1048 : }
1049 :
1050 3 : bool MediaPipelineServerInternal::getTextTrackIdentifierInternal(std::string &textTrackIdentifier)
1051 : {
1052 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1053 :
1054 3 : if (!m_gstPlayer)
1055 : {
1056 1 : RIALTO_SERVER_LOG_ERROR("Failed to get mute - Gstreamer player has not been loaded");
1057 1 : return false;
1058 : }
1059 :
1060 2 : return m_gstPlayer->getTextTrackIdentifier(textTrackIdentifier);
1061 : }
1062 :
1063 4 : bool MediaPipelineServerInternal::flush(int32_t sourceId, bool resetTime, bool &async)
1064 : {
1065 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
1066 :
1067 : bool result;
1068 4 : auto task = [&]() { result = flushInternal(sourceId, resetTime, async); };
1069 :
1070 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1071 4 : return result;
1072 : }
1073 :
1074 4 : bool MediaPipelineServerInternal::setLowLatency(bool lowLatency)
1075 : {
1076 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
1077 :
1078 : bool result;
1079 4 : auto task = [&]() { result = setLowLatencyInternal(lowLatency); };
1080 :
1081 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1082 4 : return result;
1083 : }
1084 :
1085 4 : bool MediaPipelineServerInternal::setLowLatencyInternal(bool lowLatency)
1086 : {
1087 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
1088 :
1089 4 : if (!m_gstPlayer)
1090 : {
1091 1 : RIALTO_SERVER_LOG_ERROR("Failed to set low latency - Gstreamer player has not been loaded");
1092 1 : return false;
1093 : }
1094 3 : m_IsLowLatencyAudioPlayer = lowLatency;
1095 :
1096 3 : return m_gstPlayer->setLowLatency(lowLatency);
1097 : }
1098 :
1099 3 : bool MediaPipelineServerInternal::setSync(bool sync)
1100 : {
1101 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1102 :
1103 : bool result;
1104 3 : auto task = [&]() { result = setSyncInternal(sync); };
1105 :
1106 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1107 3 : return result;
1108 : }
1109 :
1110 3 : bool MediaPipelineServerInternal::setSyncInternal(bool sync)
1111 : {
1112 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1113 :
1114 3 : if (!m_gstPlayer)
1115 : {
1116 1 : RIALTO_SERVER_LOG_ERROR("Failed to set sync - Gstreamer player has not been loaded");
1117 1 : return false;
1118 : }
1119 2 : return m_gstPlayer->setSync(sync);
1120 : }
1121 :
1122 3 : bool MediaPipelineServerInternal::getSync(bool &sync)
1123 : {
1124 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1125 :
1126 : bool result;
1127 3 : auto task = [&]() { result = getSyncInternal(sync); };
1128 :
1129 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1130 3 : return result;
1131 : }
1132 :
1133 3 : bool MediaPipelineServerInternal::getSyncInternal(bool &sync)
1134 : {
1135 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1136 :
1137 3 : if (!m_gstPlayer)
1138 : {
1139 1 : RIALTO_SERVER_LOG_ERROR("Failed to get sync - Gstreamer player has not been loaded");
1140 1 : return false;
1141 : }
1142 2 : return m_gstPlayer->getSync(sync);
1143 : }
1144 :
1145 3 : bool MediaPipelineServerInternal::setSyncOff(bool syncOff)
1146 : {
1147 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1148 :
1149 : bool result;
1150 3 : auto task = [&]() { result = setSyncOffInternal(syncOff); };
1151 :
1152 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1153 3 : return result;
1154 : }
1155 :
1156 3 : bool MediaPipelineServerInternal::setSyncOffInternal(bool syncOff)
1157 : {
1158 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1159 :
1160 3 : if (!m_gstPlayer)
1161 : {
1162 1 : RIALTO_SERVER_LOG_ERROR("Failed to set sync off - Gstreamer player has not been loaded");
1163 1 : return false;
1164 : }
1165 2 : return m_gstPlayer->setSyncOff(syncOff);
1166 : }
1167 :
1168 4 : bool MediaPipelineServerInternal::setStreamSyncMode(int32_t sourceId, int32_t streamSyncMode)
1169 : {
1170 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
1171 :
1172 : bool result;
1173 4 : auto task = [&]() { result = setStreamSyncModeInternal(sourceId, streamSyncMode); };
1174 :
1175 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1176 4 : return result;
1177 : }
1178 :
1179 4 : bool MediaPipelineServerInternal::setStreamSyncModeInternal(int32_t sourceId, int32_t streamSyncMode)
1180 : {
1181 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
1182 :
1183 4 : if (!m_gstPlayer)
1184 : {
1185 1 : RIALTO_SERVER_LOG_ERROR("Failed to set stream sync mode - Gstreamer player has not been loaded");
1186 1 : return false;
1187 : }
1188 :
1189 3 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
1190 2 : [sourceId](const auto &src) { return src.second == sourceId; });
1191 3 : if (sourceIter == m_attachedSources.end())
1192 : {
1193 1 : RIALTO_SERVER_LOG_ERROR("Failed to set stream sync mode - Source with id: %d not found", sourceId);
1194 1 : return false;
1195 : }
1196 :
1197 2 : return m_gstPlayer->setStreamSyncMode(sourceIter->first, streamSyncMode);
1198 : }
1199 :
1200 3 : bool MediaPipelineServerInternal::getStreamSyncMode(int32_t &streamSyncMode)
1201 : {
1202 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1203 :
1204 : bool result;
1205 3 : auto task = [&]() { result = getStreamSyncModeInternal(streamSyncMode); };
1206 :
1207 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1208 3 : return result;
1209 : }
1210 :
1211 3 : bool MediaPipelineServerInternal::getStreamSyncModeInternal(int32_t &streamSyncMode)
1212 : {
1213 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1214 :
1215 3 : if (!m_gstPlayer)
1216 : {
1217 1 : RIALTO_SERVER_LOG_ERROR("Failed to get stream sync mode - Gstreamer player has not been loaded");
1218 1 : return false;
1219 : }
1220 2 : return m_gstPlayer->getStreamSyncMode(streamSyncMode);
1221 : }
1222 :
1223 4 : bool MediaPipelineServerInternal::flushInternal(int32_t sourceId, bool resetTime, bool &async)
1224 : {
1225 4 : if (!m_gstPlayer)
1226 : {
1227 1 : RIALTO_SERVER_LOG_ERROR("Failed to flush - Gstreamer player has not been loaded");
1228 1 : return false;
1229 : }
1230 3 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
1231 2 : [sourceId](const auto &src) { return src.second == sourceId; });
1232 3 : if (sourceIter == m_attachedSources.end())
1233 : {
1234 1 : RIALTO_SERVER_LOG_ERROR("Failed to flush - Source with id: %d not found", sourceId);
1235 1 : return false;
1236 : }
1237 :
1238 2 : m_gstPlayer->flush(sourceIter->first, resetTime, async);
1239 :
1240 2 : m_needMediaDataTimers.erase(sourceIter->first);
1241 :
1242 : // Reset Eos on flush
1243 2 : auto it = m_isMediaTypeEosMap.find(sourceIter->first);
1244 2 : if (it != m_isMediaTypeEosMap.end() && it->second)
1245 : {
1246 1 : it->second = false;
1247 : }
1248 :
1249 2 : return true;
1250 : }
1251 :
1252 3 : bool MediaPipelineServerInternal::setSourcePosition(int32_t sourceId, int64_t position, bool resetTime,
1253 : double appliedRate, uint64_t stopPosition)
1254 : {
1255 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1256 :
1257 : bool result;
1258 3 : auto task = [&]() { result = setSourcePositionInternal(sourceId, position, resetTime, appliedRate, stopPosition); };
1259 :
1260 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1261 3 : return result;
1262 : }
1263 :
1264 3 : bool MediaPipelineServerInternal::setSourcePositionInternal(int32_t sourceId, int64_t position, bool resetTime,
1265 : double appliedRate, uint64_t stopPosition)
1266 : {
1267 3 : if (!m_gstPlayer)
1268 : {
1269 1 : RIALTO_SERVER_LOG_ERROR("Failed to set source position - Gstreamer player has not been loaded");
1270 1 : return false;
1271 : }
1272 2 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
1273 1 : [sourceId](const auto &src) { return src.second == sourceId; });
1274 2 : if (sourceIter == m_attachedSources.end())
1275 : {
1276 1 : RIALTO_SERVER_LOG_ERROR("Failed to set source position - Source with id: %d not found", sourceId);
1277 1 : return false;
1278 : }
1279 :
1280 1 : m_gstPlayer->setSourcePosition(sourceIter->first, position, resetTime, appliedRate, stopPosition);
1281 :
1282 : // Reset Eos on seek
1283 1 : auto it = m_isMediaTypeEosMap.find(sourceIter->first);
1284 1 : if (it != m_isMediaTypeEosMap.end() && it->second)
1285 : {
1286 0 : it->second = false;
1287 : }
1288 :
1289 1 : return true;
1290 : }
1291 :
1292 3 : bool MediaPipelineServerInternal::setSubtitleOffset(int32_t sourceId, int64_t position)
1293 : {
1294 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1295 :
1296 : bool result;
1297 3 : auto task = [&]() { result = setSubtitleOffsetInternal(sourceId, position); };
1298 :
1299 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1300 3 : return result;
1301 : }
1302 :
1303 3 : bool MediaPipelineServerInternal::setSubtitleOffsetInternal(int32_t sourceId, int64_t position)
1304 : {
1305 3 : if (!m_gstPlayer)
1306 : {
1307 1 : RIALTO_SERVER_LOG_ERROR("Failed to set subtitle offset - Gstreamer player has not been loaded");
1308 1 : return false;
1309 : }
1310 2 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
1311 1 : [sourceId](const auto &src) { return src.second == sourceId; });
1312 2 : if (sourceIter == m_attachedSources.end())
1313 : {
1314 1 : RIALTO_SERVER_LOG_ERROR("Failed to set subtitle offset - Source with id: %d not found", sourceId);
1315 1 : return false;
1316 : }
1317 :
1318 1 : m_gstPlayer->setSubtitleOffset(position);
1319 1 : return true;
1320 : }
1321 :
1322 2 : bool MediaPipelineServerInternal::processAudioGap(int64_t position, uint32_t duration, int64_t discontinuityGap,
1323 : bool audioAac)
1324 : {
1325 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1326 :
1327 : bool result;
1328 2 : auto task = [&]() { result = processAudioGapInternal(position, duration, discontinuityGap, audioAac); };
1329 :
1330 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1331 2 : return result;
1332 : }
1333 :
1334 2 : bool MediaPipelineServerInternal::processAudioGapInternal(int64_t position, uint32_t duration, int64_t discontinuityGap,
1335 : bool audioAac)
1336 : {
1337 2 : if (!m_gstPlayer)
1338 : {
1339 1 : RIALTO_SERVER_LOG_ERROR("Failed to process audio gap - Gstreamer player has not been loaded");
1340 1 : return false;
1341 : }
1342 1 : m_gstPlayer->processAudioGap(position, duration, discontinuityGap, audioAac);
1343 1 : return true;
1344 : }
1345 :
1346 2 : bool MediaPipelineServerInternal::setBufferingLimit(uint32_t limitBufferingMs)
1347 : {
1348 : bool result;
1349 2 : auto task = [&]() { result = setBufferingLimitInternal(limitBufferingMs); };
1350 :
1351 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1352 2 : return result;
1353 : }
1354 :
1355 2 : bool MediaPipelineServerInternal::setBufferingLimitInternal(uint32_t limitBufferingMs)
1356 : {
1357 2 : if (!m_gstPlayer)
1358 : {
1359 1 : RIALTO_SERVER_LOG_ERROR("Failed to set buffering limit - Gstreamer player has not been loaded");
1360 1 : return false;
1361 : }
1362 1 : m_gstPlayer->setBufferingLimit(limitBufferingMs);
1363 1 : return true;
1364 : }
1365 :
1366 3 : bool MediaPipelineServerInternal::getBufferingLimit(uint32_t &limitBufferingMs)
1367 : {
1368 : bool result;
1369 3 : auto task = [&]() { result = getBufferingLimitInternal(limitBufferingMs); };
1370 :
1371 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1372 3 : return result;
1373 : }
1374 :
1375 3 : bool MediaPipelineServerInternal::getBufferingLimitInternal(uint32_t &limitBufferingMs)
1376 : {
1377 3 : if (!m_gstPlayer)
1378 : {
1379 1 : RIALTO_SERVER_LOG_ERROR("Failed to get buffering limit - Gstreamer player has not been loaded");
1380 1 : return false;
1381 : }
1382 2 : return m_gstPlayer->getBufferingLimit(limitBufferingMs);
1383 : }
1384 :
1385 2 : bool MediaPipelineServerInternal::setUseBuffering(bool useBuffering)
1386 : {
1387 : bool result;
1388 2 : auto task = [&]() { result = setUseBufferingInternal(useBuffering); };
1389 :
1390 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1391 2 : return result;
1392 : }
1393 :
1394 2 : bool MediaPipelineServerInternal::setUseBufferingInternal(bool useBuffering)
1395 : {
1396 2 : if (!m_gstPlayer)
1397 : {
1398 1 : RIALTO_SERVER_LOG_ERROR("Failed to set use buffering - Gstreamer player has not been loaded");
1399 1 : return false;
1400 : }
1401 1 : m_gstPlayer->setUseBuffering(useBuffering);
1402 1 : return true;
1403 : }
1404 :
1405 3 : bool MediaPipelineServerInternal::getUseBuffering(bool &useBuffering)
1406 : {
1407 : bool result;
1408 3 : auto task = [&]() { result = getUseBufferingInternal(useBuffering); };
1409 :
1410 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1411 3 : return result;
1412 : }
1413 :
1414 3 : bool MediaPipelineServerInternal::getUseBufferingInternal(bool &useBuffering)
1415 : {
1416 3 : if (!m_gstPlayer)
1417 : {
1418 1 : RIALTO_SERVER_LOG_ERROR("Failed to get use buffering - Gstreamer player has not been loaded");
1419 1 : return false;
1420 : }
1421 2 : return m_gstPlayer->getUseBuffering(useBuffering);
1422 : }
1423 :
1424 2 : bool MediaPipelineServerInternal::switchSource(const std::unique_ptr<MediaSource> &source)
1425 : {
1426 : bool result;
1427 2 : auto task = [&]() { result = switchSourceInternal(source); };
1428 :
1429 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1430 2 : return result;
1431 : }
1432 :
1433 2 : bool MediaPipelineServerInternal::switchSourceInternal(const std::unique_ptr<MediaSource> &source)
1434 : {
1435 2 : if (!m_gstPlayer)
1436 : {
1437 1 : RIALTO_SERVER_LOG_ERROR("Failed to switch source - Gstreamer player has not been loaded");
1438 1 : return false;
1439 : }
1440 1 : m_gstPlayer->switchSource(source);
1441 1 : return true;
1442 : }
1443 :
1444 3 : AddSegmentStatus MediaPipelineServerInternal::addSegment(uint32_t needDataRequestId,
1445 : const std::unique_ptr<MediaSegment> &mediaSegment)
1446 : {
1447 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1448 :
1449 3 : AddSegmentStatus status{AddSegmentStatus::ERROR};
1450 3 : auto task = [&]() { status = addSegmentInternal(needDataRequestId, mediaSegment); };
1451 :
1452 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1453 3 : return status;
1454 : }
1455 :
1456 3 : AddSegmentStatus MediaPipelineServerInternal::addSegmentInternal(uint32_t needDataRequestId,
1457 : const std::unique_ptr<MediaSegment> &mediaSegment)
1458 : {
1459 3 : AddSegmentStatus status = m_activeRequests->addSegment(needDataRequestId, mediaSegment);
1460 3 : if (status != AddSegmentStatus::OK)
1461 : {
1462 2 : RIALTO_SERVER_LOG_ERROR("Failed to add segment for request id: %u", needDataRequestId);
1463 : }
1464 :
1465 3 : return status;
1466 : }
1467 :
1468 0 : std::weak_ptr<IMediaPipelineClient> MediaPipelineServerInternal::getClient()
1469 : {
1470 0 : return m_mediaPipelineClient;
1471 : }
1472 :
1473 10 : void MediaPipelineServerInternal::notifyPlaybackState(PlaybackState state)
1474 : {
1475 10 : RIALTO_SERVER_LOG_DEBUG("entry:");
1476 :
1477 10 : auto task = [&, state]()
1478 : {
1479 10 : m_currentPlaybackState = state;
1480 10 : if (m_mediaPipelineClient)
1481 : {
1482 10 : m_mediaPipelineClient->notifyPlaybackState(state);
1483 : }
1484 20 : };
1485 :
1486 10 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1487 : }
1488 :
1489 7 : bool MediaPipelineServerInternal::notifyNeedMediaData(MediaSourceType mediaSourceType)
1490 : {
1491 7 : RIALTO_SERVER_LOG_DEBUG("entry:");
1492 :
1493 : // the task won't execute for a disconnected client therefore
1494 : // set a default value of true which will help to stop any further
1495 : // action being taken
1496 7 : bool result{true};
1497 :
1498 7 : auto task = [&]()
1499 : {
1500 7 : result = notifyNeedMediaDataInternal(mediaSourceType);
1501 7 : if (result)
1502 : {
1503 4 : m_needDataDelayCalculator.decreaseNeedMediaDataDelay(mediaSourceType);
1504 : }
1505 14 : };
1506 :
1507 7 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1508 :
1509 7 : return result;
1510 : }
1511 :
1512 8 : bool MediaPipelineServerInternal::notifyNeedMediaDataInternal(MediaSourceType mediaSourceType)
1513 : {
1514 8 : m_needMediaDataTimers.erase(mediaSourceType);
1515 8 : m_shmBuffer->clearData(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId, mediaSourceType);
1516 8 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1517 :
1518 8 : if (m_attachedSources.cend() == kSourceIter)
1519 : {
1520 1 : RIALTO_SERVER_LOG_WARN("NeedMediaData event sending failed for %s - sourceId not found",
1521 : common::convertMediaSourceType(mediaSourceType));
1522 1 : return false;
1523 : }
1524 7 : auto it = m_isMediaTypeEosMap.find(mediaSourceType);
1525 7 : if (it != m_isMediaTypeEosMap.end() && it->second)
1526 : {
1527 2 : RIALTO_SERVER_LOG_INFO("EOS, NeedMediaData not needed for %s", common::convertMediaSourceType(mediaSourceType));
1528 2 : return false;
1529 : }
1530 5 : NeedMediaData event{m_mediaPipelineClient, *m_activeRequests, *m_shmBuffer, m_sessionId,
1531 10 : mediaSourceType, kSourceIter->second, m_currentPlaybackState};
1532 5 : if (!event.send())
1533 : {
1534 0 : RIALTO_SERVER_LOG_WARN("NeedMediaData event sending failed for %s",
1535 : common::convertMediaSourceType(mediaSourceType));
1536 0 : return false;
1537 : }
1538 :
1539 5 : RIALTO_SERVER_LOG_DEBUG("%s NeedMediaData sent.", common::convertMediaSourceType(mediaSourceType));
1540 :
1541 5 : return true;
1542 : }
1543 :
1544 3 : bool MediaPipelineServerInternal::notifyNeedMediaDataWithDelay(MediaSourceType mediaSourceType)
1545 : {
1546 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1547 :
1548 : // the task won't execute for a disconnected client therefore
1549 : // set a default value of true which will help to stop any further
1550 : // action being taken
1551 3 : bool result{true};
1552 :
1553 3 : auto task = [&]() { result = notifyNeedMediaDataWithDelayInternal(mediaSourceType); };
1554 :
1555 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1556 :
1557 3 : return result;
1558 : }
1559 :
1560 3 : bool MediaPipelineServerInternal::notifyNeedMediaDataWithDelayInternal(MediaSourceType mediaSourceType)
1561 : {
1562 3 : m_needMediaDataTimers.erase(mediaSourceType);
1563 3 : m_shmBuffer->clearData(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId, mediaSourceType);
1564 3 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1565 :
1566 3 : if (m_attachedSources.cend() == kSourceIter)
1567 : {
1568 1 : RIALTO_SERVER_LOG_WARN("NeedMediaData event sending failed for %s - sourceId not found",
1569 : common::convertMediaSourceType(mediaSourceType));
1570 1 : return false;
1571 : }
1572 2 : auto it = m_isMediaTypeEosMap.find(mediaSourceType);
1573 2 : if (it != m_isMediaTypeEosMap.end() && it->second)
1574 : {
1575 1 : RIALTO_SERVER_LOG_INFO("EOS, NeedMediaData not needed for %s", common::convertMediaSourceType(mediaSourceType));
1576 1 : return false;
1577 : }
1578 :
1579 1 : scheduleNotifyNeedMediaData(mediaSourceType);
1580 :
1581 1 : RIALTO_SERVER_LOG_DEBUG("%s NeedMediaData scheduled.", common::convertMediaSourceType(mediaSourceType));
1582 :
1583 1 : return true;
1584 : }
1585 :
1586 1 : void MediaPipelineServerInternal::notifyPosition(std::int64_t position)
1587 : {
1588 1 : RIALTO_SERVER_LOG_DEBUG("entry:");
1589 :
1590 1 : auto task = [&, position]()
1591 : {
1592 1 : if (m_mediaPipelineClient)
1593 : {
1594 1 : m_mediaPipelineClient->notifyPosition(position);
1595 : }
1596 2 : };
1597 :
1598 1 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1599 : }
1600 :
1601 118 : void MediaPipelineServerInternal::notifyNetworkState(NetworkState state)
1602 : {
1603 118 : RIALTO_SERVER_LOG_DEBUG("entry:");
1604 :
1605 118 : auto task = [&, state]()
1606 : {
1607 118 : if (m_mediaPipelineClient)
1608 : {
1609 118 : m_mediaPipelineClient->notifyNetworkState(state);
1610 : }
1611 236 : };
1612 :
1613 118 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1614 : }
1615 :
1616 1 : void MediaPipelineServerInternal::clearActiveRequestsCache()
1617 : {
1618 1 : RIALTO_SERVER_LOG_DEBUG("entry:");
1619 :
1620 1 : auto task = [&]() { m_activeRequests->clear(); };
1621 :
1622 1 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1623 : }
1624 :
1625 1 : void MediaPipelineServerInternal::invalidateActiveRequests(const MediaSourceType &type)
1626 : {
1627 1 : RIALTO_SERVER_LOG_DEBUG("entry:");
1628 :
1629 1 : auto task = [&, type]() { m_activeRequests->erase(type); };
1630 :
1631 1 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1632 : }
1633 :
1634 2 : void MediaPipelineServerInternal::notifyQos(MediaSourceType mediaSourceType, const QosInfo &qosInfo)
1635 : {
1636 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1637 :
1638 2 : auto task = [&, mediaSourceType, qosInfo]()
1639 : {
1640 2 : if (m_mediaPipelineClient)
1641 : {
1642 2 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1643 2 : if (m_attachedSources.cend() == kSourceIter)
1644 : {
1645 1 : RIALTO_SERVER_LOG_WARN("Qos notification failed - sourceId not found for %s",
1646 : common::convertMediaSourceType(mediaSourceType));
1647 1 : return;
1648 : }
1649 1 : m_mediaPipelineClient->notifyQos(kSourceIter->second, qosInfo);
1650 : }
1651 2 : };
1652 :
1653 2 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1654 : }
1655 :
1656 0 : void MediaPipelineServerInternal::notifyBufferUnderflow(MediaSourceType mediaSourceType)
1657 : {
1658 0 : RIALTO_SERVER_LOG_DEBUG("entry:");
1659 :
1660 0 : auto task = [&, mediaSourceType]()
1661 : {
1662 0 : m_needDataDelayCalculator.resetMediaDataDelay(mediaSourceType);
1663 0 : if (m_mediaPipelineClient)
1664 : {
1665 0 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1666 0 : if (m_attachedSources.cend() == kSourceIter)
1667 : {
1668 0 : RIALTO_SERVER_LOG_WARN("Buffer underflow notification failed - sourceId not found for %s",
1669 : common::convertMediaSourceType(mediaSourceType));
1670 0 : return;
1671 : }
1672 0 : m_mediaPipelineClient->notifyBufferUnderflow(kSourceIter->second);
1673 : }
1674 0 : };
1675 :
1676 0 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1677 : }
1678 :
1679 2 : void MediaPipelineServerInternal::notifyFirstFrameReceived(MediaSourceType mediaSourceType)
1680 : {
1681 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1682 :
1683 2 : auto task = [&, mediaSourceType]()
1684 : {
1685 2 : if (m_mediaPipelineClient)
1686 : {
1687 2 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1688 2 : if (m_attachedSources.cend() == kSourceIter)
1689 : {
1690 1 : RIALTO_SERVER_LOG_WARN("First frame notification failed - sourceId not found for %s",
1691 : common::convertMediaSourceType(mediaSourceType));
1692 1 : return;
1693 : }
1694 1 : m_mediaPipelineClient->notifyFirstFrameReceived(kSourceIter->second);
1695 : }
1696 2 : };
1697 :
1698 2 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1699 : }
1700 :
1701 2 : void MediaPipelineServerInternal::notifyPlaybackError(MediaSourceType mediaSourceType, PlaybackError error)
1702 : {
1703 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1704 :
1705 2 : auto task = [&, mediaSourceType, error]()
1706 : {
1707 2 : if (m_mediaPipelineClient)
1708 : {
1709 2 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1710 2 : if (m_attachedSources.cend() == kSourceIter)
1711 : {
1712 1 : RIALTO_SERVER_LOG_WARN("Playback error notification failed - sourceId not found for %s",
1713 : common::convertMediaSourceType(mediaSourceType));
1714 1 : return;
1715 : }
1716 1 : m_mediaPipelineClient->notifyPlaybackError(kSourceIter->second, error);
1717 : }
1718 2 : };
1719 :
1720 2 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1721 : }
1722 :
1723 2 : void MediaPipelineServerInternal::notifySourceFlushed(MediaSourceType mediaSourceType)
1724 : {
1725 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1726 :
1727 2 : auto task = [&, mediaSourceType]()
1728 : {
1729 2 : if (m_mediaPipelineClient)
1730 : {
1731 2 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1732 2 : if (m_attachedSources.cend() == kSourceIter)
1733 : {
1734 1 : RIALTO_SERVER_LOG_WARN("Source flushed notification failed - sourceId not found for: %s",
1735 : common::convertMediaSourceType(mediaSourceType));
1736 1 : return;
1737 : }
1738 1 : m_mediaPipelineClient->notifySourceFlushed(kSourceIter->second);
1739 1 : RIALTO_SERVER_LOG_DEBUG("%s source flushed", common::convertMediaSourceType(mediaSourceType));
1740 : }
1741 1 : m_needDataDelayCalculator.resetMediaDataDelay(mediaSourceType);
1742 2 : };
1743 :
1744 2 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1745 : }
1746 :
1747 0 : void MediaPipelineServerInternal::notifyPlaybackInfo(const PlaybackInfo &playbackInfo)
1748 : {
1749 0 : if (m_mediaPipelineClient)
1750 : {
1751 0 : m_mediaPipelineClient->notifyPlaybackInfo(playbackInfo);
1752 : }
1753 : }
1754 :
1755 8 : void MediaPipelineServerInternal::scheduleNotifyNeedMediaData(MediaSourceType mediaSourceType)
1756 : {
1757 8 : RIALTO_SERVER_LOG_DEBUG("entry:");
1758 8 : auto timer = m_needMediaDataTimers.find(mediaSourceType);
1759 8 : if (m_needMediaDataTimers.end() != timer && timer->second && timer->second->isActive())
1760 : {
1761 1 : RIALTO_SERVER_LOG_DEBUG("Skip scheduling need media data for %s - it is already scheduled",
1762 : common::convertMediaSourceType(mediaSourceType));
1763 1 : return;
1764 : }
1765 :
1766 7 : m_needMediaDataTimers[mediaSourceType] =
1767 7 : m_timerFactory
1768 21 : ->createTimer(getNeedMediaDataTimeout(mediaSourceType),
1769 14 : [this, mediaSourceType]()
1770 : {
1771 1 : m_mainThread
1772 2 : ->enqueueTask(m_mainThreadClientId,
1773 1 : [this, mediaSourceType]()
1774 : {
1775 1 : m_needMediaDataTimers.erase(mediaSourceType);
1776 1 : if (!notifyNeedMediaDataInternal(mediaSourceType))
1777 : {
1778 0 : RIALTO_SERVER_LOG_WARN("Scheduled Need media data sending "
1779 : "failed for: %s. Scheduling again...",
1780 : common::convertMediaSourceType(
1781 : mediaSourceType));
1782 0 : scheduleNotifyNeedMediaData(mediaSourceType);
1783 : }
1784 : else
1785 : {
1786 1 : m_needDataDelayCalculator.increaseNeedMediaDataDelay(
1787 : mediaSourceType);
1788 : }
1789 1 : });
1790 8 : });
1791 : }
1792 :
1793 7 : std::chrono::milliseconds MediaPipelineServerInternal::getNeedMediaDataTimeout(MediaSourceType mediaSourceType)
1794 : {
1795 7 : constexpr std::chrono::milliseconds kNeedMediaDataResendTimeMsForLowLatency{5};
1796 7 : if ((mediaSourceType == MediaSourceType::VIDEO && m_IsLowLatencyVideoPlayer) ||
1797 1 : (mediaSourceType == MediaSourceType::AUDIO && m_IsLowLatencyAudioPlayer))
1798 : {
1799 2 : return kNeedMediaDataResendTimeMsForLowLatency;
1800 : }
1801 5 : return m_needDataDelayCalculator.getNeedMediaDataDelay(mediaSourceType);
1802 : }
1803 : }; // namespace firebolt::rialto::server
|