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: 2026-03-18 08:38:49 Functions: 97.0 % 166 161

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

Generated by: LCOV version 2.0-1