LCOV - code coverage report
Current view: top level - media/server/main/source - MediaPipelineServerInternal.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.0 % 819 770
Test Date: 2026-03-02 14:04:59 Functions: 97.1 % 174 169

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

Generated by: LCOV version 2.0-1