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