LCOV - code coverage report
Current view: top level - media/server/main/source - MediaPipelineServerInternal.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.9 % 806 757
Test Date: 2026-06-16 04:38:33 Functions: 97.0 % 169 164

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

Generated by: LCOV version 2.0-1