LCOV - code coverage report
Current view: top level - media/server/main/source - MediaPipelineServerInternal.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.8 % 792 743
Test Date: 2026-04-17 13:27:18 Functions: 97.0 % 166 161

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

Generated by: LCOV version 2.0-1