LCOV - code coverage report
Current view: top level - media/server/main/source - MediaPipelineServerInternal.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.0 % 868 816
Test Date: 2026-08-10 07:51:03 Functions: 97.2 % 180 175

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

Generated by: LCOV version 2.0-1