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

Generated by: LCOV version 2.0-1