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 : m_IsLowLatencyVideoPlayer = immediateOutput;
559 4 : return m_gstPlayer->setImmediateOutput(sourceIter->first, immediateOutput);
560 : }
561 :
562 5 : bool MediaPipelineServerInternal::setReportDecodeErrors(int32_t sourceId, bool reportDecodeErrors)
563 : {
564 5 : RIALTO_SERVER_LOG_DEBUG("entry:");
565 :
566 : bool result;
567 5 : auto task = [&]() { result = setReportDecodeErrorsInternal(sourceId, reportDecodeErrors); };
568 :
569 5 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
570 5 : return result;
571 : }
572 :
573 5 : bool MediaPipelineServerInternal::setReportDecodeErrorsInternal(int32_t sourceId, bool reportDecodeErrors)
574 : {
575 5 : if (!m_gstPlayer)
576 : {
577 1 : RIALTO_SERVER_LOG_ERROR("Failed - Gstreamer player has not been loaded");
578 1 : return false;
579 : }
580 4 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
581 3 : [sourceId](const auto &src) { return src.second == sourceId; });
582 4 : if (sourceIter == m_attachedSources.end())
583 : {
584 1 : RIALTO_SERVER_LOG_ERROR("Failed - Source not found");
585 1 : return false;
586 : }
587 :
588 3 : return m_gstPlayer->setReportDecodeErrors(sourceIter->first, reportDecodeErrors);
589 : }
590 :
591 5 : bool MediaPipelineServerInternal::getQueuedFrames(int32_t sourceId, uint32_t &queuedFrames)
592 : {
593 5 : RIALTO_SERVER_LOG_DEBUG("entry:");
594 :
595 : bool result;
596 5 : auto task = [&]() { result = getQueuedFramesInternal(sourceId, queuedFrames); };
597 :
598 5 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
599 5 : return result;
600 : }
601 :
602 5 : bool MediaPipelineServerInternal::getQueuedFramesInternal(int32_t sourceId, uint32_t &queuedFrames)
603 : {
604 5 : if (!m_gstPlayer)
605 : {
606 1 : RIALTO_SERVER_LOG_ERROR("Failed - Gstreamer player has not been loaded");
607 1 : return false;
608 : }
609 4 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
610 3 : [sourceId](const auto &src) { return src.second == sourceId; });
611 4 : if (sourceIter == m_attachedSources.end())
612 : {
613 1 : RIALTO_SERVER_LOG_ERROR("Failed - Source not found");
614 1 : return false;
615 : }
616 3 : return m_gstPlayer->getQueuedFrames(queuedFrames);
617 : }
618 :
619 5 : bool MediaPipelineServerInternal::getImmediateOutput(int32_t sourceId, bool &immediateOutput)
620 : {
621 5 : RIALTO_SERVER_LOG_DEBUG("entry:");
622 :
623 : bool result;
624 5 : auto task = [&]() { result = getImmediateOutputInternal(sourceId, immediateOutput); };
625 :
626 5 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
627 5 : return result;
628 : }
629 :
630 5 : bool MediaPipelineServerInternal::getImmediateOutputInternal(int32_t sourceId, bool &immediateOutput)
631 : {
632 5 : if (!m_gstPlayer)
633 : {
634 1 : RIALTO_SERVER_LOG_ERROR("Failed - Gstreamer player has not been loaded");
635 1 : return false;
636 : }
637 4 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
638 3 : [sourceId](const auto &src) { return src.second == sourceId; });
639 4 : if (sourceIter == m_attachedSources.end())
640 : {
641 1 : RIALTO_SERVER_LOG_ERROR("Failed - Source not found");
642 1 : return false;
643 : }
644 3 : return m_gstPlayer->getImmediateOutput(sourceIter->first, immediateOutput);
645 : }
646 :
647 2 : bool MediaPipelineServerInternal::setVideoWindow(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
648 : {
649 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
650 :
651 : bool result;
652 2 : auto task = [&]() { result = setVideoWindowInternal(x, y, width, height); };
653 :
654 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
655 2 : return result;
656 : }
657 :
658 2 : bool MediaPipelineServerInternal::setVideoWindowInternal(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
659 : {
660 2 : if (!m_gstPlayer)
661 : {
662 1 : RIALTO_SERVER_LOG_ERROR("Failed to set video window - Gstreamer player has not been loaded");
663 1 : return false;
664 : }
665 :
666 1 : m_gstPlayer->setVideoGeometry(x, y, width, height);
667 1 : return true;
668 : }
669 :
670 13 : bool MediaPipelineServerInternal::haveData(MediaSourceStatus status, uint32_t needDataRequestId)
671 : {
672 13 : RIALTO_SERVER_LOG_DEBUG("entry:");
673 :
674 : bool result;
675 13 : auto task = [&]() { result = haveDataInternal(status, needDataRequestId); };
676 :
677 13 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
678 13 : return result;
679 : }
680 :
681 13 : bool MediaPipelineServerInternal::haveDataInternal(MediaSourceStatus status, uint32_t needDataRequestId)
682 : {
683 13 : if (!m_gstPlayer)
684 : {
685 1 : RIALTO_SERVER_LOG_ERROR("HaveData failed - Gstreamer player has not been loaded");
686 1 : return false;
687 : }
688 :
689 12 : MediaSourceType mediaSourceType = m_activeRequests->getType(needDataRequestId);
690 12 : if (MediaSourceType::UNKNOWN == mediaSourceType)
691 : {
692 1 : RIALTO_SERVER_LOG_WARN("NeedData RequestID is not valid: %u", needDataRequestId);
693 1 : return true;
694 : }
695 :
696 11 : unsigned int &counter = m_noAvailableSamplesCounter[mediaSourceType];
697 11 : if (status != MediaSourceStatus::OK && status != MediaSourceStatus::EOS)
698 : {
699 : // Incrementing the counter allows us to track the occurrences where the status is other than OK or EOS.
700 :
701 3 : ++counter;
702 3 : if (status == MediaSourceStatus::NO_AVAILABLE_SAMPLES)
703 : {
704 2 : RIALTO_SERVER_LOG_DEBUG("Data request for needDataRequestId: %u. NO_AVAILABLE_SAMPLES received: %u "
705 : "consecutively for mediaSourceType: %s",
706 : needDataRequestId, counter, common::convertMediaSourceType(mediaSourceType));
707 : }
708 : else
709 : {
710 1 : RIALTO_SERVER_LOG_WARN("%s Data request for needDataRequestId: %u received with wrong status: %s",
711 : common::convertMediaSourceType(mediaSourceType), needDataRequestId, toString(status));
712 1 : counter = 0;
713 : }
714 :
715 3 : m_activeRequests->erase(needDataRequestId);
716 3 : scheduleNotifyNeedMediaData(mediaSourceType);
717 3 : return true;
718 : }
719 : else
720 : {
721 8 : RIALTO_SERVER_LOG_DEBUG("%s Data request for needDataRequestId: %u received with correct status",
722 : common::convertMediaSourceType(mediaSourceType), needDataRequestId);
723 8 : counter = 0;
724 : }
725 :
726 : try
727 : {
728 8 : const IMediaPipeline::MediaSegmentVector &kSegments = m_activeRequests->getSegments(needDataRequestId);
729 7 : m_gstPlayer->attachSamples(kSegments);
730 : }
731 1 : catch (const std::runtime_error &e)
732 : {
733 1 : RIALTO_SERVER_LOG_ERROR("Failed to get segments %s", e.what());
734 1 : m_activeRequests->erase(needDataRequestId);
735 1 : return false;
736 : }
737 :
738 7 : m_activeRequests->erase(needDataRequestId);
739 7 : if (status == MediaSourceStatus::EOS)
740 : {
741 6 : m_gstPlayer->setEos(mediaSourceType);
742 6 : m_isMediaTypeEosMap[mediaSourceType] = true;
743 : }
744 :
745 7 : return true;
746 : }
747 :
748 15 : bool MediaPipelineServerInternal::haveData(MediaSourceStatus status, uint32_t numFrames, uint32_t needDataRequestId)
749 : {
750 15 : RIALTO_SERVER_LOG_DEBUG("entry:");
751 :
752 : bool result;
753 15 : auto task = [&]() { result = haveDataInternal(status, numFrames, needDataRequestId); };
754 :
755 15 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
756 15 : return result;
757 : }
758 :
759 15 : bool MediaPipelineServerInternal::haveDataInternal(MediaSourceStatus status, uint32_t numFrames,
760 : uint32_t needDataRequestId)
761 : {
762 15 : if (!m_gstPlayer)
763 : {
764 1 : RIALTO_SERVER_LOG_ERROR("HaveData failed - Gstreamer player has not been loaded");
765 1 : return false;
766 : }
767 14 : MediaSourceType mediaSourceType = m_activeRequests->getType(needDataRequestId);
768 14 : if (MediaSourceType::UNKNOWN == mediaSourceType)
769 : {
770 1 : RIALTO_SERVER_LOG_WARN("NeedData RequestID is not valid: %u", needDataRequestId);
771 1 : return true;
772 : }
773 13 : const std::uint32_t kMaxNumFrames = m_activeRequests->getMaxFrames(needDataRequestId);
774 13 : m_activeRequests->erase(needDataRequestId);
775 :
776 13 : unsigned int &counter = m_noAvailableSamplesCounter[mediaSourceType];
777 13 : if (status != MediaSourceStatus::OK && status != MediaSourceStatus::EOS &&
778 : status != MediaSourceStatus::NO_SPACE_FOR_SAMPLES)
779 : {
780 : // Incrementing the counter allows us to track the occurrences where the status is other than OK or EOS.
781 :
782 4 : ++counter;
783 4 : if (status == MediaSourceStatus::NO_AVAILABLE_SAMPLES)
784 : {
785 0 : RIALTO_SERVER_LOG_DEBUG("Data request for needDataRequestId: %u. NO_AVAILABLE_SAMPLES received: %u "
786 : "consecutively for mediaSourceType: %s",
787 : needDataRequestId, counter, common::convertMediaSourceType(mediaSourceType));
788 : }
789 : else
790 : {
791 4 : RIALTO_SERVER_LOG_WARN("%s Data request for needDataRequestId: %u received with wrong status",
792 : common::convertMediaSourceType(mediaSourceType), needDataRequestId);
793 4 : counter = 0;
794 : }
795 4 : scheduleNotifyNeedMediaData(mediaSourceType);
796 4 : return true;
797 : }
798 : else
799 : {
800 9 : RIALTO_SERVER_LOG_DEBUG("%s Data request for needDataRequestId: %u received with correct status",
801 : common::convertMediaSourceType(mediaSourceType), needDataRequestId);
802 9 : counter = 0;
803 : }
804 :
805 9 : uint8_t *buffer = m_shmBuffer->getBuffer();
806 9 : if (!buffer)
807 : {
808 1 : RIALTO_SERVER_LOG_ERROR("No buffer available");
809 1 : notifyPlaybackState(PlaybackState::FAILURE);
810 1 : return false;
811 : }
812 :
813 8 : std::uint32_t regionOffset = 0;
814 : try
815 : {
816 : regionOffset =
817 8 : m_shmBuffer->getDataOffset(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId, mediaSourceType);
818 : }
819 1 : catch (const std::runtime_error &e)
820 : {
821 1 : RIALTO_SERVER_LOG_ERROR("Failed to get region's buffer offset, reason: %s", e.what());
822 1 : notifyPlaybackState(PlaybackState::FAILURE);
823 1 : return false;
824 : }
825 :
826 7 : if (0 != numFrames)
827 : {
828 6 : const bool kIsBufferFull = kMaxNumFrames == numFrames || status == MediaSourceStatus::NO_SPACE_FOR_SAMPLES ||
829 : status == MediaSourceStatus::EOS;
830 : std::shared_ptr<IDataReader> dataReader =
831 6 : m_dataReaderFactory->createDataReader(mediaSourceType, buffer, regionOffset, numFrames, kIsBufferFull);
832 6 : if (!dataReader)
833 : {
834 1 : RIALTO_SERVER_LOG_ERROR("Metadata version not supported for %s request id: %u",
835 : common::convertMediaSourceType(mediaSourceType), needDataRequestId);
836 1 : notifyPlaybackState(PlaybackState::FAILURE);
837 1 : return false;
838 : }
839 5 : m_gstPlayer->attachSamples(dataReader);
840 6 : }
841 6 : if (status == MediaSourceStatus::EOS)
842 : {
843 2 : m_gstPlayer->setEos(mediaSourceType);
844 2 : m_isMediaTypeEosMap[mediaSourceType] = true;
845 : }
846 :
847 6 : return true;
848 : }
849 :
850 2 : void MediaPipelineServerInternal::ping(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler)
851 : {
852 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
853 :
854 2 : auto task = [&]() { pingInternal(std::move(heartbeatHandler)); };
855 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
856 : }
857 :
858 2 : void MediaPipelineServerInternal::pingInternal(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler)
859 : {
860 2 : if (!m_gstPlayer)
861 : {
862 : // No need to check GstPlayer worker thread, we reached this function, so main thread is working fine.
863 1 : heartbeatHandler.reset();
864 1 : return;
865 : }
866 : // Check GstPlayer worker thread
867 1 : m_gstPlayer->ping(std::move(heartbeatHandler));
868 : }
869 :
870 2 : bool MediaPipelineServerInternal::renderFrame()
871 : {
872 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
873 :
874 : bool result;
875 2 : auto task = [&]() { result = renderFrameInternal(); };
876 :
877 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
878 2 : return result;
879 : }
880 :
881 2 : bool MediaPipelineServerInternal::renderFrameInternal()
882 : {
883 2 : if (!m_gstPlayer)
884 : {
885 1 : RIALTO_SERVER_LOG_ERROR("renderFrame failed - Gstreamer player has not been loaded");
886 1 : return false;
887 : }
888 :
889 1 : m_gstPlayer->renderFrame();
890 1 : return true;
891 : }
892 :
893 2 : bool MediaPipelineServerInternal::setVolume(double targetVolume, uint32_t volumeDuration, EaseType easeType)
894 : {
895 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
896 :
897 : bool result;
898 2 : auto task = [&]() { result = setVolumeInternal(targetVolume, volumeDuration, easeType); };
899 :
900 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
901 2 : return result;
902 : }
903 :
904 2 : bool MediaPipelineServerInternal::setVolumeInternal(double targetVolume, uint32_t volumeDuration, EaseType easeType)
905 : {
906 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
907 :
908 2 : if (!m_gstPlayer)
909 : {
910 1 : RIALTO_SERVER_LOG_ERROR("Failed to set volume - Gstreamer player has not been loaded");
911 1 : return false;
912 : }
913 1 : m_gstPlayer->setVolume(targetVolume, volumeDuration, easeType);
914 1 : return true;
915 : }
916 :
917 3 : bool MediaPipelineServerInternal::getVolume(double ¤tVolume)
918 : {
919 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
920 :
921 : bool result;
922 3 : auto task = [&]() { result = getVolumeInternal(currentVolume); };
923 :
924 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
925 3 : return result;
926 : }
927 :
928 3 : bool MediaPipelineServerInternal::getVolumeInternal(double ¤tVolume)
929 : {
930 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
931 :
932 3 : if (!m_gstPlayer)
933 : {
934 1 : RIALTO_SERVER_LOG_ERROR("Failed to get volume - Gstreamer player has not been loaded");
935 1 : return false;
936 : }
937 2 : return m_gstPlayer->getVolume(currentVolume);
938 : }
939 :
940 3 : bool MediaPipelineServerInternal::setMute(std::int32_t sourceId, bool mute)
941 : {
942 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
943 :
944 : bool result;
945 3 : auto task = [&]() { result = setMuteInternal(sourceId, mute); };
946 :
947 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
948 3 : return result;
949 : }
950 :
951 3 : bool MediaPipelineServerInternal::setMuteInternal(std::int32_t sourceId, bool mute)
952 : {
953 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
954 :
955 3 : if (!m_gstPlayer)
956 : {
957 1 : RIALTO_SERVER_LOG_ERROR("Failed to set mute - Gstreamer player has not been loaded");
958 1 : return false;
959 : }
960 :
961 2 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
962 1 : [sourceId](const auto &src) { return src.second == sourceId; });
963 2 : if (sourceIter == m_attachedSources.end())
964 : {
965 1 : RIALTO_SERVER_LOG_ERROR("Failed to set mute - Source with id: %d not found", sourceId);
966 1 : return false;
967 : }
968 :
969 1 : m_gstPlayer->setMute(sourceIter->first, mute);
970 :
971 1 : return true;
972 : }
973 :
974 4 : bool MediaPipelineServerInternal::getMute(std::int32_t sourceId, bool &mute)
975 : {
976 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
977 :
978 : bool result;
979 4 : auto task = [&]() { result = getMuteInternal(sourceId, mute); };
980 :
981 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
982 4 : return result;
983 : }
984 :
985 4 : bool MediaPipelineServerInternal::getMuteInternal(std::int32_t sourceId, bool &mute)
986 : {
987 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
988 :
989 4 : if (!m_gstPlayer)
990 : {
991 1 : RIALTO_SERVER_LOG_ERROR("Failed to get mute - Gstreamer player has not been loaded");
992 1 : return false;
993 : }
994 :
995 3 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
996 2 : [sourceId](const auto &src) { return src.second == sourceId; });
997 3 : if (sourceIter == m_attachedSources.end())
998 : {
999 1 : RIALTO_SERVER_LOG_ERROR("Failed to get mute - Source with id: %d not found", sourceId);
1000 1 : return false;
1001 : }
1002 :
1003 2 : return m_gstPlayer->getMute(sourceIter->first, mute);
1004 : }
1005 :
1006 2 : bool MediaPipelineServerInternal::setTextTrackIdentifier(const std::string &textTrackIdentifier)
1007 : {
1008 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1009 :
1010 : bool result;
1011 2 : auto task = [&]() { result = setTextTrackIdentifierInternal(textTrackIdentifier); };
1012 :
1013 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1014 2 : return result;
1015 : }
1016 :
1017 2 : bool MediaPipelineServerInternal::setTextTrackIdentifierInternal(const std::string &textTrackIdentifier)
1018 : {
1019 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1020 :
1021 2 : if (!m_gstPlayer)
1022 : {
1023 1 : RIALTO_SERVER_LOG_ERROR("Failed to set text track identifier - Gstreamer player has not been loaded");
1024 1 : return false;
1025 : }
1026 :
1027 1 : m_gstPlayer->setTextTrackIdentifier(textTrackIdentifier);
1028 :
1029 1 : return true;
1030 : }
1031 :
1032 3 : bool MediaPipelineServerInternal::getTextTrackIdentifier(std::string &textTrackIdentifier)
1033 : {
1034 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1035 :
1036 : bool result;
1037 3 : auto task = [&]() { result = getTextTrackIdentifierInternal(textTrackIdentifier); };
1038 :
1039 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1040 3 : return result;
1041 : }
1042 :
1043 3 : bool MediaPipelineServerInternal::getTextTrackIdentifierInternal(std::string &textTrackIdentifier)
1044 : {
1045 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1046 :
1047 3 : if (!m_gstPlayer)
1048 : {
1049 1 : RIALTO_SERVER_LOG_ERROR("Failed to get mute - Gstreamer player has not been loaded");
1050 1 : return false;
1051 : }
1052 :
1053 2 : return m_gstPlayer->getTextTrackIdentifier(textTrackIdentifier);
1054 : }
1055 :
1056 4 : bool MediaPipelineServerInternal::flush(int32_t sourceId, bool resetTime, bool &async)
1057 : {
1058 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
1059 :
1060 : bool result;
1061 4 : auto task = [&]() { result = flushInternal(sourceId, resetTime, async); };
1062 :
1063 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1064 4 : return result;
1065 : }
1066 :
1067 4 : bool MediaPipelineServerInternal::setLowLatency(bool lowLatency)
1068 : {
1069 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
1070 :
1071 : bool result;
1072 4 : auto task = [&]() { result = setLowLatencyInternal(lowLatency); };
1073 :
1074 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1075 4 : return result;
1076 : }
1077 :
1078 4 : bool MediaPipelineServerInternal::setLowLatencyInternal(bool lowLatency)
1079 : {
1080 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
1081 :
1082 4 : if (!m_gstPlayer)
1083 : {
1084 1 : RIALTO_SERVER_LOG_ERROR("Failed to set low latency - Gstreamer player has not been loaded");
1085 1 : return false;
1086 : }
1087 3 : m_IsLowLatencyAudioPlayer = lowLatency;
1088 :
1089 3 : return m_gstPlayer->setLowLatency(lowLatency);
1090 : }
1091 :
1092 3 : bool MediaPipelineServerInternal::setSync(bool sync)
1093 : {
1094 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1095 :
1096 : bool result;
1097 3 : auto task = [&]() { result = setSyncInternal(sync); };
1098 :
1099 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1100 3 : return result;
1101 : }
1102 :
1103 3 : bool MediaPipelineServerInternal::setSyncInternal(bool sync)
1104 : {
1105 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1106 :
1107 3 : if (!m_gstPlayer)
1108 : {
1109 1 : RIALTO_SERVER_LOG_ERROR("Failed to set sync - Gstreamer player has not been loaded");
1110 1 : return false;
1111 : }
1112 2 : return m_gstPlayer->setSync(sync);
1113 : }
1114 :
1115 3 : bool MediaPipelineServerInternal::getSync(bool &sync)
1116 : {
1117 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1118 :
1119 : bool result;
1120 3 : auto task = [&]() { result = getSyncInternal(sync); };
1121 :
1122 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1123 3 : return result;
1124 : }
1125 :
1126 3 : bool MediaPipelineServerInternal::getSyncInternal(bool &sync)
1127 : {
1128 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1129 :
1130 3 : if (!m_gstPlayer)
1131 : {
1132 1 : RIALTO_SERVER_LOG_ERROR("Failed to get sync - Gstreamer player has not been loaded");
1133 1 : return false;
1134 : }
1135 2 : return m_gstPlayer->getSync(sync);
1136 : }
1137 :
1138 3 : bool MediaPipelineServerInternal::setSyncOff(bool syncOff)
1139 : {
1140 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1141 :
1142 : bool result;
1143 3 : auto task = [&]() { result = setSyncOffInternal(syncOff); };
1144 :
1145 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1146 3 : return result;
1147 : }
1148 :
1149 3 : bool MediaPipelineServerInternal::setSyncOffInternal(bool syncOff)
1150 : {
1151 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1152 :
1153 3 : if (!m_gstPlayer)
1154 : {
1155 1 : RIALTO_SERVER_LOG_ERROR("Failed to set sync off - Gstreamer player has not been loaded");
1156 1 : return false;
1157 : }
1158 2 : return m_gstPlayer->setSyncOff(syncOff);
1159 : }
1160 :
1161 4 : bool MediaPipelineServerInternal::setStreamSyncMode(int32_t sourceId, int32_t streamSyncMode)
1162 : {
1163 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
1164 :
1165 : bool result;
1166 4 : auto task = [&]() { result = setStreamSyncModeInternal(sourceId, streamSyncMode); };
1167 :
1168 4 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1169 4 : return result;
1170 : }
1171 :
1172 4 : bool MediaPipelineServerInternal::setStreamSyncModeInternal(int32_t sourceId, int32_t streamSyncMode)
1173 : {
1174 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
1175 :
1176 4 : if (!m_gstPlayer)
1177 : {
1178 1 : RIALTO_SERVER_LOG_ERROR("Failed to set stream sync mode - Gstreamer player has not been loaded");
1179 1 : return false;
1180 : }
1181 :
1182 3 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
1183 2 : [sourceId](const auto &src) { return src.second == sourceId; });
1184 3 : if (sourceIter == m_attachedSources.end())
1185 : {
1186 1 : RIALTO_SERVER_LOG_ERROR("Failed to set stream sync mode - Source with id: %d not found", sourceId);
1187 1 : return false;
1188 : }
1189 :
1190 2 : return m_gstPlayer->setStreamSyncMode(sourceIter->first, streamSyncMode);
1191 : }
1192 :
1193 3 : bool MediaPipelineServerInternal::getStreamSyncMode(int32_t &streamSyncMode)
1194 : {
1195 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1196 :
1197 : bool result;
1198 3 : auto task = [&]() { result = getStreamSyncModeInternal(streamSyncMode); };
1199 :
1200 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1201 3 : return result;
1202 : }
1203 :
1204 3 : bool MediaPipelineServerInternal::getStreamSyncModeInternal(int32_t &streamSyncMode)
1205 : {
1206 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1207 :
1208 3 : if (!m_gstPlayer)
1209 : {
1210 1 : RIALTO_SERVER_LOG_ERROR("Failed to get stream sync mode - Gstreamer player has not been loaded");
1211 1 : return false;
1212 : }
1213 2 : return m_gstPlayer->getStreamSyncMode(streamSyncMode);
1214 : }
1215 :
1216 4 : bool MediaPipelineServerInternal::flushInternal(int32_t sourceId, bool resetTime, bool &async)
1217 : {
1218 4 : if (!m_gstPlayer)
1219 : {
1220 1 : RIALTO_SERVER_LOG_ERROR("Failed to flush - Gstreamer player has not been loaded");
1221 1 : return false;
1222 : }
1223 3 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
1224 2 : [sourceId](const auto &src) { return src.second == sourceId; });
1225 3 : if (sourceIter == m_attachedSources.end())
1226 : {
1227 1 : RIALTO_SERVER_LOG_ERROR("Failed to flush - Source with id: %d not found", sourceId);
1228 1 : return false;
1229 : }
1230 :
1231 2 : m_gstPlayer->flush(sourceIter->first, resetTime, async);
1232 :
1233 2 : m_needMediaDataTimers.erase(sourceIter->first);
1234 :
1235 : // Reset Eos on flush
1236 2 : auto it = m_isMediaTypeEosMap.find(sourceIter->first);
1237 2 : if (it != m_isMediaTypeEosMap.end() && it->second)
1238 : {
1239 1 : it->second = false;
1240 : }
1241 :
1242 2 : return true;
1243 : }
1244 :
1245 3 : bool MediaPipelineServerInternal::setSourcePosition(int32_t sourceId, int64_t position, bool resetTime,
1246 : double appliedRate, uint64_t stopPosition)
1247 : {
1248 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1249 :
1250 : bool result;
1251 3 : auto task = [&]() { result = setSourcePositionInternal(sourceId, position, resetTime, appliedRate, stopPosition); };
1252 :
1253 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1254 3 : return result;
1255 : }
1256 :
1257 3 : bool MediaPipelineServerInternal::setSourcePositionInternal(int32_t sourceId, int64_t position, bool resetTime,
1258 : double appliedRate, uint64_t stopPosition)
1259 : {
1260 3 : if (!m_gstPlayer)
1261 : {
1262 1 : RIALTO_SERVER_LOG_ERROR("Failed to set source position - Gstreamer player has not been loaded");
1263 1 : return false;
1264 : }
1265 2 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
1266 1 : [sourceId](const auto &src) { return src.second == sourceId; });
1267 2 : if (sourceIter == m_attachedSources.end())
1268 : {
1269 1 : RIALTO_SERVER_LOG_ERROR("Failed to set source position - Source with id: %d not found", sourceId);
1270 1 : return false;
1271 : }
1272 :
1273 1 : m_gstPlayer->setSourcePosition(sourceIter->first, position, resetTime, appliedRate, stopPosition);
1274 :
1275 : // Reset Eos on seek
1276 1 : auto it = m_isMediaTypeEosMap.find(sourceIter->first);
1277 1 : if (it != m_isMediaTypeEosMap.end() && it->second)
1278 : {
1279 0 : it->second = false;
1280 : }
1281 :
1282 1 : return true;
1283 : }
1284 :
1285 3 : bool MediaPipelineServerInternal::setSubtitleOffset(int32_t sourceId, int64_t position)
1286 : {
1287 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1288 :
1289 : bool result;
1290 3 : auto task = [&]() { result = setSubtitleOffsetInternal(sourceId, position); };
1291 :
1292 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1293 3 : return result;
1294 : }
1295 :
1296 3 : bool MediaPipelineServerInternal::setSubtitleOffsetInternal(int32_t sourceId, int64_t position)
1297 : {
1298 3 : if (!m_gstPlayer)
1299 : {
1300 1 : RIALTO_SERVER_LOG_ERROR("Failed to set subtitle offset - Gstreamer player has not been loaded");
1301 1 : return false;
1302 : }
1303 2 : auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
1304 1 : [sourceId](const auto &src) { return src.second == sourceId; });
1305 2 : if (sourceIter == m_attachedSources.end())
1306 : {
1307 1 : RIALTO_SERVER_LOG_ERROR("Failed to set subtitle offset - Source with id: %d not found", sourceId);
1308 1 : return false;
1309 : }
1310 :
1311 1 : m_gstPlayer->setSubtitleOffset(position);
1312 1 : return true;
1313 : }
1314 :
1315 2 : bool MediaPipelineServerInternal::processAudioGap(int64_t position, uint32_t duration, int64_t discontinuityGap,
1316 : bool audioAac)
1317 : {
1318 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1319 :
1320 : bool result;
1321 2 : auto task = [&]() { result = processAudioGapInternal(position, duration, discontinuityGap, audioAac); };
1322 :
1323 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1324 2 : return result;
1325 : }
1326 :
1327 2 : bool MediaPipelineServerInternal::processAudioGapInternal(int64_t position, uint32_t duration, int64_t discontinuityGap,
1328 : bool audioAac)
1329 : {
1330 2 : if (!m_gstPlayer)
1331 : {
1332 1 : RIALTO_SERVER_LOG_ERROR("Failed to process audio gap - Gstreamer player has not been loaded");
1333 1 : return false;
1334 : }
1335 1 : m_gstPlayer->processAudioGap(position, duration, discontinuityGap, audioAac);
1336 1 : return true;
1337 : }
1338 :
1339 2 : bool MediaPipelineServerInternal::setBufferingLimit(uint32_t limitBufferingMs)
1340 : {
1341 : bool result;
1342 2 : auto task = [&]() { result = setBufferingLimitInternal(limitBufferingMs); };
1343 :
1344 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1345 2 : return result;
1346 : }
1347 :
1348 2 : bool MediaPipelineServerInternal::setBufferingLimitInternal(uint32_t limitBufferingMs)
1349 : {
1350 2 : if (!m_gstPlayer)
1351 : {
1352 1 : RIALTO_SERVER_LOG_ERROR("Failed to set buffering limit - Gstreamer player has not been loaded");
1353 1 : return false;
1354 : }
1355 1 : m_gstPlayer->setBufferingLimit(limitBufferingMs);
1356 1 : return true;
1357 : }
1358 :
1359 3 : bool MediaPipelineServerInternal::getBufferingLimit(uint32_t &limitBufferingMs)
1360 : {
1361 : bool result;
1362 3 : auto task = [&]() { result = getBufferingLimitInternal(limitBufferingMs); };
1363 :
1364 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1365 3 : return result;
1366 : }
1367 :
1368 3 : bool MediaPipelineServerInternal::getBufferingLimitInternal(uint32_t &limitBufferingMs)
1369 : {
1370 3 : if (!m_gstPlayer)
1371 : {
1372 1 : RIALTO_SERVER_LOG_ERROR("Failed to get buffering limit - Gstreamer player has not been loaded");
1373 1 : return false;
1374 : }
1375 2 : return m_gstPlayer->getBufferingLimit(limitBufferingMs);
1376 : }
1377 :
1378 2 : bool MediaPipelineServerInternal::setUseBuffering(bool useBuffering)
1379 : {
1380 : bool result;
1381 2 : auto task = [&]() { result = setUseBufferingInternal(useBuffering); };
1382 :
1383 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1384 2 : return result;
1385 : }
1386 :
1387 2 : bool MediaPipelineServerInternal::setUseBufferingInternal(bool useBuffering)
1388 : {
1389 2 : if (!m_gstPlayer)
1390 : {
1391 1 : RIALTO_SERVER_LOG_ERROR("Failed to set use buffering - Gstreamer player has not been loaded");
1392 1 : return false;
1393 : }
1394 1 : m_gstPlayer->setUseBuffering(useBuffering);
1395 1 : return true;
1396 : }
1397 :
1398 3 : bool MediaPipelineServerInternal::getUseBuffering(bool &useBuffering)
1399 : {
1400 : bool result;
1401 3 : auto task = [&]() { result = getUseBufferingInternal(useBuffering); };
1402 :
1403 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1404 3 : return result;
1405 : }
1406 :
1407 3 : bool MediaPipelineServerInternal::getUseBufferingInternal(bool &useBuffering)
1408 : {
1409 3 : if (!m_gstPlayer)
1410 : {
1411 1 : RIALTO_SERVER_LOG_ERROR("Failed to get use buffering - Gstreamer player has not been loaded");
1412 1 : return false;
1413 : }
1414 2 : return m_gstPlayer->getUseBuffering(useBuffering);
1415 : }
1416 :
1417 2 : bool MediaPipelineServerInternal::switchSource(const std::unique_ptr<MediaSource> &source)
1418 : {
1419 : bool result;
1420 2 : auto task = [&]() { result = switchSourceInternal(source); };
1421 :
1422 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1423 2 : return result;
1424 : }
1425 :
1426 2 : bool MediaPipelineServerInternal::switchSourceInternal(const std::unique_ptr<MediaSource> &source)
1427 : {
1428 2 : if (!m_gstPlayer)
1429 : {
1430 1 : RIALTO_SERVER_LOG_ERROR("Failed to switch source - Gstreamer player has not been loaded");
1431 1 : return false;
1432 : }
1433 1 : m_gstPlayer->switchSource(source);
1434 1 : return true;
1435 : }
1436 :
1437 3 : AddSegmentStatus MediaPipelineServerInternal::addSegment(uint32_t needDataRequestId,
1438 : const std::unique_ptr<MediaSegment> &mediaSegment)
1439 : {
1440 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1441 :
1442 3 : AddSegmentStatus status{AddSegmentStatus::ERROR};
1443 3 : auto task = [&]() { status = addSegmentInternal(needDataRequestId, mediaSegment); };
1444 :
1445 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1446 3 : return status;
1447 : }
1448 :
1449 3 : AddSegmentStatus MediaPipelineServerInternal::addSegmentInternal(uint32_t needDataRequestId,
1450 : const std::unique_ptr<MediaSegment> &mediaSegment)
1451 : {
1452 3 : AddSegmentStatus status = m_activeRequests->addSegment(needDataRequestId, mediaSegment);
1453 3 : if (status != AddSegmentStatus::OK)
1454 : {
1455 2 : RIALTO_SERVER_LOG_ERROR("Failed to add segment for request id: %u", needDataRequestId);
1456 : }
1457 :
1458 3 : return status;
1459 : }
1460 :
1461 0 : std::weak_ptr<IMediaPipelineClient> MediaPipelineServerInternal::getClient()
1462 : {
1463 0 : return m_mediaPipelineClient;
1464 : }
1465 :
1466 10 : void MediaPipelineServerInternal::notifyPlaybackState(PlaybackState state)
1467 : {
1468 10 : RIALTO_SERVER_LOG_DEBUG("entry:");
1469 :
1470 10 : auto task = [&, state]()
1471 : {
1472 10 : m_currentPlaybackState = state;
1473 10 : if (m_mediaPipelineClient)
1474 : {
1475 10 : m_mediaPipelineClient->notifyPlaybackState(state);
1476 : }
1477 20 : };
1478 :
1479 10 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1480 : }
1481 :
1482 7 : bool MediaPipelineServerInternal::notifyNeedMediaData(MediaSourceType mediaSourceType)
1483 : {
1484 7 : RIALTO_SERVER_LOG_DEBUG("entry:");
1485 :
1486 : // the task won't execute for a disconnected client therefore
1487 : // set a default value of true which will help to stop any further
1488 : // action being taken
1489 7 : bool result{true};
1490 :
1491 7 : auto task = [&]()
1492 : {
1493 7 : result = notifyNeedMediaDataInternal(mediaSourceType);
1494 7 : if (result)
1495 : {
1496 4 : m_needDataDelayCalculator.decreaseNeedMediaDataDelay(mediaSourceType);
1497 : }
1498 14 : };
1499 :
1500 7 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1501 :
1502 7 : return result;
1503 : }
1504 :
1505 8 : bool MediaPipelineServerInternal::notifyNeedMediaDataInternal(MediaSourceType mediaSourceType)
1506 : {
1507 8 : m_needMediaDataTimers.erase(mediaSourceType);
1508 8 : m_shmBuffer->clearData(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId, mediaSourceType);
1509 8 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1510 :
1511 8 : if (m_attachedSources.cend() == kSourceIter)
1512 : {
1513 1 : RIALTO_SERVER_LOG_WARN("NeedMediaData event sending failed for %s - sourceId not found",
1514 : common::convertMediaSourceType(mediaSourceType));
1515 1 : return false;
1516 : }
1517 7 : auto it = m_isMediaTypeEosMap.find(mediaSourceType);
1518 7 : if (it != m_isMediaTypeEosMap.end() && it->second)
1519 : {
1520 2 : RIALTO_SERVER_LOG_INFO("EOS, NeedMediaData not needed for %s", common::convertMediaSourceType(mediaSourceType));
1521 2 : return false;
1522 : }
1523 5 : NeedMediaData event{m_mediaPipelineClient, *m_activeRequests, *m_shmBuffer, m_sessionId,
1524 10 : mediaSourceType, kSourceIter->second, m_currentPlaybackState};
1525 5 : if (!event.send())
1526 : {
1527 0 : RIALTO_SERVER_LOG_WARN("NeedMediaData event sending failed for %s",
1528 : common::convertMediaSourceType(mediaSourceType));
1529 0 : return false;
1530 : }
1531 :
1532 5 : RIALTO_SERVER_LOG_DEBUG("%s NeedMediaData sent.", common::convertMediaSourceType(mediaSourceType));
1533 :
1534 5 : return true;
1535 : }
1536 :
1537 3 : bool MediaPipelineServerInternal::notifyNeedMediaDataWithDelay(MediaSourceType mediaSourceType)
1538 : {
1539 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
1540 :
1541 : // the task won't execute for a disconnected client therefore
1542 : // set a default value of true which will help to stop any further
1543 : // action being taken
1544 3 : bool result{true};
1545 :
1546 3 : auto task = [&]() { result = notifyNeedMediaDataWithDelayInternal(mediaSourceType); };
1547 :
1548 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
1549 :
1550 3 : return result;
1551 : }
1552 :
1553 3 : bool MediaPipelineServerInternal::notifyNeedMediaDataWithDelayInternal(MediaSourceType mediaSourceType)
1554 : {
1555 3 : m_needMediaDataTimers.erase(mediaSourceType);
1556 3 : m_shmBuffer->clearData(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId, mediaSourceType);
1557 3 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1558 :
1559 3 : if (m_attachedSources.cend() == kSourceIter)
1560 : {
1561 1 : RIALTO_SERVER_LOG_WARN("NeedMediaData event sending failed for %s - sourceId not found",
1562 : common::convertMediaSourceType(mediaSourceType));
1563 1 : return false;
1564 : }
1565 2 : auto it = m_isMediaTypeEosMap.find(mediaSourceType);
1566 2 : if (it != m_isMediaTypeEosMap.end() && it->second)
1567 : {
1568 1 : RIALTO_SERVER_LOG_INFO("EOS, NeedMediaData not needed for %s", common::convertMediaSourceType(mediaSourceType));
1569 1 : return false;
1570 : }
1571 :
1572 1 : scheduleNotifyNeedMediaData(mediaSourceType);
1573 :
1574 1 : RIALTO_SERVER_LOG_DEBUG("%s NeedMediaData scheduled.", common::convertMediaSourceType(mediaSourceType));
1575 :
1576 1 : return true;
1577 : }
1578 :
1579 1 : void MediaPipelineServerInternal::notifyPosition(std::int64_t position)
1580 : {
1581 1 : RIALTO_SERVER_LOG_DEBUG("entry:");
1582 :
1583 1 : auto task = [&, position]()
1584 : {
1585 1 : if (m_mediaPipelineClient)
1586 : {
1587 1 : m_mediaPipelineClient->notifyPosition(position);
1588 : }
1589 2 : };
1590 :
1591 1 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1592 : }
1593 :
1594 118 : void MediaPipelineServerInternal::notifyNetworkState(NetworkState state)
1595 : {
1596 118 : RIALTO_SERVER_LOG_DEBUG("entry:");
1597 :
1598 118 : auto task = [&, state]()
1599 : {
1600 118 : if (m_mediaPipelineClient)
1601 : {
1602 118 : m_mediaPipelineClient->notifyNetworkState(state);
1603 : }
1604 236 : };
1605 :
1606 118 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1607 : }
1608 :
1609 1 : void MediaPipelineServerInternal::clearActiveRequestsCache()
1610 : {
1611 1 : RIALTO_SERVER_LOG_DEBUG("entry:");
1612 :
1613 1 : auto task = [&]() { m_activeRequests->clear(); };
1614 :
1615 1 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1616 : }
1617 :
1618 1 : void MediaPipelineServerInternal::invalidateActiveRequests(const MediaSourceType &type)
1619 : {
1620 1 : RIALTO_SERVER_LOG_DEBUG("entry:");
1621 :
1622 1 : auto task = [&, type]() { m_activeRequests->erase(type); };
1623 :
1624 1 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1625 : }
1626 :
1627 2 : void MediaPipelineServerInternal::notifyQos(MediaSourceType mediaSourceType, const QosInfo &qosInfo)
1628 : {
1629 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1630 :
1631 2 : auto task = [&, mediaSourceType, qosInfo]()
1632 : {
1633 2 : if (m_mediaPipelineClient)
1634 : {
1635 2 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1636 2 : if (m_attachedSources.cend() == kSourceIter)
1637 : {
1638 1 : RIALTO_SERVER_LOG_WARN("Qos notification failed - sourceId not found for %s",
1639 : common::convertMediaSourceType(mediaSourceType));
1640 1 : return;
1641 : }
1642 1 : m_mediaPipelineClient->notifyQos(kSourceIter->second, qosInfo);
1643 : }
1644 2 : };
1645 :
1646 2 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1647 : }
1648 :
1649 0 : void MediaPipelineServerInternal::notifyBufferUnderflow(MediaSourceType mediaSourceType)
1650 : {
1651 0 : RIALTO_SERVER_LOG_DEBUG("entry:");
1652 :
1653 0 : auto task = [&, mediaSourceType]()
1654 : {
1655 0 : m_needDataDelayCalculator.resetMediaDataDelay(mediaSourceType);
1656 0 : if (m_mediaPipelineClient)
1657 : {
1658 0 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1659 0 : if (m_attachedSources.cend() == kSourceIter)
1660 : {
1661 0 : RIALTO_SERVER_LOG_WARN("Buffer underflow notification failed - sourceId not found for %s",
1662 : common::convertMediaSourceType(mediaSourceType));
1663 0 : return;
1664 : }
1665 0 : m_mediaPipelineClient->notifyBufferUnderflow(kSourceIter->second);
1666 : }
1667 0 : };
1668 :
1669 0 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1670 : }
1671 :
1672 2 : void MediaPipelineServerInternal::notifyFirstFrameReceived(MediaSourceType mediaSourceType)
1673 : {
1674 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1675 :
1676 2 : auto task = [&, mediaSourceType]()
1677 : {
1678 2 : if (m_mediaPipelineClient)
1679 : {
1680 2 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1681 2 : if (m_attachedSources.cend() == kSourceIter)
1682 : {
1683 1 : RIALTO_SERVER_LOG_WARN("First frame notification failed - sourceId not found for %s",
1684 : common::convertMediaSourceType(mediaSourceType));
1685 1 : return;
1686 : }
1687 1 : m_mediaPipelineClient->notifyFirstFrameReceived(kSourceIter->second);
1688 : }
1689 2 : };
1690 :
1691 2 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1692 : }
1693 :
1694 2 : void MediaPipelineServerInternal::notifyPlaybackError(MediaSourceType mediaSourceType, PlaybackError error)
1695 : {
1696 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1697 :
1698 2 : auto task = [&, mediaSourceType, error]()
1699 : {
1700 2 : if (m_mediaPipelineClient)
1701 : {
1702 2 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1703 2 : if (m_attachedSources.cend() == kSourceIter)
1704 : {
1705 1 : RIALTO_SERVER_LOG_WARN("Playback error notification failed - sourceId not found for %s",
1706 : common::convertMediaSourceType(mediaSourceType));
1707 1 : return;
1708 : }
1709 1 : m_mediaPipelineClient->notifyPlaybackError(kSourceIter->second, error);
1710 : }
1711 2 : };
1712 :
1713 2 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1714 : }
1715 :
1716 2 : void MediaPipelineServerInternal::notifySourceFlushed(MediaSourceType mediaSourceType)
1717 : {
1718 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
1719 :
1720 2 : auto task = [&, mediaSourceType]()
1721 : {
1722 2 : if (m_mediaPipelineClient)
1723 : {
1724 2 : const auto kSourceIter = m_attachedSources.find(mediaSourceType);
1725 2 : if (m_attachedSources.cend() == kSourceIter)
1726 : {
1727 1 : RIALTO_SERVER_LOG_WARN("Source flushed notification failed - sourceId not found for: %s",
1728 : common::convertMediaSourceType(mediaSourceType));
1729 1 : return;
1730 : }
1731 1 : m_mediaPipelineClient->notifySourceFlushed(kSourceIter->second);
1732 1 : RIALTO_SERVER_LOG_DEBUG("%s source flushed", common::convertMediaSourceType(mediaSourceType));
1733 : }
1734 1 : m_needDataDelayCalculator.resetMediaDataDelay(mediaSourceType);
1735 2 : };
1736 :
1737 2 : m_mainThread->enqueueTask(m_mainThreadClientId, task);
1738 : }
1739 :
1740 0 : void MediaPipelineServerInternal::notifyPlaybackInfo(const PlaybackInfo &playbackInfo)
1741 : {
1742 0 : if (m_mediaPipelineClient)
1743 : {
1744 0 : m_mediaPipelineClient->notifyPlaybackInfo(playbackInfo);
1745 : }
1746 : }
1747 :
1748 8 : void MediaPipelineServerInternal::scheduleNotifyNeedMediaData(MediaSourceType mediaSourceType)
1749 : {
1750 8 : RIALTO_SERVER_LOG_DEBUG("entry:");
1751 8 : auto timer = m_needMediaDataTimers.find(mediaSourceType);
1752 8 : if (m_needMediaDataTimers.end() != timer && timer->second && timer->second->isActive())
1753 : {
1754 1 : RIALTO_SERVER_LOG_DEBUG("Skip scheduling need media data for %s - it is already scheduled",
1755 : common::convertMediaSourceType(mediaSourceType));
1756 1 : return;
1757 : }
1758 :
1759 7 : m_needMediaDataTimers[mediaSourceType] =
1760 7 : m_timerFactory
1761 21 : ->createTimer(getNeedMediaDataTimeout(mediaSourceType),
1762 14 : [this, mediaSourceType]()
1763 : {
1764 1 : m_mainThread
1765 2 : ->enqueueTask(m_mainThreadClientId,
1766 1 : [this, mediaSourceType]()
1767 : {
1768 1 : m_needMediaDataTimers.erase(mediaSourceType);
1769 1 : if (!notifyNeedMediaDataInternal(mediaSourceType))
1770 : {
1771 0 : RIALTO_SERVER_LOG_WARN("Scheduled Need media data sending "
1772 : "failed for: %s. Scheduling again...",
1773 : common::convertMediaSourceType(
1774 : mediaSourceType));
1775 0 : scheduleNotifyNeedMediaData(mediaSourceType);
1776 : }
1777 : else
1778 : {
1779 1 : m_needDataDelayCalculator.increaseNeedMediaDataDelay(
1780 : mediaSourceType);
1781 : }
1782 1 : });
1783 8 : });
1784 : }
1785 :
1786 7 : std::chrono::milliseconds MediaPipelineServerInternal::getNeedMediaDataTimeout(MediaSourceType mediaSourceType)
1787 : {
1788 7 : constexpr std::chrono::milliseconds kNeedMediaDataResendTimeMsForLowLatency{5};
1789 7 : if ((mediaSourceType == MediaSourceType::VIDEO && m_IsLowLatencyVideoPlayer) ||
1790 1 : (mediaSourceType == MediaSourceType::AUDIO && m_IsLowLatencyAudioPlayer))
1791 : {
1792 2 : return kNeedMediaDataResendTimeMsForLowLatency;
1793 : }
1794 5 : return m_needDataDelayCalculator.getNeedMediaDataDelay(mediaSourceType);
1795 : }
1796 : }; // namespace firebolt::rialto::server
|