LCOV - code coverage report
Current view: top level - media/server/main/source - MediaPipelineServerInternal.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.8 % 871 817
Test Date: 2026-10-14 17:48:17 Functions: 97.2 % 180 175

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

Generated by: LCOV version 2.0-1