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 % 838 786
Test Date: 2026-07-07 06:27:16 Functions: 97.1 % 172 167

            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           35 : std::int32_t generateSourceId()
      56              : {
      57              :     static std::int32_t sourceId{1};
      58           35 :     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          157 : 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          157 :     std::unique_ptr<IActiveRequests> &&activeRequests, IDecryptionService &decryptionService)
     139          157 :     : m_mediaPipelineClient(client), m_kGstPlayerFactory(gstPlayerFactory), m_kVideoRequirements(videoRequirements),
     140          157 :       m_sessionId{sessionId}, m_shmBuffer{shmBuffer}, m_dataReaderFactory{std::move(dataReaderFactory)},
     141          157 :       m_timerFactory{timerFactory}, m_activeRequests{std::move(activeRequests)}, m_decryptionService{decryptionService},
     142          471 :       m_currentPlaybackState{PlaybackState::UNKNOWN}, m_wasAllSourcesAttachedCalled{false}
     143              : {
     144          157 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     145              : 
     146          157 :     m_mainThread = mainThreadFactory->getMainThread();
     147          157 :     if (!m_mainThread)
     148              :     {
     149            0 :         throw std::runtime_error("Failed to get the main thread");
     150              :     }
     151          157 :     m_mainThreadClientId = m_mainThread->registerClient();
     152              : 
     153          157 :     bool result = false;
     154          157 :     auto task = [&]()
     155              :     {
     156          157 :         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          157 :             result = true;
     163              :         }
     164          314 :     };
     165              : 
     166          157 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     167          157 :     if (!result)
     168              :     {
     169            0 :         throw std::runtime_error("MediaPipelineServerInternal construction failed");
     170              :     }
     171          157 : }
     172              : 
     173          471 : MediaPipelineServerInternal::~MediaPipelineServerInternal()
     174              : {
     175          157 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     176              : 
     177          157 :     auto task = [&]()
     178              :     {
     179          163 :         for (const auto &timer : m_needMediaDataTimers)
     180              :         {
     181            6 :             if (timer.second && timer.second->isActive())
     182              :             {
     183            6 :                 timer.second->cancel();
     184              :             }
     185              :         }
     186          157 :         if (!m_shmBuffer->unmapPartition(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId))
     187              :         {
     188            0 :             RIALTO_SERVER_LOG_ERROR("Unable to unmap shm partition");
     189              :         }
     190              : 
     191          157 :         m_shmBuffer.reset();
     192          157 :         m_mainThread->unregisterClient(m_mainThreadClientId);
     193          314 :     };
     194          157 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     195          314 : }
     196              : 
     197          112 : bool MediaPipelineServerInternal::load(MediaType type, const std::string &mimeType, const std::string &url, bool isLive)
     198              : {
     199          112 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     200              : 
     201              :     bool result;
     202          112 :     auto task = [&]() { result = loadInternal(type, mimeType, url, isLive); };
     203              : 
     204          112 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     205          112 :     return result;
     206              : }
     207              : 
     208          112 : bool MediaPipelineServerInternal::loadInternal(MediaType type, const std::string &mimeType, const std::string &url,
     209              :                                                bool isLive)
     210              : {
     211          112 :     std::unique_lock lock{m_getPropertyMutex};
     212              :     /* If gstreamer player already created, destroy the old one first */
     213          112 :     if (m_gstPlayer)
     214              :     {
     215            0 :         m_gstPlayer.reset();
     216              :     }
     217              : 
     218              :     m_gstPlayer =
     219          112 :         m_kGstPlayerFactory
     220          336 :             ->createGstGenericPlayer(this, m_decryptionService, type, m_kVideoRequirements, isLive,
     221          336 :                                      firebolt::rialto::wrappers::IRdkGstreamerUtilsWrapperFactory::getFactory());
     222          112 :     if (!m_gstPlayer)
     223              :     {
     224            1 :         RIALTO_SERVER_LOG_ERROR("Failed to load gstreamer player");
     225            1 :         return false;
     226              :     }
     227              : 
     228          111 :     notifyNetworkState(NetworkState::BUFFERING);
     229              : 
     230          111 :     return true;
     231          112 : }
     232              : 
     233           37 : bool MediaPipelineServerInternal::attachSource(const std::unique_ptr<MediaSource> &source)
     234              : {
     235           37 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     236              : 
     237              :     bool result;
     238           37 :     auto task = [&]() { result = attachSourceInternal(source); };
     239              : 
     240           37 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     241           37 :     return result;
     242              : }
     243              : 
     244           37 : bool MediaPipelineServerInternal::attachSourceInternal(const std::unique_ptr<MediaSource> &source)
     245              : {
     246           37 :     source->setId(-1);
     247              : 
     248           37 :     if (!m_gstPlayer)
     249              :     {
     250            1 :         RIALTO_SERVER_LOG_ERROR("Gstreamer player has not been loaded");
     251            1 :         return false;
     252              :     }
     253              : 
     254           36 :     if (source->getType() == MediaSourceType::UNKNOWN)
     255              :     {
     256            0 :         RIALTO_SERVER_LOG_ERROR("Media source type unknown");
     257            0 :         return false;
     258              :     }
     259              : 
     260           36 :     m_gstPlayer->attachSource(source);
     261              : 
     262           36 :     const auto kSourceIter = m_attachedSources.find(source->getType());
     263           36 :     if (m_attachedSources.cend() == kSourceIter)
     264              :     {
     265           35 :         source->setId(generateSourceId());
     266           35 :         RIALTO_SERVER_LOG_DEBUG("New ID generated for MediaSourceType: %s: %d",
     267              :                                 common::convertMediaSourceType(source->getType()), source->getId());
     268           35 :         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           35 :     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 :     m_IsLowLatencyVideoPlayer = immediateOutput;
     559            4 :     return m_gstPlayer->setImmediateOutput(sourceIter->first, immediateOutput);
     560              : }
     561              : 
     562            5 : bool MediaPipelineServerInternal::getImmediateOutput(int32_t sourceId, bool &immediateOutput)
     563              : {
     564            5 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     565              : 
     566              :     bool result;
     567            5 :     auto task = [&]() { result = getImmediateOutputInternal(sourceId, immediateOutput); };
     568              : 
     569            5 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     570            5 :     return result;
     571              : }
     572              : 
     573            5 : bool MediaPipelineServerInternal::getImmediateOutputInternal(int32_t sourceId, bool &immediateOutput)
     574              : {
     575            5 :     if (!m_gstPlayer)
     576              :     {
     577            1 :         RIALTO_SERVER_LOG_ERROR("Failed - Gstreamer player has not been loaded");
     578            1 :         return false;
     579              :     }
     580            4 :     auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
     581            3 :                                    [sourceId](const auto &src) { return src.second == sourceId; });
     582            4 :     if (sourceIter == m_attachedSources.end())
     583              :     {
     584            1 :         RIALTO_SERVER_LOG_ERROR("Failed - Source not found");
     585            1 :         return false;
     586              :     }
     587            3 :     return m_gstPlayer->getImmediateOutput(sourceIter->first, immediateOutput);
     588              : }
     589              : 
     590            2 : bool MediaPipelineServerInternal::setVideoWindow(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
     591              : {
     592            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     593              : 
     594              :     bool result;
     595            2 :     auto task = [&]() { result = setVideoWindowInternal(x, y, width, height); };
     596              : 
     597            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     598            2 :     return result;
     599              : }
     600              : 
     601            2 : bool MediaPipelineServerInternal::setVideoWindowInternal(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
     602              : {
     603            2 :     if (!m_gstPlayer)
     604              :     {
     605            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set video window - Gstreamer player has not been loaded");
     606            1 :         return false;
     607              :     }
     608              : 
     609            1 :     m_gstPlayer->setVideoGeometry(x, y, width, height);
     610            1 :     return true;
     611              : }
     612              : 
     613           13 : bool MediaPipelineServerInternal::haveData(MediaSourceStatus status, uint32_t needDataRequestId)
     614              : {
     615           13 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     616              : 
     617              :     bool result;
     618           13 :     auto task = [&]() { result = haveDataInternal(status, needDataRequestId); };
     619              : 
     620           13 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     621           13 :     return result;
     622              : }
     623              : 
     624           13 : bool MediaPipelineServerInternal::haveDataInternal(MediaSourceStatus status, uint32_t needDataRequestId)
     625              : {
     626           13 :     if (!m_gstPlayer)
     627              :     {
     628            1 :         RIALTO_SERVER_LOG_ERROR("HaveData failed - Gstreamer player has not been loaded");
     629            1 :         return false;
     630              :     }
     631              : 
     632           12 :     MediaSourceType mediaSourceType = m_activeRequests->getType(needDataRequestId);
     633           12 :     if (MediaSourceType::UNKNOWN == mediaSourceType)
     634              :     {
     635            1 :         RIALTO_SERVER_LOG_WARN("NeedData RequestID is not valid: %u", needDataRequestId);
     636            1 :         return true;
     637              :     }
     638              : 
     639           11 :     unsigned int &counter = m_noAvailableSamplesCounter[mediaSourceType];
     640           11 :     if (status != MediaSourceStatus::OK && status != MediaSourceStatus::EOS)
     641              :     {
     642              :         // Incrementing the counter allows us to track the occurrences where the status is other than OK or EOS.
     643              : 
     644            3 :         ++counter;
     645            3 :         if (status == MediaSourceStatus::NO_AVAILABLE_SAMPLES)
     646              :         {
     647            2 :             RIALTO_SERVER_LOG_DEBUG("Data request for needDataRequestId: %u. NO_AVAILABLE_SAMPLES received: %u "
     648              :                                     "consecutively for mediaSourceType: %s",
     649              :                                     needDataRequestId, counter, common::convertMediaSourceType(mediaSourceType));
     650              :         }
     651              :         else
     652              :         {
     653            1 :             RIALTO_SERVER_LOG_WARN("%s Data request for needDataRequestId: %u received with wrong status: %s",
     654              :                                    common::convertMediaSourceType(mediaSourceType), needDataRequestId, toString(status));
     655            1 :             counter = 0;
     656              :         }
     657              : 
     658            3 :         m_activeRequests->erase(needDataRequestId);
     659            3 :         scheduleNotifyNeedMediaData(mediaSourceType);
     660            3 :         return true;
     661              :     }
     662              :     else
     663              :     {
     664            8 :         RIALTO_SERVER_LOG_DEBUG("%s Data request for needDataRequestId: %u received with correct status",
     665              :                                 common::convertMediaSourceType(mediaSourceType), needDataRequestId);
     666            8 :         counter = 0;
     667              :     }
     668              : 
     669              :     try
     670              :     {
     671            8 :         const IMediaPipeline::MediaSegmentVector &kSegments = m_activeRequests->getSegments(needDataRequestId);
     672            7 :         m_gstPlayer->attachSamples(kSegments);
     673              :     }
     674            1 :     catch (const std::runtime_error &e)
     675              :     {
     676            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get segments %s", e.what());
     677            1 :         m_activeRequests->erase(needDataRequestId);
     678            1 :         return false;
     679              :     }
     680              : 
     681            7 :     m_activeRequests->erase(needDataRequestId);
     682            7 :     if (status == MediaSourceStatus::EOS)
     683              :     {
     684            6 :         m_gstPlayer->setEos(mediaSourceType);
     685            6 :         m_isMediaTypeEosMap[mediaSourceType] = true;
     686              :     }
     687              : 
     688            7 :     return true;
     689              : }
     690              : 
     691           15 : bool MediaPipelineServerInternal::haveData(MediaSourceStatus status, uint32_t numFrames, uint32_t needDataRequestId)
     692              : {
     693           15 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     694              : 
     695              :     bool result;
     696           15 :     auto task = [&]() { result = haveDataInternal(status, numFrames, needDataRequestId); };
     697              : 
     698           15 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     699           15 :     return result;
     700              : }
     701              : 
     702           15 : bool MediaPipelineServerInternal::haveDataInternal(MediaSourceStatus status, uint32_t numFrames,
     703              :                                                    uint32_t needDataRequestId)
     704              : {
     705           15 :     if (!m_gstPlayer)
     706              :     {
     707            1 :         RIALTO_SERVER_LOG_ERROR("HaveData failed - Gstreamer player has not been loaded");
     708            1 :         return false;
     709              :     }
     710           14 :     MediaSourceType mediaSourceType = m_activeRequests->getType(needDataRequestId);
     711           14 :     if (MediaSourceType::UNKNOWN == mediaSourceType)
     712              :     {
     713            1 :         RIALTO_SERVER_LOG_WARN("NeedData RequestID is not valid: %u", needDataRequestId);
     714            1 :         return true;
     715              :     }
     716           13 :     const std::uint32_t kMaxNumFrames = m_activeRequests->getMaxFrames(needDataRequestId);
     717           13 :     m_activeRequests->erase(needDataRequestId);
     718              : 
     719           13 :     unsigned int &counter = m_noAvailableSamplesCounter[mediaSourceType];
     720           13 :     if (status != MediaSourceStatus::OK && status != MediaSourceStatus::EOS &&
     721              :         status != MediaSourceStatus::NO_SPACE_FOR_SAMPLES)
     722              :     {
     723              :         // Incrementing the counter allows us to track the occurrences where the status is other than OK or EOS.
     724              : 
     725            4 :         ++counter;
     726            4 :         if (status == MediaSourceStatus::NO_AVAILABLE_SAMPLES)
     727              :         {
     728            0 :             RIALTO_SERVER_LOG_DEBUG("Data request for needDataRequestId: %u. NO_AVAILABLE_SAMPLES received: %u "
     729              :                                     "consecutively for mediaSourceType: %s",
     730              :                                     needDataRequestId, counter, common::convertMediaSourceType(mediaSourceType));
     731              :         }
     732              :         else
     733              :         {
     734            4 :             RIALTO_SERVER_LOG_WARN("%s Data request for needDataRequestId: %u received with wrong status",
     735              :                                    common::convertMediaSourceType(mediaSourceType), needDataRequestId);
     736            4 :             counter = 0;
     737              :         }
     738            4 :         scheduleNotifyNeedMediaData(mediaSourceType);
     739            4 :         return true;
     740              :     }
     741              :     else
     742              :     {
     743            9 :         RIALTO_SERVER_LOG_DEBUG("%s Data request for needDataRequestId: %u received with correct status",
     744              :                                 common::convertMediaSourceType(mediaSourceType), needDataRequestId);
     745            9 :         counter = 0;
     746              :     }
     747              : 
     748            9 :     uint8_t *buffer = m_shmBuffer->getBuffer();
     749            9 :     if (!buffer)
     750              :     {
     751            1 :         RIALTO_SERVER_LOG_ERROR("No buffer available");
     752            1 :         notifyPlaybackState(PlaybackState::FAILURE);
     753            1 :         return false;
     754              :     }
     755              : 
     756            8 :     std::uint32_t regionOffset = 0;
     757              :     try
     758              :     {
     759              :         regionOffset =
     760            8 :             m_shmBuffer->getDataOffset(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId, mediaSourceType);
     761              :     }
     762            1 :     catch (const std::runtime_error &e)
     763              :     {
     764            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get region's buffer offset, reason: %s", e.what());
     765            1 :         notifyPlaybackState(PlaybackState::FAILURE);
     766            1 :         return false;
     767              :     }
     768              : 
     769            7 :     if (0 != numFrames)
     770              :     {
     771            6 :         const bool kIsBufferFull = kMaxNumFrames == numFrames || status == MediaSourceStatus::NO_SPACE_FOR_SAMPLES ||
     772              :                                    status == MediaSourceStatus::EOS;
     773              :         std::shared_ptr<IDataReader> dataReader =
     774            6 :             m_dataReaderFactory->createDataReader(mediaSourceType, buffer, regionOffset, numFrames, kIsBufferFull);
     775            6 :         if (!dataReader)
     776              :         {
     777            1 :             RIALTO_SERVER_LOG_ERROR("Metadata version not supported for %s request id: %u",
     778              :                                     common::convertMediaSourceType(mediaSourceType), needDataRequestId);
     779            1 :             notifyPlaybackState(PlaybackState::FAILURE);
     780            1 :             return false;
     781              :         }
     782            5 :         m_gstPlayer->attachSamples(dataReader);
     783            6 :     }
     784            6 :     if (status == MediaSourceStatus::EOS)
     785              :     {
     786            2 :         m_gstPlayer->setEos(mediaSourceType);
     787            2 :         m_isMediaTypeEosMap[mediaSourceType] = true;
     788              :     }
     789              : 
     790            6 :     return true;
     791              : }
     792              : 
     793            2 : void MediaPipelineServerInternal::ping(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler)
     794              : {
     795            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     796              : 
     797            2 :     auto task = [&]() { pingInternal(std::move(heartbeatHandler)); };
     798            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     799              : }
     800              : 
     801            2 : void MediaPipelineServerInternal::pingInternal(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler)
     802              : {
     803            2 :     if (!m_gstPlayer)
     804              :     {
     805              :         // No need to check GstPlayer worker thread, we reached this function, so main thread is working fine.
     806            1 :         heartbeatHandler.reset();
     807            1 :         return;
     808              :     }
     809              :     // Check GstPlayer worker thread
     810            1 :     m_gstPlayer->ping(std::move(heartbeatHandler));
     811              : }
     812              : 
     813            2 : bool MediaPipelineServerInternal::renderFrame()
     814              : {
     815            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     816              : 
     817              :     bool result;
     818            2 :     auto task = [&]() { result = renderFrameInternal(); };
     819              : 
     820            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     821            2 :     return result;
     822              : }
     823              : 
     824            2 : bool MediaPipelineServerInternal::renderFrameInternal()
     825              : {
     826            2 :     if (!m_gstPlayer)
     827              :     {
     828            1 :         RIALTO_SERVER_LOG_ERROR("renderFrame failed - Gstreamer player has not been loaded");
     829            1 :         return false;
     830              :     }
     831              : 
     832            1 :     m_gstPlayer->renderFrame();
     833            1 :     return true;
     834              : }
     835              : 
     836            2 : bool MediaPipelineServerInternal::setVolume(double targetVolume, uint32_t volumeDuration, EaseType easeType)
     837              : {
     838            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     839              : 
     840              :     bool result;
     841            2 :     auto task = [&]() { result = setVolumeInternal(targetVolume, volumeDuration, easeType); };
     842              : 
     843            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     844            2 :     return result;
     845              : }
     846              : 
     847            2 : bool MediaPipelineServerInternal::setVolumeInternal(double targetVolume, uint32_t volumeDuration, EaseType easeType)
     848              : {
     849            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     850              : 
     851            2 :     if (!m_gstPlayer)
     852              :     {
     853            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set volume - Gstreamer player has not been loaded");
     854            1 :         return false;
     855              :     }
     856            1 :     m_gstPlayer->setVolume(targetVolume, volumeDuration, easeType);
     857            1 :     return true;
     858              : }
     859              : 
     860            3 : bool MediaPipelineServerInternal::getVolume(double &currentVolume)
     861              : {
     862            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     863              : 
     864              :     bool result;
     865            3 :     auto task = [&]() { result = getVolumeInternal(currentVolume); };
     866              : 
     867            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     868            3 :     return result;
     869              : }
     870              : 
     871            3 : bool MediaPipelineServerInternal::getVolumeInternal(double &currentVolume)
     872              : {
     873            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     874              : 
     875            3 :     if (!m_gstPlayer)
     876              :     {
     877            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get volume - Gstreamer player has not been loaded");
     878            1 :         return false;
     879              :     }
     880            2 :     return m_gstPlayer->getVolume(currentVolume);
     881              : }
     882              : 
     883            3 : bool MediaPipelineServerInternal::setMute(std::int32_t sourceId, bool mute)
     884              : {
     885            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     886              : 
     887              :     bool result;
     888            3 :     auto task = [&]() { result = setMuteInternal(sourceId, mute); };
     889              : 
     890            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     891            3 :     return result;
     892              : }
     893              : 
     894            3 : bool MediaPipelineServerInternal::setMuteInternal(std::int32_t sourceId, bool mute)
     895              : {
     896            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     897              : 
     898            3 :     if (!m_gstPlayer)
     899              :     {
     900            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set mute - Gstreamer player has not been loaded");
     901            1 :         return false;
     902              :     }
     903              : 
     904            2 :     auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
     905            1 :                                    [sourceId](const auto &src) { return src.second == sourceId; });
     906            2 :     if (sourceIter == m_attachedSources.end())
     907              :     {
     908            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set mute - Source with id: %d not found", sourceId);
     909            1 :         return false;
     910              :     }
     911              : 
     912            1 :     m_gstPlayer->setMute(sourceIter->first, mute);
     913              : 
     914            1 :     return true;
     915              : }
     916              : 
     917            4 : bool MediaPipelineServerInternal::getMute(std::int32_t sourceId, bool &mute)
     918              : {
     919            4 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     920              : 
     921              :     bool result;
     922            4 :     auto task = [&]() { result = getMuteInternal(sourceId, mute); };
     923              : 
     924            4 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     925            4 :     return result;
     926              : }
     927              : 
     928            4 : bool MediaPipelineServerInternal::getMuteInternal(std::int32_t sourceId, bool &mute)
     929              : {
     930            4 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     931              : 
     932            4 :     if (!m_gstPlayer)
     933              :     {
     934            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get mute - Gstreamer player has not been loaded");
     935            1 :         return false;
     936              :     }
     937              : 
     938            3 :     auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
     939            2 :                                    [sourceId](const auto &src) { return src.second == sourceId; });
     940            3 :     if (sourceIter == m_attachedSources.end())
     941              :     {
     942            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get mute - Source with id: %d not found", sourceId);
     943            1 :         return false;
     944              :     }
     945              : 
     946            2 :     return m_gstPlayer->getMute(sourceIter->first, mute);
     947              : }
     948              : 
     949            2 : bool MediaPipelineServerInternal::setTextTrackIdentifier(const std::string &textTrackIdentifier)
     950              : {
     951            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     952              : 
     953              :     bool result;
     954            2 :     auto task = [&]() { result = setTextTrackIdentifierInternal(textTrackIdentifier); };
     955              : 
     956            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     957            2 :     return result;
     958              : }
     959              : 
     960            2 : bool MediaPipelineServerInternal::setTextTrackIdentifierInternal(const std::string &textTrackIdentifier)
     961              : {
     962            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     963              : 
     964            2 :     if (!m_gstPlayer)
     965              :     {
     966            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set text track identifier - Gstreamer player has not been loaded");
     967            1 :         return false;
     968              :     }
     969              : 
     970            1 :     m_gstPlayer->setTextTrackIdentifier(textTrackIdentifier);
     971              : 
     972            1 :     return true;
     973              : }
     974              : 
     975            3 : bool MediaPipelineServerInternal::getTextTrackIdentifier(std::string &textTrackIdentifier)
     976              : {
     977            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     978              : 
     979              :     bool result;
     980            3 :     auto task = [&]() { result = getTextTrackIdentifierInternal(textTrackIdentifier); };
     981              : 
     982            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
     983            3 :     return result;
     984              : }
     985              : 
     986            3 : bool MediaPipelineServerInternal::getTextTrackIdentifierInternal(std::string &textTrackIdentifier)
     987              : {
     988            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     989              : 
     990            3 :     if (!m_gstPlayer)
     991              :     {
     992            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get mute - Gstreamer player has not been loaded");
     993            1 :         return false;
     994              :     }
     995              : 
     996            2 :     return m_gstPlayer->getTextTrackIdentifier(textTrackIdentifier);
     997              : }
     998              : 
     999            4 : bool MediaPipelineServerInternal::flush(int32_t sourceId, bool resetTime, bool &async)
    1000              : {
    1001            4 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1002              : 
    1003              :     bool result;
    1004            4 :     auto task = [&]() { result = flushInternal(sourceId, resetTime, async); };
    1005              : 
    1006            4 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1007            4 :     return result;
    1008              : }
    1009              : 
    1010            4 : bool MediaPipelineServerInternal::setLowLatency(bool lowLatency)
    1011              : {
    1012            4 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1013              : 
    1014              :     bool result;
    1015            4 :     auto task = [&]() { result = setLowLatencyInternal(lowLatency); };
    1016              : 
    1017            4 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1018            4 :     return result;
    1019              : }
    1020              : 
    1021            4 : bool MediaPipelineServerInternal::setLowLatencyInternal(bool lowLatency)
    1022              : {
    1023            4 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1024              : 
    1025            4 :     if (!m_gstPlayer)
    1026              :     {
    1027            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set low latency - Gstreamer player has not been loaded");
    1028            1 :         return false;
    1029              :     }
    1030            3 :     m_IsLowLatencyAudioPlayer = lowLatency;
    1031              : 
    1032            3 :     return m_gstPlayer->setLowLatency(lowLatency);
    1033              : }
    1034              : 
    1035            3 : bool MediaPipelineServerInternal::setSync(bool sync)
    1036              : {
    1037            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1038              : 
    1039              :     bool result;
    1040            3 :     auto task = [&]() { result = setSyncInternal(sync); };
    1041              : 
    1042            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1043            3 :     return result;
    1044              : }
    1045              : 
    1046            3 : bool MediaPipelineServerInternal::setSyncInternal(bool sync)
    1047              : {
    1048            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1049              : 
    1050            3 :     if (!m_gstPlayer)
    1051              :     {
    1052            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set sync - Gstreamer player has not been loaded");
    1053            1 :         return false;
    1054              :     }
    1055            2 :     return m_gstPlayer->setSync(sync);
    1056              : }
    1057              : 
    1058            3 : bool MediaPipelineServerInternal::getSync(bool &sync)
    1059              : {
    1060            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1061              : 
    1062              :     bool result;
    1063            3 :     auto task = [&]() { result = getSyncInternal(sync); };
    1064              : 
    1065            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1066            3 :     return result;
    1067              : }
    1068              : 
    1069            3 : bool MediaPipelineServerInternal::getSyncInternal(bool &sync)
    1070              : {
    1071            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1072              : 
    1073            3 :     if (!m_gstPlayer)
    1074              :     {
    1075            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get sync - Gstreamer player has not been loaded");
    1076            1 :         return false;
    1077              :     }
    1078            2 :     return m_gstPlayer->getSync(sync);
    1079              : }
    1080              : 
    1081            3 : bool MediaPipelineServerInternal::setSyncOff(bool syncOff)
    1082              : {
    1083            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1084              : 
    1085              :     bool result;
    1086            3 :     auto task = [&]() { result = setSyncOffInternal(syncOff); };
    1087              : 
    1088            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1089            3 :     return result;
    1090              : }
    1091              : 
    1092            3 : bool MediaPipelineServerInternal::setSyncOffInternal(bool syncOff)
    1093              : {
    1094            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1095              : 
    1096            3 :     if (!m_gstPlayer)
    1097              :     {
    1098            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set sync off - Gstreamer player has not been loaded");
    1099            1 :         return false;
    1100              :     }
    1101            2 :     return m_gstPlayer->setSyncOff(syncOff);
    1102              : }
    1103              : 
    1104            4 : bool MediaPipelineServerInternal::setStreamSyncMode(int32_t sourceId, int32_t streamSyncMode)
    1105              : {
    1106            4 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1107              : 
    1108              :     bool result;
    1109            4 :     auto task = [&]() { result = setStreamSyncModeInternal(sourceId, streamSyncMode); };
    1110              : 
    1111            4 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1112            4 :     return result;
    1113              : }
    1114              : 
    1115            4 : bool MediaPipelineServerInternal::setStreamSyncModeInternal(int32_t sourceId, int32_t streamSyncMode)
    1116              : {
    1117            4 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1118              : 
    1119            4 :     if (!m_gstPlayer)
    1120              :     {
    1121            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set stream sync mode - Gstreamer player has not been loaded");
    1122            1 :         return false;
    1123              :     }
    1124              : 
    1125            3 :     auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
    1126            2 :                                    [sourceId](const auto &src) { return src.second == sourceId; });
    1127            3 :     if (sourceIter == m_attachedSources.end())
    1128              :     {
    1129            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set stream sync mode - Source with id: %d not found", sourceId);
    1130            1 :         return false;
    1131              :     }
    1132              : 
    1133            2 :     return m_gstPlayer->setStreamSyncMode(sourceIter->first, streamSyncMode);
    1134              : }
    1135              : 
    1136            3 : bool MediaPipelineServerInternal::getStreamSyncMode(int32_t &streamSyncMode)
    1137              : {
    1138            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1139              : 
    1140              :     bool result;
    1141            3 :     auto task = [&]() { result = getStreamSyncModeInternal(streamSyncMode); };
    1142              : 
    1143            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1144            3 :     return result;
    1145              : }
    1146              : 
    1147            3 : bool MediaPipelineServerInternal::getStreamSyncModeInternal(int32_t &streamSyncMode)
    1148              : {
    1149            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1150              : 
    1151            3 :     if (!m_gstPlayer)
    1152              :     {
    1153            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get stream sync mode - Gstreamer player has not been loaded");
    1154            1 :         return false;
    1155              :     }
    1156            2 :     return m_gstPlayer->getStreamSyncMode(streamSyncMode);
    1157              : }
    1158              : 
    1159            4 : bool MediaPipelineServerInternal::flushInternal(int32_t sourceId, bool resetTime, bool &async)
    1160              : {
    1161            4 :     if (!m_gstPlayer)
    1162              :     {
    1163            1 :         RIALTO_SERVER_LOG_ERROR("Failed to flush - Gstreamer player has not been loaded");
    1164            1 :         return false;
    1165              :     }
    1166            3 :     auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
    1167            2 :                                    [sourceId](const auto &src) { return src.second == sourceId; });
    1168            3 :     if (sourceIter == m_attachedSources.end())
    1169              :     {
    1170            1 :         RIALTO_SERVER_LOG_ERROR("Failed to flush - Source with id: %d not found", sourceId);
    1171            1 :         return false;
    1172              :     }
    1173              : 
    1174            2 :     m_gstPlayer->flush(sourceIter->first, resetTime, async);
    1175              : 
    1176            2 :     m_needMediaDataTimers.erase(sourceIter->first);
    1177              : 
    1178              :     // Reset Eos on flush
    1179            2 :     auto it = m_isMediaTypeEosMap.find(sourceIter->first);
    1180            2 :     if (it != m_isMediaTypeEosMap.end() && it->second)
    1181              :     {
    1182            1 :         it->second = false;
    1183              :     }
    1184              : 
    1185            2 :     return true;
    1186              : }
    1187              : 
    1188            3 : bool MediaPipelineServerInternal::setSourcePosition(int32_t sourceId, int64_t position, bool resetTime,
    1189              :                                                     double appliedRate, uint64_t stopPosition)
    1190              : {
    1191            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1192              : 
    1193              :     bool result;
    1194            3 :     auto task = [&]() { result = setSourcePositionInternal(sourceId, position, resetTime, appliedRate, stopPosition); };
    1195              : 
    1196            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1197            3 :     return result;
    1198              : }
    1199              : 
    1200            3 : bool MediaPipelineServerInternal::setSourcePositionInternal(int32_t sourceId, int64_t position, bool resetTime,
    1201              :                                                             double appliedRate, uint64_t stopPosition)
    1202              : {
    1203            3 :     if (!m_gstPlayer)
    1204              :     {
    1205            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set source position - Gstreamer player has not been loaded");
    1206            1 :         return false;
    1207              :     }
    1208            2 :     auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
    1209            1 :                                    [sourceId](const auto &src) { return src.second == sourceId; });
    1210            2 :     if (sourceIter == m_attachedSources.end())
    1211              :     {
    1212            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set source position - Source with id: %d not found", sourceId);
    1213            1 :         return false;
    1214              :     }
    1215              : 
    1216            1 :     m_gstPlayer->setSourcePosition(sourceIter->first, position, resetTime, appliedRate, stopPosition);
    1217              : 
    1218              :     // Reset Eos on seek
    1219            1 :     auto it = m_isMediaTypeEosMap.find(sourceIter->first);
    1220            1 :     if (it != m_isMediaTypeEosMap.end() && it->second)
    1221              :     {
    1222            0 :         it->second = false;
    1223              :     }
    1224              : 
    1225            1 :     return true;
    1226              : }
    1227              : 
    1228            3 : bool MediaPipelineServerInternal::setSubtitleOffset(int32_t sourceId, int64_t position)
    1229              : {
    1230            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1231              : 
    1232              :     bool result;
    1233            3 :     auto task = [&]() { result = setSubtitleOffsetInternal(sourceId, position); };
    1234              : 
    1235            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1236            3 :     return result;
    1237              : }
    1238              : 
    1239            3 : bool MediaPipelineServerInternal::setSubtitleOffsetInternal(int32_t sourceId, int64_t position)
    1240              : {
    1241            3 :     if (!m_gstPlayer)
    1242              :     {
    1243            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set subtitle offset - Gstreamer player has not been loaded");
    1244            1 :         return false;
    1245              :     }
    1246            2 :     auto sourceIter = std::find_if(m_attachedSources.begin(), m_attachedSources.end(),
    1247            1 :                                    [sourceId](const auto &src) { return src.second == sourceId; });
    1248            2 :     if (sourceIter == m_attachedSources.end())
    1249              :     {
    1250            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set subtitle offset - Source with id: %d not found", sourceId);
    1251            1 :         return false;
    1252              :     }
    1253              : 
    1254            1 :     m_gstPlayer->setSubtitleOffset(position);
    1255            1 :     return true;
    1256              : }
    1257              : 
    1258            2 : bool MediaPipelineServerInternal::processAudioGap(int64_t position, uint32_t duration, int64_t discontinuityGap,
    1259              :                                                   bool audioAac)
    1260              : {
    1261            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1262              : 
    1263              :     bool result;
    1264            2 :     auto task = [&]() { result = processAudioGapInternal(position, duration, discontinuityGap, audioAac); };
    1265              : 
    1266            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1267            2 :     return result;
    1268              : }
    1269              : 
    1270            2 : bool MediaPipelineServerInternal::processAudioGapInternal(int64_t position, uint32_t duration, int64_t discontinuityGap,
    1271              :                                                           bool audioAac)
    1272              : {
    1273            2 :     if (!m_gstPlayer)
    1274              :     {
    1275            1 :         RIALTO_SERVER_LOG_ERROR("Failed to process audio gap - Gstreamer player has not been loaded");
    1276            1 :         return false;
    1277              :     }
    1278            1 :     m_gstPlayer->processAudioGap(position, duration, discontinuityGap, audioAac);
    1279            1 :     return true;
    1280              : }
    1281              : 
    1282            2 : bool MediaPipelineServerInternal::setBufferingLimit(uint32_t limitBufferingMs)
    1283              : {
    1284              :     bool result;
    1285            2 :     auto task = [&]() { result = setBufferingLimitInternal(limitBufferingMs); };
    1286              : 
    1287            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1288            2 :     return result;
    1289              : }
    1290              : 
    1291            2 : bool MediaPipelineServerInternal::setBufferingLimitInternal(uint32_t limitBufferingMs)
    1292              : {
    1293            2 :     if (!m_gstPlayer)
    1294              :     {
    1295            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set buffering limit - Gstreamer player has not been loaded");
    1296            1 :         return false;
    1297              :     }
    1298            1 :     m_gstPlayer->setBufferingLimit(limitBufferingMs);
    1299            1 :     return true;
    1300              : }
    1301              : 
    1302            3 : bool MediaPipelineServerInternal::getBufferingLimit(uint32_t &limitBufferingMs)
    1303              : {
    1304              :     bool result;
    1305            3 :     auto task = [&]() { result = getBufferingLimitInternal(limitBufferingMs); };
    1306              : 
    1307            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1308            3 :     return result;
    1309              : }
    1310              : 
    1311            3 : bool MediaPipelineServerInternal::getBufferingLimitInternal(uint32_t &limitBufferingMs)
    1312              : {
    1313            3 :     if (!m_gstPlayer)
    1314              :     {
    1315            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get buffering limit - Gstreamer player has not been loaded");
    1316            1 :         return false;
    1317              :     }
    1318            2 :     return m_gstPlayer->getBufferingLimit(limitBufferingMs);
    1319              : }
    1320              : 
    1321            2 : bool MediaPipelineServerInternal::setUseBuffering(bool useBuffering)
    1322              : {
    1323              :     bool result;
    1324            2 :     auto task = [&]() { result = setUseBufferingInternal(useBuffering); };
    1325              : 
    1326            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1327            2 :     return result;
    1328              : }
    1329              : 
    1330            2 : bool MediaPipelineServerInternal::setUseBufferingInternal(bool useBuffering)
    1331              : {
    1332            2 :     if (!m_gstPlayer)
    1333              :     {
    1334            1 :         RIALTO_SERVER_LOG_ERROR("Failed to set use buffering - Gstreamer player has not been loaded");
    1335            1 :         return false;
    1336              :     }
    1337            1 :     m_gstPlayer->setUseBuffering(useBuffering);
    1338            1 :     return true;
    1339              : }
    1340              : 
    1341            3 : bool MediaPipelineServerInternal::getUseBuffering(bool &useBuffering)
    1342              : {
    1343              :     bool result;
    1344            3 :     auto task = [&]() { result = getUseBufferingInternal(useBuffering); };
    1345              : 
    1346            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1347            3 :     return result;
    1348              : }
    1349              : 
    1350            3 : bool MediaPipelineServerInternal::getUseBufferingInternal(bool &useBuffering)
    1351              : {
    1352            3 :     if (!m_gstPlayer)
    1353              :     {
    1354            1 :         RIALTO_SERVER_LOG_ERROR("Failed to get use buffering - Gstreamer player has not been loaded");
    1355            1 :         return false;
    1356              :     }
    1357            2 :     return m_gstPlayer->getUseBuffering(useBuffering);
    1358              : }
    1359              : 
    1360            2 : bool MediaPipelineServerInternal::switchSource(const std::unique_ptr<MediaSource> &source)
    1361              : {
    1362              :     bool result;
    1363            2 :     auto task = [&]() { result = switchSourceInternal(source); };
    1364              : 
    1365            2 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1366            2 :     return result;
    1367              : }
    1368              : 
    1369            2 : bool MediaPipelineServerInternal::switchSourceInternal(const std::unique_ptr<MediaSource> &source)
    1370              : {
    1371            2 :     if (!m_gstPlayer)
    1372              :     {
    1373            1 :         RIALTO_SERVER_LOG_ERROR("Failed to switch source - Gstreamer player has not been loaded");
    1374            1 :         return false;
    1375              :     }
    1376            1 :     m_gstPlayer->switchSource(source);
    1377            1 :     return true;
    1378              : }
    1379              : 
    1380            3 : AddSegmentStatus MediaPipelineServerInternal::addSegment(uint32_t needDataRequestId,
    1381              :                                                          const std::unique_ptr<MediaSegment> &mediaSegment)
    1382              : {
    1383            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1384              : 
    1385            3 :     AddSegmentStatus status{AddSegmentStatus::ERROR};
    1386            3 :     auto task = [&]() { status = addSegmentInternal(needDataRequestId, mediaSegment); };
    1387              : 
    1388            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1389            3 :     return status;
    1390              : }
    1391              : 
    1392            3 : AddSegmentStatus MediaPipelineServerInternal::addSegmentInternal(uint32_t needDataRequestId,
    1393              :                                                                  const std::unique_ptr<MediaSegment> &mediaSegment)
    1394              : {
    1395            3 :     AddSegmentStatus status = m_activeRequests->addSegment(needDataRequestId, mediaSegment);
    1396            3 :     if (status != AddSegmentStatus::OK)
    1397              :     {
    1398            2 :         RIALTO_SERVER_LOG_ERROR("Failed to add segment for request id: %u", needDataRequestId);
    1399              :     }
    1400              : 
    1401            3 :     return status;
    1402              : }
    1403              : 
    1404            0 : std::weak_ptr<IMediaPipelineClient> MediaPipelineServerInternal::getClient()
    1405              : {
    1406            0 :     return m_mediaPipelineClient;
    1407              : }
    1408              : 
    1409           10 : void MediaPipelineServerInternal::notifyPlaybackState(PlaybackState state)
    1410              : {
    1411           10 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1412              : 
    1413           10 :     auto task = [&, state]()
    1414              :     {
    1415           10 :         m_currentPlaybackState = state;
    1416           10 :         if (m_mediaPipelineClient)
    1417              :         {
    1418           10 :             m_mediaPipelineClient->notifyPlaybackState(state);
    1419              :         }
    1420           20 :     };
    1421              : 
    1422           10 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
    1423              : }
    1424              : 
    1425            7 : bool MediaPipelineServerInternal::notifyNeedMediaData(MediaSourceType mediaSourceType)
    1426              : {
    1427            7 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1428              : 
    1429              :     // the task won't execute for a disconnected client therefore
    1430              :     // set a default value of true which will help to stop any further
    1431              :     // action being taken
    1432            7 :     bool result{true};
    1433              : 
    1434            7 :     auto task = [&]()
    1435              :     {
    1436            7 :         result = notifyNeedMediaDataInternal(mediaSourceType);
    1437            7 :         if (result)
    1438              :         {
    1439            4 :             m_needDataDelayCalculator.decreaseNeedMediaDataDelay(mediaSourceType);
    1440              :         }
    1441           14 :     };
    1442              : 
    1443            7 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1444              : 
    1445            7 :     return result;
    1446              : }
    1447              : 
    1448            8 : bool MediaPipelineServerInternal::notifyNeedMediaDataInternal(MediaSourceType mediaSourceType)
    1449              : {
    1450            8 :     m_needMediaDataTimers.erase(mediaSourceType);
    1451            8 :     m_shmBuffer->clearData(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId, mediaSourceType);
    1452            8 :     const auto kSourceIter = m_attachedSources.find(mediaSourceType);
    1453              : 
    1454            8 :     if (m_attachedSources.cend() == kSourceIter)
    1455              :     {
    1456            1 :         RIALTO_SERVER_LOG_WARN("NeedMediaData event sending failed for %s - sourceId not found",
    1457              :                                common::convertMediaSourceType(mediaSourceType));
    1458            1 :         return false;
    1459              :     }
    1460            7 :     auto it = m_isMediaTypeEosMap.find(mediaSourceType);
    1461            7 :     if (it != m_isMediaTypeEosMap.end() && it->second)
    1462              :     {
    1463            2 :         RIALTO_SERVER_LOG_INFO("EOS, NeedMediaData not needed for %s", common::convertMediaSourceType(mediaSourceType));
    1464            2 :         return false;
    1465              :     }
    1466            5 :     NeedMediaData event{m_mediaPipelineClient, *m_activeRequests,   *m_shmBuffer,          m_sessionId,
    1467           10 :                         mediaSourceType,       kSourceIter->second, m_currentPlaybackState};
    1468            5 :     if (!event.send())
    1469              :     {
    1470            0 :         RIALTO_SERVER_LOG_WARN("NeedMediaData event sending failed for %s",
    1471              :                                common::convertMediaSourceType(mediaSourceType));
    1472            0 :         return false;
    1473              :     }
    1474              : 
    1475            5 :     RIALTO_SERVER_LOG_DEBUG("%s NeedMediaData sent.", common::convertMediaSourceType(mediaSourceType));
    1476              : 
    1477            5 :     return true;
    1478              : }
    1479              : 
    1480            3 : bool MediaPipelineServerInternal::notifyNeedMediaDataWithDelay(MediaSourceType mediaSourceType)
    1481              : {
    1482            3 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1483              : 
    1484              :     // the task won't execute for a disconnected client therefore
    1485              :     // set a default value of true which will help to stop any further
    1486              :     // action being taken
    1487            3 :     bool result{true};
    1488              : 
    1489            3 :     auto task = [&]() { result = notifyNeedMediaDataWithDelayInternal(mediaSourceType); };
    1490              : 
    1491            3 :     m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
    1492              : 
    1493            3 :     return result;
    1494              : }
    1495              : 
    1496            3 : bool MediaPipelineServerInternal::notifyNeedMediaDataWithDelayInternal(MediaSourceType mediaSourceType)
    1497              : {
    1498            3 :     m_needMediaDataTimers.erase(mediaSourceType);
    1499            3 :     m_shmBuffer->clearData(ISharedMemoryBuffer::MediaPlaybackType::GENERIC, m_sessionId, mediaSourceType);
    1500            3 :     const auto kSourceIter = m_attachedSources.find(mediaSourceType);
    1501              : 
    1502            3 :     if (m_attachedSources.cend() == kSourceIter)
    1503              :     {
    1504            1 :         RIALTO_SERVER_LOG_WARN("NeedMediaData event sending failed for %s - sourceId not found",
    1505              :                                common::convertMediaSourceType(mediaSourceType));
    1506            1 :         return false;
    1507              :     }
    1508            2 :     auto it = m_isMediaTypeEosMap.find(mediaSourceType);
    1509            2 :     if (it != m_isMediaTypeEosMap.end() && it->second)
    1510              :     {
    1511            1 :         RIALTO_SERVER_LOG_INFO("EOS, NeedMediaData not needed for %s", common::convertMediaSourceType(mediaSourceType));
    1512            1 :         return false;
    1513              :     }
    1514              : 
    1515            1 :     scheduleNotifyNeedMediaData(mediaSourceType);
    1516              : 
    1517            1 :     RIALTO_SERVER_LOG_DEBUG("%s NeedMediaData scheduled.", common::convertMediaSourceType(mediaSourceType));
    1518              : 
    1519            1 :     return true;
    1520              : }
    1521              : 
    1522            1 : void MediaPipelineServerInternal::notifyPosition(std::int64_t position)
    1523              : {
    1524            1 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1525              : 
    1526            1 :     auto task = [&, position]()
    1527              :     {
    1528            1 :         if (m_mediaPipelineClient)
    1529              :         {
    1530            1 :             m_mediaPipelineClient->notifyPosition(position);
    1531              :         }
    1532            2 :     };
    1533              : 
    1534            1 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
    1535              : }
    1536              : 
    1537          112 : void MediaPipelineServerInternal::notifyNetworkState(NetworkState state)
    1538              : {
    1539          112 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1540              : 
    1541          112 :     auto task = [&, state]()
    1542              :     {
    1543          112 :         if (m_mediaPipelineClient)
    1544              :         {
    1545          112 :             m_mediaPipelineClient->notifyNetworkState(state);
    1546              :         }
    1547          224 :     };
    1548              : 
    1549          112 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
    1550              : }
    1551              : 
    1552            1 : void MediaPipelineServerInternal::clearActiveRequestsCache()
    1553              : {
    1554            1 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1555              : 
    1556            1 :     auto task = [&]() { m_activeRequests->clear(); };
    1557              : 
    1558            1 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
    1559              : }
    1560              : 
    1561            1 : void MediaPipelineServerInternal::invalidateActiveRequests(const MediaSourceType &type)
    1562              : {
    1563            1 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1564              : 
    1565            1 :     auto task = [&, type]() { m_activeRequests->erase(type); };
    1566              : 
    1567            1 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
    1568              : }
    1569              : 
    1570            2 : void MediaPipelineServerInternal::notifyQos(MediaSourceType mediaSourceType, const QosInfo &qosInfo)
    1571              : {
    1572            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1573              : 
    1574            2 :     auto task = [&, mediaSourceType, qosInfo]()
    1575              :     {
    1576            2 :         if (m_mediaPipelineClient)
    1577              :         {
    1578            2 :             const auto kSourceIter = m_attachedSources.find(mediaSourceType);
    1579            2 :             if (m_attachedSources.cend() == kSourceIter)
    1580              :             {
    1581            1 :                 RIALTO_SERVER_LOG_WARN("Qos notification failed - sourceId not found for %s",
    1582              :                                        common::convertMediaSourceType(mediaSourceType));
    1583            1 :                 return;
    1584              :             }
    1585            1 :             m_mediaPipelineClient->notifyQos(kSourceIter->second, qosInfo);
    1586              :         }
    1587            2 :     };
    1588              : 
    1589            2 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
    1590              : }
    1591              : 
    1592            0 : void MediaPipelineServerInternal::notifyBufferUnderflow(MediaSourceType mediaSourceType)
    1593              : {
    1594            0 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1595              : 
    1596            0 :     auto task = [&, mediaSourceType]()
    1597              :     {
    1598            0 :         m_needDataDelayCalculator.resetMediaDataDelay(mediaSourceType);
    1599            0 :         if (m_mediaPipelineClient)
    1600              :         {
    1601            0 :             const auto kSourceIter = m_attachedSources.find(mediaSourceType);
    1602            0 :             if (m_attachedSources.cend() == kSourceIter)
    1603              :             {
    1604            0 :                 RIALTO_SERVER_LOG_WARN("Buffer underflow notification failed - sourceId not found for %s",
    1605              :                                        common::convertMediaSourceType(mediaSourceType));
    1606            0 :                 return;
    1607              :             }
    1608            0 :             m_mediaPipelineClient->notifyBufferUnderflow(kSourceIter->second);
    1609              :         }
    1610            0 :     };
    1611              : 
    1612            0 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
    1613              : }
    1614              : 
    1615            2 : void MediaPipelineServerInternal::notifyFirstFrameReceived(MediaSourceType mediaSourceType)
    1616              : {
    1617            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1618              : 
    1619            2 :     auto task = [&, mediaSourceType]()
    1620              :     {
    1621            2 :         if (m_mediaPipelineClient)
    1622              :         {
    1623            2 :             const auto kSourceIter = m_attachedSources.find(mediaSourceType);
    1624            2 :             if (m_attachedSources.cend() == kSourceIter)
    1625              :             {
    1626            1 :                 RIALTO_SERVER_LOG_WARN("First frame notification failed - sourceId not found for %s",
    1627              :                                        common::convertMediaSourceType(mediaSourceType));
    1628            1 :                 return;
    1629              :             }
    1630            1 :             m_mediaPipelineClient->notifyFirstFrameReceived(kSourceIter->second);
    1631              :         }
    1632            2 :     };
    1633              : 
    1634            2 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
    1635              : }
    1636              : 
    1637            2 : void MediaPipelineServerInternal::notifyPlaybackError(MediaSourceType mediaSourceType, PlaybackError error)
    1638              : {
    1639            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1640              : 
    1641            2 :     auto task = [&, mediaSourceType, error]()
    1642              :     {
    1643            2 :         if (m_mediaPipelineClient)
    1644              :         {
    1645            2 :             const auto kSourceIter = m_attachedSources.find(mediaSourceType);
    1646            2 :             if (m_attachedSources.cend() == kSourceIter)
    1647              :             {
    1648            1 :                 RIALTO_SERVER_LOG_WARN("Playback error notification failed - sourceId not found for %s",
    1649              :                                        common::convertMediaSourceType(mediaSourceType));
    1650            1 :                 return;
    1651              :             }
    1652            1 :             m_mediaPipelineClient->notifyPlaybackError(kSourceIter->second, error);
    1653              :         }
    1654            2 :     };
    1655              : 
    1656            2 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
    1657              : }
    1658              : 
    1659            2 : void MediaPipelineServerInternal::notifySourceFlushed(MediaSourceType mediaSourceType)
    1660              : {
    1661            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1662              : 
    1663            2 :     auto task = [&, mediaSourceType]()
    1664              :     {
    1665            2 :         if (m_mediaPipelineClient)
    1666              :         {
    1667            2 :             const auto kSourceIter = m_attachedSources.find(mediaSourceType);
    1668            2 :             if (m_attachedSources.cend() == kSourceIter)
    1669              :             {
    1670            1 :                 RIALTO_SERVER_LOG_WARN("Source flushed notification failed - sourceId not found for: %s",
    1671              :                                        common::convertMediaSourceType(mediaSourceType));
    1672            1 :                 return;
    1673              :             }
    1674            1 :             m_mediaPipelineClient->notifySourceFlushed(kSourceIter->second);
    1675            1 :             RIALTO_SERVER_LOG_DEBUG("%s source flushed", common::convertMediaSourceType(mediaSourceType));
    1676              :         }
    1677            1 :         m_needDataDelayCalculator.resetMediaDataDelay(mediaSourceType);
    1678            2 :     };
    1679              : 
    1680            2 :     m_mainThread->enqueueTask(m_mainThreadClientId, task);
    1681              : }
    1682              : 
    1683            0 : void MediaPipelineServerInternal::notifyPlaybackInfo(const PlaybackInfo &playbackInfo)
    1684              : {
    1685            0 :     if (m_mediaPipelineClient)
    1686              :     {
    1687            0 :         m_mediaPipelineClient->notifyPlaybackInfo(playbackInfo);
    1688              :     }
    1689              : }
    1690              : 
    1691            8 : void MediaPipelineServerInternal::scheduleNotifyNeedMediaData(MediaSourceType mediaSourceType)
    1692              : {
    1693            8 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1694            8 :     auto timer = m_needMediaDataTimers.find(mediaSourceType);
    1695            8 :     if (m_needMediaDataTimers.end() != timer && timer->second && timer->second->isActive())
    1696              :     {
    1697            1 :         RIALTO_SERVER_LOG_DEBUG("Skip scheduling need media data for %s - it is already scheduled",
    1698              :                                 common::convertMediaSourceType(mediaSourceType));
    1699            1 :         return;
    1700              :     }
    1701              : 
    1702            7 :     m_needMediaDataTimers[mediaSourceType] =
    1703            7 :         m_timerFactory
    1704           21 :             ->createTimer(getNeedMediaDataTimeout(mediaSourceType),
    1705           14 :                           [this, mediaSourceType]()
    1706              :                           {
    1707            1 :                               m_mainThread
    1708            2 :                                   ->enqueueTask(m_mainThreadClientId,
    1709            1 :                                                 [this, mediaSourceType]()
    1710              :                                                 {
    1711            1 :                                                     m_needMediaDataTimers.erase(mediaSourceType);
    1712            1 :                                                     if (!notifyNeedMediaDataInternal(mediaSourceType))
    1713              :                                                     {
    1714            0 :                                                         RIALTO_SERVER_LOG_WARN("Scheduled Need media data sending "
    1715              :                                                                                "failed for: %s. Scheduling again...",
    1716              :                                                                                common::convertMediaSourceType(
    1717              :                                                                                    mediaSourceType));
    1718            0 :                                                         scheduleNotifyNeedMediaData(mediaSourceType);
    1719              :                                                     }
    1720              :                                                     else
    1721              :                                                     {
    1722            1 :                                                         m_needDataDelayCalculator.increaseNeedMediaDataDelay(
    1723              :                                                             mediaSourceType);
    1724              :                                                     }
    1725            1 :                                                 });
    1726            8 :                           });
    1727              : }
    1728              : 
    1729            7 : std::chrono::milliseconds MediaPipelineServerInternal::getNeedMediaDataTimeout(MediaSourceType mediaSourceType)
    1730              : {
    1731            7 :     constexpr std::chrono::milliseconds kNeedMediaDataResendTimeMsForLowLatency{5};
    1732            7 :     if ((mediaSourceType == MediaSourceType::VIDEO && m_IsLowLatencyVideoPlayer) ||
    1733            1 :         (mediaSourceType == MediaSourceType::AUDIO && m_IsLowLatencyAudioPlayer))
    1734              :     {
    1735            2 :         return kNeedMediaDataResendTimeMsForLowLatency;
    1736              :     }
    1737            5 :     return m_needDataDelayCalculator.getNeedMediaDataDelay(mediaSourceType);
    1738              : }
    1739              : }; // namespace firebolt::rialto::server
        

Generated by: LCOV version 2.0-1