LCOV - code coverage report
Current view: top level - media/client/ipc/source - MediaPipelineIpc.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.9 % 1077 925
Test Date: 2026-06-17 06:35:35 Functions: 90.8 % 76 69

            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              : #include "MediaPipelineIpc.h"
      20              : #include "RialtoClientLogging.h"
      21              : #include "RialtoCommonIpc.h"
      22              : #include "mediapipelinemodule.pb.h"
      23              : #include <IMediaPipeline.h>
      24              : #include <unordered_map>
      25              : 
      26              : namespace firebolt::rialto::client
      27              : {
      28              : std::weak_ptr<IMediaPipelineIpcFactory> MediaPipelineIpcFactory::m_factory;
      29              : 
      30            1 : std::shared_ptr<IMediaPipelineIpcFactory> IMediaPipelineIpcFactory::getFactory()
      31              : {
      32            1 :     std::shared_ptr<IMediaPipelineIpcFactory> factory = MediaPipelineIpcFactory::m_factory.lock();
      33              : 
      34            1 :     if (!factory)
      35              :     {
      36              :         try
      37              :         {
      38            1 :             factory = std::make_shared<MediaPipelineIpcFactory>();
      39              :         }
      40            0 :         catch (const std::exception &e)
      41              :         {
      42            0 :             RIALTO_CLIENT_LOG_ERROR("Failed to create the media player ipc factory, reason: %s", e.what());
      43              :         }
      44              : 
      45            1 :         MediaPipelineIpcFactory::m_factory = factory;
      46              :     }
      47              : 
      48            1 :     return factory;
      49              : }
      50              : 
      51            1 : std::unique_ptr<IMediaPipelineIpc> MediaPipelineIpcFactory::createMediaPipelineIpc(
      52              :     IMediaPipelineIpcClient *client, const VideoRequirements &videoRequirements, std::weak_ptr<IIpcClient> ipcClientParam)
      53              : {
      54            1 :     std::unique_ptr<IMediaPipelineIpc> mediaPipelineIpc;
      55              :     try
      56              :     {
      57            1 :         std::shared_ptr<IIpcClient> ipcClient = ipcClientParam.lock();
      58              :         mediaPipelineIpc =
      59            3 :             std::make_unique<MediaPipelineIpc>(client, videoRequirements,
      60            2 :                                                ipcClient ? *ipcClient : IIpcClientAccessor::instance().getIpcClient(),
      61            3 :                                                firebolt::rialto::common::IEventThreadFactory::createFactory());
      62            1 :     }
      63            0 :     catch (const std::exception &e)
      64              :     {
      65            0 :         RIALTO_CLIENT_LOG_ERROR("Failed to create the media player ipc, reason: %s", e.what());
      66              :     }
      67              : 
      68            1 :     return mediaPipelineIpc;
      69              : }
      70              : 
      71          184 : MediaPipelineIpc::MediaPipelineIpc(IMediaPipelineIpcClient *client, const VideoRequirements &videoRequirements,
      72              :                                    IIpcClient &ipcClient,
      73          184 :                                    const std::shared_ptr<common::IEventThreadFactory> &eventThreadFactory)
      74          184 :     : IpcModule(ipcClient), m_mediaPipelineIpcClient(client),
      75          368 :       m_eventThread(eventThreadFactory->createEventThread("rialto-media-player-events"))
      76              : {
      77          184 :     if (!attachChannel())
      78              :     {
      79            4 :         throw std::runtime_error("Failed attach to the ipc channel");
      80              :     }
      81              : 
      82              :     // create media player session
      83          180 :     if (!createSession(videoRequirements))
      84              :     {
      85            1 :         detachChannel();
      86            1 :         throw std::runtime_error("Could not create the media player session");
      87              :     }
      88          199 : }
      89              : 
      90          358 : MediaPipelineIpc::~MediaPipelineIpc()
      91              : {
      92              :     // destroy media player session
      93          179 :     destroySession();
      94              : 
      95              :     // detach the Ipc channel
      96          179 :     detachChannel();
      97              : 
      98              :     // destroy the thread processing async notifications
      99          179 :     m_eventThread.reset();
     100          358 : }
     101              : 
     102          254 : bool MediaPipelineIpc::createRpcStubs(const std::shared_ptr<ipc::IChannel> &ipcChannel)
     103              : {
     104          254 :     m_mediaPipelineStub = std::make_unique<::firebolt::rialto::MediaPipelineModule_Stub>(ipcChannel.get());
     105          254 :     if (!m_mediaPipelineStub)
     106              :     {
     107            0 :         return false;
     108              :     }
     109          254 :     return true;
     110              : }
     111              : 
     112          254 : bool MediaPipelineIpc::subscribeToEvents(const std::shared_ptr<ipc::IChannel> &ipcChannel)
     113              : {
     114          254 :     if (!ipcChannel)
     115              :     {
     116            0 :         return false;
     117              :     }
     118              : 
     119          508 :     int eventTag = ipcChannel->subscribe<firebolt::rialto::PlaybackStateChangeEvent>(
     120          254 :         [this](const std::shared_ptr<firebolt::rialto::PlaybackStateChangeEvent> &event)
     121          256 :         { m_eventThread->add(&MediaPipelineIpc::onPlaybackStateUpdated, this, event); });
     122          254 :     if (eventTag < 0)
     123            0 :         return false;
     124          254 :     m_eventTags.push_back(eventTag);
     125              : 
     126          508 :     eventTag = ipcChannel->subscribe<firebolt::rialto::PositionChangeEvent>(
     127          254 :         [this](const std::shared_ptr<firebolt::rialto::PositionChangeEvent> &event)
     128            0 :         { m_eventThread->add(&MediaPipelineIpc::onPositionUpdated, this, event); });
     129          254 :     if (eventTag < 0)
     130            1 :         return false;
     131          253 :     m_eventTags.push_back(eventTag);
     132              : 
     133          506 :     eventTag = ipcChannel->subscribe<firebolt::rialto::NetworkStateChangeEvent>(
     134          253 :         [this](const std::shared_ptr<firebolt::rialto::NetworkStateChangeEvent> &event)
     135            2 :         { m_eventThread->add(&MediaPipelineIpc::onNetworkStateUpdated, this, event); });
     136          253 :     if (eventTag < 0)
     137            0 :         return false;
     138          253 :     m_eventTags.push_back(eventTag);
     139              : 
     140          506 :     eventTag = ipcChannel->subscribe<firebolt::rialto::NeedMediaDataEvent>(
     141          253 :         [this](const std::shared_ptr<firebolt::rialto::NeedMediaDataEvent> &event)
     142            3 :         { m_eventThread->add(&MediaPipelineIpc::onNeedMediaData, this, event); });
     143          253 :     if (eventTag < 0)
     144            0 :         return false;
     145          253 :     m_eventTags.push_back(eventTag);
     146              : 
     147          506 :     eventTag = ipcChannel->subscribe<firebolt::rialto::QosEvent>(
     148          253 :         [this](const std::shared_ptr<firebolt::rialto::QosEvent> &event)
     149            2 :         { m_eventThread->add(&MediaPipelineIpc::onQos, this, event); });
     150          253 :     if (eventTag < 0)
     151            0 :         return false;
     152          253 :     m_eventTags.push_back(eventTag);
     153              : 
     154          506 :     eventTag = ipcChannel->subscribe<firebolt::rialto::BufferUnderflowEvent>(
     155          253 :         [this](const std::shared_ptr<firebolt::rialto::BufferUnderflowEvent> &event)
     156            0 :         { m_eventThread->add(&MediaPipelineIpc::onBufferUnderflow, this, event); });
     157          253 :     if (eventTag < 0)
     158            0 :         return false;
     159          253 :     m_eventTags.push_back(eventTag);
     160              : 
     161          506 :     eventTag = ipcChannel->subscribe<firebolt::rialto::FirstFrameReceivedEvent>(
     162          253 :         [this](const std::shared_ptr<firebolt::rialto::FirstFrameReceivedEvent> &event)
     163            2 :         { m_eventThread->add(&MediaPipelineIpc::onFirstFrameReceived, this, event); });
     164          253 :     if (eventTag < 0)
     165            0 :         return false;
     166          253 :     m_eventTags.push_back(eventTag);
     167              : 
     168          506 :     eventTag = ipcChannel->subscribe<firebolt::rialto::PlaybackErrorEvent>(
     169          253 :         [this](const std::shared_ptr<firebolt::rialto::PlaybackErrorEvent> &event)
     170            2 :         { m_eventThread->add(&MediaPipelineIpc::onPlaybackError, this, event); });
     171          253 :     if (eventTag < 0)
     172            0 :         return false;
     173          253 :     m_eventTags.push_back(eventTag);
     174              : 
     175          506 :     eventTag = ipcChannel->subscribe<firebolt::rialto::SourceFlushedEvent>(
     176          253 :         [this](const std::shared_ptr<firebolt::rialto::SourceFlushedEvent> &event)
     177            2 :         { m_eventThread->add(&MediaPipelineIpc::onSourceFlushed, this, event); });
     178          253 :     if (eventTag < 0)
     179            0 :         return false;
     180          253 :     m_eventTags.push_back(eventTag);
     181              : 
     182          506 :     eventTag = ipcChannel->subscribe<firebolt::rialto::PlaybackInfoEvent>(
     183          253 :         [this](const std::shared_ptr<firebolt::rialto::PlaybackInfoEvent> &event)
     184            1 :         { m_eventThread->add(&MediaPipelineIpc::onPlaybackInfo, this, event); });
     185          253 :     if (eventTag < 0)
     186            0 :         return false;
     187          253 :     m_eventTags.push_back(eventTag);
     188              : 
     189          253 :     return true;
     190              : }
     191              : 
     192            4 : bool MediaPipelineIpc::load(MediaType type, const std::string &mimeType, const std::string &url, bool isLive)
     193              : {
     194            4 :     if (!reattachChannelIfRequired())
     195              :     {
     196            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     197            1 :         return false;
     198              :     }
     199              : 
     200            3 :     firebolt::rialto::LoadRequest request;
     201              : 
     202            3 :     request.set_session_id(m_sessionId);
     203            3 :     request.set_type(convertLoadRequestMediaType(type));
     204              :     request.set_mime_type(mimeType);
     205              :     request.set_url(url);
     206            3 :     request.set_is_live(isLive);
     207              : 
     208            3 :     firebolt::rialto::LoadResponse response;
     209            3 :     auto ipcController = m_ipc.createRpcController();
     210            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     211            3 :     m_mediaPipelineStub->load(ipcController.get(), &request, &response, blockingClosure.get());
     212              : 
     213              :     // wait for the call to complete
     214            3 :     blockingClosure->wait();
     215              : 
     216              :     // check the result
     217            3 :     if (ipcController->Failed())
     218              :     {
     219            1 :         RIALTO_CLIENT_LOG_ERROR("failed to load media due to '%s'", ipcController->ErrorText().c_str());
     220            1 :         return false;
     221              :     }
     222              : 
     223            2 :     return true;
     224            3 : }
     225              : 
     226           14 : bool MediaPipelineIpc::attachSource(const std::unique_ptr<IMediaPipeline::MediaSource> &source, int32_t &sourceId)
     227              : {
     228           14 :     if (!reattachChannelIfRequired())
     229              :     {
     230            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     231            1 :         return false;
     232              :     }
     233              : 
     234           13 :     firebolt::rialto::AttachSourceRequest request;
     235              : 
     236           13 :     request.set_session_id(m_sessionId);
     237           13 :     request.set_switch_source(false);
     238           13 :     if (!buildAttachSourceRequest(request, source))
     239              :     {
     240            5 :         RIALTO_CLIENT_LOG_ERROR("Failed to parse source");
     241            5 :         return false;
     242              :     }
     243              : 
     244            8 :     firebolt::rialto::AttachSourceResponse response;
     245            8 :     auto ipcController = m_ipc.createRpcController();
     246            8 :     auto blockingClosure = m_ipc.createBlockingClosure();
     247            8 :     m_mediaPipelineStub->attachSource(ipcController.get(), &request, &response, blockingClosure.get());
     248              : 
     249              :     // wait for the call to complete
     250            8 :     blockingClosure->wait();
     251              : 
     252              :     // check the result
     253            8 :     if (ipcController->Failed())
     254              :     {
     255            1 :         RIALTO_CLIENT_LOG_ERROR("failed to attach source due to '%s'", ipcController->ErrorText().c_str());
     256            1 :         return false;
     257              :     }
     258              : 
     259            7 :     sourceId = response.source_id();
     260              : 
     261            7 :     return true;
     262           13 : }
     263              : 
     264            4 : bool MediaPipelineIpc::removeSource(int32_t sourceId)
     265              : {
     266            4 :     if (!reattachChannelIfRequired())
     267              :     {
     268            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     269            1 :         return false;
     270              :     }
     271              : 
     272            3 :     firebolt::rialto::RemoveSourceRequest request;
     273              : 
     274            3 :     request.set_session_id(m_sessionId);
     275            3 :     request.set_source_id(sourceId);
     276              : 
     277            3 :     firebolt::rialto::RemoveSourceResponse response;
     278            3 :     auto ipcController = m_ipc.createRpcController();
     279            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     280            3 :     m_mediaPipelineStub->removeSource(ipcController.get(), &request, &response, blockingClosure.get());
     281              : 
     282              :     // wait for the call to complete
     283            3 :     blockingClosure->wait();
     284              : 
     285              :     // check the result
     286            3 :     if (ipcController->Failed())
     287              :     {
     288            1 :         RIALTO_CLIENT_LOG_ERROR("failed to remove source due to '%s'", ipcController->ErrorText().c_str());
     289            1 :         return false;
     290              :     }
     291              : 
     292            2 :     return true;
     293            3 : }
     294              : 
     295            4 : bool MediaPipelineIpc::allSourcesAttached()
     296              : {
     297            4 :     if (!reattachChannelIfRequired())
     298              :     {
     299            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     300            1 :         return false;
     301              :     }
     302              : 
     303            3 :     firebolt::rialto::AllSourcesAttachedRequest request;
     304            3 :     request.set_session_id(m_sessionId);
     305              : 
     306            3 :     firebolt::rialto::AllSourcesAttachedResponse response;
     307            3 :     auto ipcController = m_ipc.createRpcController();
     308            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     309            3 :     m_mediaPipelineStub->allSourcesAttached(ipcController.get(), &request, &response, blockingClosure.get());
     310              : 
     311              :     // wait for the call to complete
     312            3 :     blockingClosure->wait();
     313              : 
     314              :     // check the result
     315            3 :     if (ipcController->Failed())
     316              :     {
     317            1 :         RIALTO_CLIENT_LOG_ERROR("failed to notify about all sources attached due to '%s'",
     318              :                                 ipcController->ErrorText().c_str());
     319            1 :         return false;
     320              :     }
     321              : 
     322            2 :     return true;
     323            3 : }
     324              : 
     325            4 : bool MediaPipelineIpc::setVideoWindow(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
     326              : {
     327            4 :     if (!reattachChannelIfRequired())
     328              :     {
     329            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     330            1 :         return false;
     331              :     }
     332              : 
     333            3 :     firebolt::rialto::SetVideoWindowRequest request;
     334              : 
     335            3 :     request.set_session_id(m_sessionId);
     336            3 :     request.set_x(x);
     337            3 :     request.set_y(y);
     338            3 :     request.set_width(width);
     339            3 :     request.set_height(height);
     340              : 
     341            3 :     firebolt::rialto::SetVideoWindowResponse response;
     342            3 :     auto ipcController = m_ipc.createRpcController();
     343            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     344            3 :     m_mediaPipelineStub->setVideoWindow(ipcController.get(), &request, &response, blockingClosure.get());
     345              : 
     346              :     // wait for the call to complete
     347            3 :     blockingClosure->wait();
     348              : 
     349              :     // check the result
     350            3 :     if (ipcController->Failed())
     351              :     {
     352            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set the video window due to '%s'", ipcController->ErrorText().c_str());
     353            1 :         return false;
     354              :     }
     355              : 
     356            2 :     return true;
     357            3 : }
     358              : 
     359            4 : bool MediaPipelineIpc::play(bool &async)
     360              : {
     361            4 :     if (!reattachChannelIfRequired())
     362              :     {
     363            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     364            1 :         return false;
     365              :     }
     366              : 
     367            3 :     firebolt::rialto::PlayRequest request;
     368              : 
     369            3 :     request.set_session_id(m_sessionId);
     370              : 
     371            3 :     firebolt::rialto::PlayResponse response;
     372            3 :     auto ipcController = m_ipc.createRpcController();
     373            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     374            3 :     m_mediaPipelineStub->play(ipcController.get(), &request, &response, blockingClosure.get());
     375              : 
     376              :     // wait for the call to complete
     377            3 :     blockingClosure->wait();
     378              : 
     379              :     // check the result
     380            3 :     if (ipcController->Failed())
     381              :     {
     382            1 :         RIALTO_CLIENT_LOG_ERROR("failed to play due to '%s'", ipcController->ErrorText().c_str());
     383            1 :         return false;
     384              :     }
     385              : 
     386            2 :     async = response.async();
     387              : 
     388            2 :     return true;
     389            3 : }
     390              : 
     391            4 : bool MediaPipelineIpc::pause()
     392              : {
     393            4 :     if (!reattachChannelIfRequired())
     394              :     {
     395            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     396            1 :         return false;
     397              :     }
     398              : 
     399            3 :     firebolt::rialto::PauseRequest request;
     400              : 
     401            3 :     request.set_session_id(m_sessionId);
     402              : 
     403            3 :     firebolt::rialto::PauseResponse response;
     404            3 :     auto ipcController = m_ipc.createRpcController();
     405            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     406            3 :     m_mediaPipelineStub->pause(ipcController.get(), &request, &response, blockingClosure.get());
     407              : 
     408              :     // wait for the call to complete
     409            3 :     blockingClosure->wait();
     410              : 
     411              :     // check the result
     412            3 :     if (ipcController->Failed())
     413              :     {
     414            1 :         RIALTO_CLIENT_LOG_ERROR("failed to pause due to '%s'", ipcController->ErrorText().c_str());
     415            1 :         return false;
     416              :     }
     417              : 
     418            2 :     return true;
     419            3 : }
     420              : 
     421            0 : bool MediaPipelineIpc::stop()
     422              : {
     423            0 :     if (!reattachChannelIfRequired())
     424              :     {
     425            0 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     426            0 :         return false;
     427              :     }
     428              : 
     429            0 :     firebolt::rialto::StopRequest request;
     430              : 
     431            0 :     request.set_session_id(m_sessionId);
     432              : 
     433            0 :     firebolt::rialto::StopResponse response;
     434            0 :     auto ipcController = m_ipc.createRpcController();
     435            0 :     auto blockingClosure = m_ipc.createBlockingClosure();
     436            0 :     m_mediaPipelineStub->stop(ipcController.get(), &request, &response, blockingClosure.get());
     437              : 
     438              :     // wait for the call to complete
     439            0 :     blockingClosure->wait();
     440              : 
     441              :     // check the result
     442            0 :     if (ipcController->Failed())
     443              :     {
     444            0 :         RIALTO_CLIENT_LOG_ERROR("failed to stop due to '%s'", ipcController->ErrorText().c_str());
     445            0 :         return false;
     446              :     }
     447              : 
     448            0 :     return true;
     449              : }
     450              : 
     451            4 : bool MediaPipelineIpc::haveData(MediaSourceStatus status, uint32_t numFrames, uint32_t requestId)
     452              : {
     453            4 :     if (!reattachChannelIfRequired())
     454              :     {
     455            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     456            1 :         return false;
     457              :     }
     458              : 
     459            3 :     firebolt::rialto::HaveDataRequest request;
     460              : 
     461            3 :     request.set_session_id(m_sessionId);
     462            3 :     request.set_status(convertHaveDataRequestMediaSourceStatus(status));
     463            3 :     request.set_num_frames(numFrames);
     464            3 :     request.set_request_id(requestId);
     465              : 
     466            3 :     firebolt::rialto::HaveDataResponse response;
     467            3 :     auto ipcController = m_ipc.createRpcController();
     468            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     469            3 :     m_mediaPipelineStub->haveData(ipcController.get(), &request, &response, blockingClosure.get());
     470              : 
     471              :     // wait for the call to complete
     472            3 :     blockingClosure->wait();
     473              : 
     474              :     // check the result
     475            3 :     if (ipcController->Failed())
     476              :     {
     477            1 :         RIALTO_CLIENT_LOG_ERROR("failed to stop due to '%s'", ipcController->ErrorText().c_str());
     478            1 :         return false;
     479              :     }
     480              : 
     481            2 :     return true;
     482            3 : }
     483              : 
     484            4 : bool MediaPipelineIpc::setPosition(int64_t position)
     485              : {
     486            4 :     if (!reattachChannelIfRequired())
     487              :     {
     488            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     489            1 :         return false;
     490              :     }
     491              : 
     492            3 :     firebolt::rialto::SetPositionRequest request;
     493              : 
     494            3 :     request.set_session_id(m_sessionId);
     495            3 :     request.set_position(position);
     496              : 
     497            3 :     firebolt::rialto::SetPositionResponse response;
     498            3 :     auto ipcController = m_ipc.createRpcController();
     499            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     500            3 :     m_mediaPipelineStub->setPosition(ipcController.get(), &request, &response, blockingClosure.get());
     501              : 
     502              :     // wait for the call to complete
     503            3 :     blockingClosure->wait();
     504              : 
     505              :     // check the result
     506            3 :     if (ipcController->Failed())
     507              :     {
     508            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set position due to '%s'", ipcController->ErrorText().c_str());
     509            1 :         return false;
     510              :     }
     511              : 
     512            2 :     return true;
     513            3 : }
     514              : 
     515            4 : bool MediaPipelineIpc::getPosition(int64_t &position)
     516              : {
     517            4 :     if (!reattachChannelIfRequired())
     518              :     {
     519            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     520            1 :         return false;
     521              :     }
     522              : 
     523            3 :     firebolt::rialto::GetPositionRequest request;
     524              : 
     525            3 :     request.set_session_id(m_sessionId);
     526              : 
     527            3 :     firebolt::rialto::GetPositionResponse response;
     528            3 :     auto ipcController = m_ipc.createRpcController();
     529            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     530            3 :     m_mediaPipelineStub->getPosition(ipcController.get(), &request, &response, blockingClosure.get());
     531              : 
     532              :     // wait for the call to complete
     533            3 :     blockingClosure->wait();
     534              : 
     535              :     // check the result
     536            3 :     if (ipcController->Failed())
     537              :     {
     538            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get position due to '%s'", ipcController->ErrorText().c_str());
     539            1 :         return false;
     540              :     }
     541              : 
     542            2 :     position = response.position();
     543            2 :     return true;
     544            3 : }
     545              : 
     546            4 : bool MediaPipelineIpc::getDuration(int64_t &duration)
     547              : {
     548            4 :     if (!reattachChannelIfRequired())
     549              :     {
     550            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     551            1 :         return false;
     552              :     }
     553              : 
     554            3 :     firebolt::rialto::GetDurationRequest request;
     555              : 
     556            3 :     request.set_session_id(m_sessionId);
     557              : 
     558            3 :     firebolt::rialto::GetDurationResponse response;
     559            3 :     auto ipcController = m_ipc.createRpcController();
     560            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     561            3 :     m_mediaPipelineStub->getDuration(ipcController.get(), &request, &response, blockingClosure.get());
     562              : 
     563              :     // wait for the call to complete
     564            3 :     blockingClosure->wait();
     565              : 
     566              :     // check the result
     567            3 :     if (ipcController->Failed())
     568              :     {
     569            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get duration due to '%s'", ipcController->ErrorText().c_str());
     570            1 :         return false;
     571              :     }
     572              : 
     573            2 :     duration = response.duration();
     574            2 :     return true;
     575            3 : }
     576              : 
     577            4 : bool MediaPipelineIpc::setImmediateOutput(int32_t sourceId, bool immediateOutput)
     578              : {
     579            4 :     if (!reattachChannelIfRequired())
     580              :     {
     581            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     582            1 :         return false;
     583              :     }
     584              : 
     585            3 :     firebolt::rialto::SetImmediateOutputRequest request;
     586              : 
     587            3 :     request.set_session_id(m_sessionId);
     588            3 :     request.set_source_id(sourceId);
     589            3 :     request.set_immediate_output(immediateOutput);
     590              : 
     591            3 :     firebolt::rialto::SetImmediateOutputResponse response;
     592            3 :     auto ipcController = m_ipc.createRpcController();
     593            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     594            3 :     m_mediaPipelineStub->setImmediateOutput(ipcController.get(), &request, &response, blockingClosure.get());
     595              : 
     596              :     // wait for the call to complete
     597            3 :     blockingClosure->wait();
     598              : 
     599              :     // check the result
     600            3 :     if (ipcController->Failed())
     601              :     {
     602            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set immediate-output due to '%s'", ipcController->ErrorText().c_str());
     603            1 :         return false;
     604              :     }
     605              : 
     606            2 :     return true;
     607            3 : }
     608              : 
     609            4 : bool MediaPipelineIpc::getImmediateOutput(int32_t sourceId, bool &immediateOutput)
     610              : {
     611            4 :     if (!reattachChannelIfRequired())
     612              :     {
     613            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     614            1 :         return false;
     615              :     }
     616              : 
     617            3 :     firebolt::rialto::GetImmediateOutputRequest request;
     618              : 
     619            3 :     request.set_session_id(m_sessionId);
     620            3 :     request.set_source_id(sourceId);
     621              : 
     622            3 :     firebolt::rialto::GetImmediateOutputResponse response;
     623            3 :     auto ipcController = m_ipc.createRpcController();
     624            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     625            3 :     m_mediaPipelineStub->getImmediateOutput(ipcController.get(), &request, &response, blockingClosure.get());
     626              : 
     627              :     // wait for the call to complete
     628            3 :     blockingClosure->wait();
     629              : 
     630              :     // check the result
     631            3 :     if (ipcController->Failed())
     632              :     {
     633            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get immediate-output due to '%s'", ipcController->ErrorText().c_str());
     634            1 :         return false;
     635              :     }
     636              :     else
     637              :     {
     638            2 :         immediateOutput = response.immediate_output();
     639              :     }
     640              : 
     641            2 :     return true;
     642            3 : }
     643              : 
     644            4 : bool MediaPipelineIpc::getStats(int32_t sourceId, uint64_t &renderedFrames, uint64_t &droppedFrames)
     645              : {
     646            4 :     if (!reattachChannelIfRequired())
     647              :     {
     648            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     649            1 :         return false;
     650              :     }
     651              : 
     652            3 :     firebolt::rialto::GetStatsRequest request;
     653              : 
     654            3 :     request.set_session_id(m_sessionId);
     655            3 :     request.set_source_id(sourceId);
     656              : 
     657            3 :     firebolt::rialto::GetStatsResponse response;
     658            3 :     auto ipcController = m_ipc.createRpcController();
     659            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     660            3 :     m_mediaPipelineStub->getStats(ipcController.get(), &request, &response, blockingClosure.get());
     661              : 
     662              :     // wait for the call to complete
     663            3 :     blockingClosure->wait();
     664              : 
     665              :     // check the result
     666            3 :     if (ipcController->Failed())
     667              :     {
     668            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get stats due to '%s'", ipcController->ErrorText().c_str());
     669            1 :         return false;
     670              :     }
     671              : 
     672            2 :     renderedFrames = response.rendered_frames();
     673            2 :     droppedFrames = response.dropped_frames();
     674            2 :     return true;
     675            3 : }
     676              : 
     677            4 : bool MediaPipelineIpc::setPlaybackRate(double rate)
     678              : {
     679            4 :     if (!reattachChannelIfRequired())
     680              :     {
     681            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     682            1 :         return false;
     683              :     }
     684              : 
     685            3 :     firebolt::rialto::SetPlaybackRateRequest request;
     686              : 
     687            3 :     request.set_session_id(m_sessionId);
     688            3 :     request.set_rate(rate);
     689              : 
     690            3 :     firebolt::rialto::SetPlaybackRateResponse response;
     691            3 :     auto ipcController = m_ipc.createRpcController();
     692            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     693            3 :     m_mediaPipelineStub->setPlaybackRate(ipcController.get(), &request, &response, blockingClosure.get());
     694              : 
     695              :     // wait for the call to complete
     696            3 :     blockingClosure->wait();
     697              : 
     698              :     // check the result
     699            3 :     if (ipcController->Failed())
     700              :     {
     701            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set playback rate due to '%s'", ipcController->ErrorText().c_str());
     702            1 :         return false;
     703              :     }
     704              : 
     705            2 :     return true;
     706            3 : }
     707              : 
     708            4 : bool MediaPipelineIpc::renderFrame()
     709              : {
     710            4 :     if (!reattachChannelIfRequired())
     711              :     {
     712            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     713            1 :         return false;
     714              :     }
     715              : 
     716            3 :     firebolt::rialto::RenderFrameRequest request;
     717            3 :     request.set_session_id(m_sessionId);
     718              : 
     719            3 :     firebolt::rialto::RenderFrameResponse response;
     720            3 :     auto ipcController = m_ipc.createRpcController();
     721            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     722            3 :     m_mediaPipelineStub->renderFrame(ipcController.get(), &request, &response, blockingClosure.get());
     723              : 
     724              :     // wait for the call to complete
     725            3 :     blockingClosure->wait();
     726              : 
     727              :     // check the result
     728            3 :     if (ipcController->Failed())
     729              :     {
     730            1 :         RIALTO_CLIENT_LOG_ERROR("failed to render frame due to '%s'", ipcController->ErrorText().c_str());
     731            1 :         return false;
     732              :     }
     733              : 
     734            2 :     return true;
     735            3 : }
     736              : 
     737            4 : bool MediaPipelineIpc::setVolume(double targetVolume, uint32_t volumeDuration, EaseType easeType)
     738              : {
     739            4 :     if (!reattachChannelIfRequired())
     740              :     {
     741            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     742            1 :         return false;
     743              :     }
     744              : 
     745            3 :     firebolt::rialto::SetVolumeRequest request;
     746              : 
     747            3 :     request.set_session_id(m_sessionId);
     748            3 :     request.set_volume(targetVolume);
     749            3 :     request.set_volume_duration(volumeDuration);
     750            3 :     request.set_ease_type(convertEaseType(easeType));
     751              : 
     752            3 :     firebolt::rialto::SetVolumeResponse response;
     753            3 :     auto ipcController = m_ipc.createRpcController();
     754            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     755            3 :     m_mediaPipelineStub->setVolume(ipcController.get(), &request, &response, blockingClosure.get());
     756              : 
     757              :     // wait for the call to complete
     758            3 :     blockingClosure->wait();
     759              : 
     760              :     // check the result
     761            3 :     if (ipcController->Failed())
     762              :     {
     763            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set volume due to '%s'", ipcController->ErrorText().c_str());
     764            1 :         return false;
     765              :     }
     766              : 
     767            2 :     return true;
     768            3 : }
     769              : 
     770            4 : bool MediaPipelineIpc::getVolume(double &volume)
     771              : {
     772            4 :     if (!reattachChannelIfRequired())
     773              :     {
     774            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     775            1 :         return false;
     776              :     }
     777              : 
     778            3 :     firebolt::rialto::GetVolumeRequest request;
     779              : 
     780            3 :     request.set_session_id(m_sessionId);
     781              : 
     782            3 :     firebolt::rialto::GetVolumeResponse response;
     783            3 :     auto ipcController = m_ipc.createRpcController();
     784            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     785            3 :     m_mediaPipelineStub->getVolume(ipcController.get(), &request, &response, blockingClosure.get());
     786              : 
     787              :     // wait for the call to complete
     788            3 :     blockingClosure->wait();
     789              : 
     790              :     // check the result
     791            3 :     if (ipcController->Failed())
     792              :     {
     793            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get volume due to '%s'", ipcController->ErrorText().c_str());
     794            1 :         return false;
     795              :     }
     796            2 :     volume = response.volume();
     797              : 
     798            2 :     return true;
     799            3 : }
     800              : 
     801            4 : bool MediaPipelineIpc::setMute(int32_t sourceId, bool mute)
     802              : {
     803            4 :     if (!reattachChannelIfRequired())
     804              :     {
     805            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     806            1 :         return false;
     807              :     }
     808              : 
     809            3 :     firebolt::rialto::SetMuteRequest request;
     810              : 
     811            3 :     request.set_session_id(m_sessionId);
     812            3 :     request.set_mute(mute);
     813            3 :     request.set_source_id(sourceId);
     814              : 
     815            3 :     firebolt::rialto::SetMuteResponse response;
     816            3 :     auto ipcController = m_ipc.createRpcController();
     817            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     818            3 :     m_mediaPipelineStub->setMute(ipcController.get(), &request, &response, blockingClosure.get());
     819              : 
     820              :     // waiting for call to complete
     821            3 :     blockingClosure->wait();
     822              : 
     823              :     // check the result
     824            3 :     if (ipcController->Failed())
     825              :     {
     826            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set mute due to '%s'", ipcController->ErrorText().c_str());
     827            1 :         return false;
     828              :     }
     829              : 
     830            2 :     return true;
     831            3 : }
     832              : 
     833            4 : bool MediaPipelineIpc::getMute(std::int32_t sourceId, bool &mute)
     834              : {
     835            4 :     if (!reattachChannelIfRequired())
     836              :     {
     837            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     838            1 :         return false;
     839              :     }
     840              : 
     841            3 :     firebolt::rialto::GetMuteRequest request;
     842              : 
     843            3 :     request.set_session_id(m_sessionId);
     844            3 :     request.set_source_id(sourceId);
     845              : 
     846            3 :     firebolt::rialto::GetMuteResponse response;
     847            3 :     auto ipcController = m_ipc.createRpcController();
     848            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     849            3 :     m_mediaPipelineStub->getMute(ipcController.get(), &request, &response, blockingClosure.get());
     850              : 
     851              :     // wait for the call to complete
     852            3 :     blockingClosure->wait();
     853              : 
     854              :     // check the result
     855            3 :     if (ipcController->Failed())
     856              :     {
     857            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get mute due to '%s'", ipcController->ErrorText().c_str());
     858            1 :         return false;
     859              :     }
     860              : 
     861            2 :     mute = response.mute();
     862              : 
     863            2 :     return true;
     864            3 : }
     865              : 
     866            4 : bool MediaPipelineIpc::setTextTrackIdentifier(const std::string &textTrackIdentifier)
     867              : {
     868            4 :     if (!reattachChannelIfRequired())
     869              :     {
     870            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     871            1 :         return false;
     872              :     }
     873              : 
     874            3 :     firebolt::rialto::SetTextTrackIdentifierRequest request;
     875              : 
     876            3 :     request.set_session_id(m_sessionId);
     877              :     request.set_text_track_identifier(textTrackIdentifier);
     878              : 
     879            3 :     firebolt::rialto::SetTextTrackIdentifierResponse response;
     880            3 :     auto ipcController = m_ipc.createRpcController();
     881            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     882            3 :     m_mediaPipelineStub->setTextTrackIdentifier(ipcController.get(), &request, &response, blockingClosure.get());
     883              : 
     884              :     // waiting for call to complete
     885            3 :     blockingClosure->wait();
     886              : 
     887              :     // check the result
     888            3 :     if (ipcController->Failed())
     889              :     {
     890            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set text track identifier due to '%s'", ipcController->ErrorText().c_str());
     891            1 :         return false;
     892              :     }
     893              : 
     894            2 :     return true;
     895            3 : }
     896              : 
     897            4 : bool MediaPipelineIpc::getTextTrackIdentifier(std::string &textTrackIdentifier)
     898              : {
     899            4 :     if (!reattachChannelIfRequired())
     900              :     {
     901            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     902            1 :         return false;
     903              :     }
     904              : 
     905            3 :     firebolt::rialto::GetTextTrackIdentifierRequest request;
     906              : 
     907            3 :     request.set_session_id(m_sessionId);
     908              : 
     909            3 :     firebolt::rialto::GetTextTrackIdentifierResponse response;
     910            3 :     auto ipcController = m_ipc.createRpcController();
     911            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     912            3 :     m_mediaPipelineStub->getTextTrackIdentifier(ipcController.get(), &request, &response, blockingClosure.get());
     913              : 
     914              :     // wait for the call to complete
     915            3 :     blockingClosure->wait();
     916              : 
     917              :     // check the result
     918            3 :     if (ipcController->Failed())
     919              :     {
     920            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get mute due to '%s'", ipcController->ErrorText().c_str());
     921            1 :         return false;
     922              :     }
     923              : 
     924            2 :     textTrackIdentifier = response.text_track_identifier();
     925              : 
     926            2 :     return true;
     927            3 : }
     928              : 
     929            4 : bool MediaPipelineIpc::setLowLatency(bool lowLatency)
     930              : {
     931            4 :     if (!reattachChannelIfRequired())
     932              :     {
     933            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     934            1 :         return false;
     935              :     }
     936              : 
     937            3 :     firebolt::rialto::SetLowLatencyRequest request;
     938              : 
     939            3 :     request.set_session_id(m_sessionId);
     940            3 :     request.set_low_latency(lowLatency);
     941              : 
     942            3 :     firebolt::rialto::SetLowLatencyResponse response;
     943            3 :     auto ipcController = m_ipc.createRpcController();
     944            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     945            3 :     m_mediaPipelineStub->setLowLatency(ipcController.get(), &request, &response, blockingClosure.get());
     946              :     // waiting for call to complete
     947            3 :     blockingClosure->wait();
     948              : 
     949              :     // check the result
     950            3 :     if (ipcController->Failed())
     951              :     {
     952            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set low-latency due to '%s'", ipcController->ErrorText().c_str());
     953            1 :         return false;
     954              :     }
     955              : 
     956            2 :     return true;
     957            3 : }
     958              : 
     959            4 : bool MediaPipelineIpc::setSync(bool sync)
     960              : {
     961            4 :     if (!reattachChannelIfRequired())
     962              :     {
     963            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     964            1 :         return false;
     965              :     }
     966              : 
     967            3 :     firebolt::rialto::SetSyncRequest request;
     968              : 
     969            3 :     request.set_session_id(m_sessionId);
     970            3 :     request.set_sync(sync);
     971              : 
     972            3 :     firebolt::rialto::SetSyncResponse response;
     973            3 :     auto ipcController = m_ipc.createRpcController();
     974            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
     975            3 :     m_mediaPipelineStub->setSync(ipcController.get(), &request, &response, blockingClosure.get());
     976              : 
     977              :     // waiting for call to complete
     978            3 :     blockingClosure->wait();
     979              : 
     980              :     // check the result
     981            3 :     if (ipcController->Failed())
     982              :     {
     983            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set sync due to '%s'", ipcController->ErrorText().c_str());
     984            1 :         return false;
     985              :     }
     986              : 
     987            2 :     return true;
     988            3 : }
     989              : 
     990            4 : bool MediaPipelineIpc::getSync(bool &sync)
     991              : {
     992            4 :     if (!reattachChannelIfRequired())
     993              :     {
     994            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
     995            1 :         return false;
     996              :     }
     997              : 
     998            3 :     firebolt::rialto::GetSyncRequest request;
     999              : 
    1000            3 :     request.set_session_id(m_sessionId);
    1001              : 
    1002            3 :     firebolt::rialto::GetSyncResponse response;
    1003            3 :     auto ipcController = m_ipc.createRpcController();
    1004            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1005            3 :     m_mediaPipelineStub->getSync(ipcController.get(), &request, &response, blockingClosure.get());
    1006              : 
    1007              :     // wait for the call to complete
    1008            3 :     blockingClosure->wait();
    1009              : 
    1010              :     // check the result
    1011            3 :     if (ipcController->Failed())
    1012              :     {
    1013            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get sync due to '%s'", ipcController->ErrorText().c_str());
    1014            1 :         return false;
    1015              :     }
    1016              : 
    1017            2 :     sync = response.sync();
    1018              : 
    1019            2 :     return true;
    1020            3 : }
    1021              : 
    1022            4 : bool MediaPipelineIpc::setSyncOff(bool syncOff)
    1023              : {
    1024            4 :     if (!reattachChannelIfRequired())
    1025              :     {
    1026            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1027            1 :         return false;
    1028              :     }
    1029              : 
    1030            3 :     firebolt::rialto::SetSyncOffRequest request;
    1031              : 
    1032            3 :     request.set_session_id(m_sessionId);
    1033            3 :     request.set_sync_off(syncOff);
    1034              : 
    1035            3 :     firebolt::rialto::SetSyncOffResponse response;
    1036            3 :     auto ipcController = m_ipc.createRpcController();
    1037            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1038            3 :     m_mediaPipelineStub->setSyncOff(ipcController.get(), &request, &response, blockingClosure.get());
    1039              : 
    1040              :     // waiting for call to complete
    1041            3 :     blockingClosure->wait();
    1042              : 
    1043              :     // check the result
    1044            3 :     if (ipcController->Failed())
    1045              :     {
    1046            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set sync-off due to '%s'", ipcController->ErrorText().c_str());
    1047            1 :         return false;
    1048              :     }
    1049              : 
    1050            2 :     return true;
    1051            3 : }
    1052              : 
    1053            4 : bool MediaPipelineIpc::setStreamSyncMode(int32_t sourceId, int32_t streamSyncMode)
    1054              : {
    1055            4 :     if (!reattachChannelIfRequired())
    1056              :     {
    1057            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1058            1 :         return false;
    1059              :     }
    1060              : 
    1061            3 :     firebolt::rialto::SetStreamSyncModeRequest request;
    1062              : 
    1063            3 :     request.set_session_id(m_sessionId);
    1064            3 :     request.set_source_id(sourceId);
    1065            3 :     request.set_stream_sync_mode(streamSyncMode);
    1066              : 
    1067            3 :     firebolt::rialto::SetStreamSyncModeResponse response;
    1068            3 :     auto ipcController = m_ipc.createRpcController();
    1069            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1070            3 :     m_mediaPipelineStub->setStreamSyncMode(ipcController.get(), &request, &response, blockingClosure.get());
    1071              : 
    1072              :     // waiting for call to complete
    1073            3 :     blockingClosure->wait();
    1074              : 
    1075              :     // check the result
    1076            3 :     if (ipcController->Failed())
    1077              :     {
    1078            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set stream-sync-mode due to '%s'", ipcController->ErrorText().c_str());
    1079            1 :         return false;
    1080              :     }
    1081              : 
    1082            2 :     return true;
    1083            3 : }
    1084              : 
    1085            4 : bool MediaPipelineIpc::getStreamSyncMode(int32_t &streamSyncMode)
    1086              : {
    1087            4 :     if (!reattachChannelIfRequired())
    1088              :     {
    1089            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1090            1 :         return false;
    1091              :     }
    1092              : 
    1093            3 :     firebolt::rialto::GetStreamSyncModeRequest request;
    1094              : 
    1095            3 :     request.set_session_id(m_sessionId);
    1096              : 
    1097            3 :     firebolt::rialto::GetStreamSyncModeResponse response;
    1098            3 :     auto ipcController = m_ipc.createRpcController();
    1099            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1100            3 :     m_mediaPipelineStub->getStreamSyncMode(ipcController.get(), &request, &response, blockingClosure.get());
    1101              : 
    1102              :     // wait for the call to complete
    1103            3 :     blockingClosure->wait();
    1104              : 
    1105              :     // check the result
    1106            3 :     if (ipcController->Failed())
    1107              :     {
    1108            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get stream-sync-mode due to '%s'", ipcController->ErrorText().c_str());
    1109            1 :         return false;
    1110              :     }
    1111              : 
    1112            2 :     streamSyncMode = response.stream_sync_mode();
    1113              : 
    1114            2 :     return true;
    1115            3 : }
    1116              : 
    1117            4 : bool MediaPipelineIpc::flush(int32_t sourceId, bool resetTime, bool &async)
    1118              : {
    1119            4 :     if (!reattachChannelIfRequired())
    1120              :     {
    1121            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1122            1 :         return false;
    1123              :     }
    1124              : 
    1125            3 :     firebolt::rialto::FlushRequest request;
    1126              : 
    1127            3 :     request.set_session_id(m_sessionId);
    1128            3 :     request.set_source_id(sourceId);
    1129            3 :     request.set_reset_time(resetTime);
    1130              : 
    1131            3 :     firebolt::rialto::FlushResponse response;
    1132            3 :     auto ipcController = m_ipc.createRpcController();
    1133            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1134            3 :     m_mediaPipelineStub->flush(ipcController.get(), &request, &response, blockingClosure.get());
    1135              : 
    1136              :     // wait for the call to complete
    1137            3 :     blockingClosure->wait();
    1138              : 
    1139              :     // check the result
    1140            3 :     if (ipcController->Failed())
    1141              :     {
    1142            1 :         RIALTO_CLIENT_LOG_ERROR("failed to flush due to '%s'", ipcController->ErrorText().c_str());
    1143            1 :         return false;
    1144              :     }
    1145              : 
    1146              :     // Async is true by default
    1147            2 :     async = response.has_async() ? response.async() : true;
    1148              : 
    1149            2 :     return true;
    1150            3 : }
    1151              : 
    1152            4 : bool MediaPipelineIpc::setSourcePosition(int32_t sourceId, int64_t position, bool resetTime, double appliedRate,
    1153              :                                          uint64_t stopPosition)
    1154              : {
    1155            4 :     if (!reattachChannelIfRequired())
    1156              :     {
    1157            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1158            1 :         return false;
    1159              :     }
    1160              : 
    1161            3 :     firebolt::rialto::SetSourcePositionRequest request;
    1162              : 
    1163            3 :     request.set_session_id(m_sessionId);
    1164            3 :     request.set_source_id(sourceId);
    1165            3 :     request.set_position(position);
    1166            3 :     request.set_reset_time(resetTime);
    1167            3 :     request.set_applied_rate(appliedRate);
    1168            3 :     request.set_stop_position(stopPosition);
    1169              : 
    1170            3 :     firebolt::rialto::SetSourcePositionResponse response;
    1171            3 :     auto ipcController = m_ipc.createRpcController();
    1172            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1173            3 :     m_mediaPipelineStub->setSourcePosition(ipcController.get(), &request, &response, blockingClosure.get());
    1174              : 
    1175              :     // wait for the call to complete
    1176            3 :     blockingClosure->wait();
    1177              : 
    1178              :     // check the result
    1179            3 :     if (ipcController->Failed())
    1180              :     {
    1181            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set source position due to '%s'", ipcController->ErrorText().c_str());
    1182            1 :         return false;
    1183              :     }
    1184              : 
    1185            2 :     return true;
    1186            3 : }
    1187              : 
    1188            3 : bool MediaPipelineIpc::setSubtitleOffset(int32_t sourceId, int64_t position)
    1189              : {
    1190            3 :     if (!reattachChannelIfRequired())
    1191              :     {
    1192            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1193            1 :         return false;
    1194              :     }
    1195              : 
    1196            2 :     firebolt::rialto::SetSubtitleOffsetRequest request;
    1197              : 
    1198            2 :     request.set_session_id(m_sessionId);
    1199            2 :     request.set_source_id(sourceId);
    1200            2 :     request.set_position(position);
    1201              : 
    1202            2 :     firebolt::rialto::SetSubtitleOffsetResponse response;
    1203            2 :     auto ipcController = m_ipc.createRpcController();
    1204            2 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1205            2 :     m_mediaPipelineStub->setSubtitleOffset(ipcController.get(), &request, &response, blockingClosure.get());
    1206              : 
    1207              :     // wait for the call to complete
    1208            2 :     blockingClosure->wait();
    1209              : 
    1210              :     // check the result
    1211            2 :     if (ipcController->Failed())
    1212              :     {
    1213            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set subtitle offset due to '%s'", ipcController->ErrorText().c_str());
    1214            1 :         return false;
    1215              :     }
    1216              : 
    1217            1 :     return true;
    1218            2 : }
    1219              : 
    1220            4 : bool MediaPipelineIpc::processAudioGap(int64_t position, uint32_t duration, int64_t discontinuityGap, bool audioAac)
    1221              : {
    1222            4 :     if (!reattachChannelIfRequired())
    1223              :     {
    1224            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1225            1 :         return false;
    1226              :     }
    1227              : 
    1228            3 :     firebolt::rialto::ProcessAudioGapRequest request;
    1229              : 
    1230            3 :     request.set_session_id(m_sessionId);
    1231            3 :     request.set_position(position);
    1232            3 :     request.set_duration(duration);
    1233            3 :     request.set_discontinuity_gap(discontinuityGap);
    1234            3 :     request.set_audio_aac(audioAac);
    1235              : 
    1236            3 :     firebolt::rialto::ProcessAudioGapResponse response;
    1237            3 :     auto ipcController = m_ipc.createRpcController();
    1238            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1239            3 :     m_mediaPipelineStub->processAudioGap(ipcController.get(), &request, &response, blockingClosure.get());
    1240              : 
    1241              :     // wait for the call to complete
    1242            3 :     blockingClosure->wait();
    1243              : 
    1244              :     // check the result
    1245            3 :     if (ipcController->Failed())
    1246              :     {
    1247            1 :         RIALTO_CLIENT_LOG_ERROR("failed to process audio gap due to '%s'", ipcController->ErrorText().c_str());
    1248            1 :         return false;
    1249              :     }
    1250              : 
    1251            2 :     return true;
    1252            3 : }
    1253              : 
    1254            4 : bool MediaPipelineIpc::setBufferingLimit(uint32_t limitBufferingMs)
    1255              : {
    1256            4 :     if (!reattachChannelIfRequired())
    1257              :     {
    1258            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1259            1 :         return false;
    1260              :     }
    1261              : 
    1262            3 :     firebolt::rialto::SetBufferingLimitRequest request;
    1263              : 
    1264            3 :     request.set_session_id(m_sessionId);
    1265            3 :     request.set_limit_buffering_ms(limitBufferingMs);
    1266              : 
    1267            3 :     firebolt::rialto::SetBufferingLimitResponse response;
    1268            3 :     auto ipcController = m_ipc.createRpcController();
    1269            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1270            3 :     m_mediaPipelineStub->setBufferingLimit(ipcController.get(), &request, &response, blockingClosure.get());
    1271              : 
    1272              :     // wait for the call to complete
    1273            3 :     blockingClosure->wait();
    1274              : 
    1275              :     // check the result
    1276            3 :     if (ipcController->Failed())
    1277              :     {
    1278            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set buffering limit due to '%s'", ipcController->ErrorText().c_str());
    1279            1 :         return false;
    1280              :     }
    1281              : 
    1282            2 :     return true;
    1283            3 : }
    1284              : 
    1285            4 : bool MediaPipelineIpc::getBufferingLimit(uint32_t &limitBufferingMs)
    1286              : {
    1287            4 :     if (!reattachChannelIfRequired())
    1288              :     {
    1289            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1290            1 :         return false;
    1291              :     }
    1292              : 
    1293            3 :     firebolt::rialto::GetBufferingLimitRequest request;
    1294              : 
    1295            3 :     request.set_session_id(m_sessionId);
    1296              : 
    1297            3 :     firebolt::rialto::GetBufferingLimitResponse response;
    1298            3 :     auto ipcController = m_ipc.createRpcController();
    1299            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1300            3 :     m_mediaPipelineStub->getBufferingLimit(ipcController.get(), &request, &response, blockingClosure.get());
    1301              : 
    1302              :     // wait for the call to complete
    1303            3 :     blockingClosure->wait();
    1304              : 
    1305              :     // check the result
    1306            3 :     if (ipcController->Failed())
    1307              :     {
    1308            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get buffering limit due to '%s'", ipcController->ErrorText().c_str());
    1309            1 :         return false;
    1310              :     }
    1311              : 
    1312            2 :     limitBufferingMs = response.limit_buffering_ms();
    1313              : 
    1314            2 :     return true;
    1315            3 : }
    1316              : 
    1317            4 : bool MediaPipelineIpc::setUseBuffering(bool useBuffering)
    1318              : {
    1319            4 :     if (!reattachChannelIfRequired())
    1320              :     {
    1321            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1322            1 :         return false;
    1323              :     }
    1324              : 
    1325            3 :     firebolt::rialto::SetUseBufferingRequest request;
    1326              : 
    1327            3 :     request.set_session_id(m_sessionId);
    1328            3 :     request.set_use_buffering(useBuffering);
    1329              : 
    1330            3 :     firebolt::rialto::SetUseBufferingResponse response;
    1331            3 :     auto ipcController = m_ipc.createRpcController();
    1332            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1333            3 :     m_mediaPipelineStub->setUseBuffering(ipcController.get(), &request, &response, blockingClosure.get());
    1334              : 
    1335              :     // wait for the call to complete
    1336            3 :     blockingClosure->wait();
    1337              : 
    1338              :     // check the result
    1339            3 :     if (ipcController->Failed())
    1340              :     {
    1341            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set use buffering due to '%s'", ipcController->ErrorText().c_str());
    1342            1 :         return false;
    1343              :     }
    1344              : 
    1345            2 :     return true;
    1346            3 : }
    1347              : 
    1348            4 : bool MediaPipelineIpc::getUseBuffering(bool &useBuffering)
    1349              : {
    1350            4 :     if (!reattachChannelIfRequired())
    1351              :     {
    1352            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1353            1 :         return false;
    1354              :     }
    1355              : 
    1356            3 :     firebolt::rialto::GetUseBufferingRequest request;
    1357              : 
    1358            3 :     request.set_session_id(m_sessionId);
    1359              : 
    1360            3 :     firebolt::rialto::GetUseBufferingResponse response;
    1361            3 :     auto ipcController = m_ipc.createRpcController();
    1362            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1363            3 :     m_mediaPipelineStub->getUseBuffering(ipcController.get(), &request, &response, blockingClosure.get());
    1364              : 
    1365              :     // wait for the call to complete
    1366            3 :     blockingClosure->wait();
    1367              : 
    1368              :     // check the result
    1369            3 :     if (ipcController->Failed())
    1370              :     {
    1371            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get use buffering due to '%s'", ipcController->ErrorText().c_str());
    1372            1 :         return false;
    1373              :     }
    1374              : 
    1375            2 :     useBuffering = response.use_buffering();
    1376              : 
    1377            2 :     return true;
    1378            3 : }
    1379              : 
    1380            5 : bool MediaPipelineIpc::switchSource(const std::unique_ptr<IMediaPipeline::MediaSource> &source)
    1381              : {
    1382            5 :     if (!reattachChannelIfRequired())
    1383              :     {
    1384            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1385            1 :         return false;
    1386              :     }
    1387              : 
    1388            4 :     firebolt::rialto::AttachSourceRequest request;
    1389              : 
    1390            4 :     request.set_session_id(m_sessionId);
    1391            4 :     request.set_switch_source(true);
    1392            4 :     if (!buildAttachSourceRequest(request, source))
    1393              :     {
    1394            1 :         RIALTO_CLIENT_LOG_ERROR("Failed to parse source");
    1395            1 :         return false;
    1396              :     }
    1397              : 
    1398            3 :     firebolt::rialto::AttachSourceResponse response;
    1399            3 :     auto ipcController = m_ipc.createRpcController();
    1400            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1401            3 :     m_mediaPipelineStub->attachSource(ipcController.get(), &request, &response, blockingClosure.get());
    1402              : 
    1403              :     // wait for the call to complete
    1404            3 :     blockingClosure->wait();
    1405              : 
    1406              :     // check the result
    1407            3 :     if (ipcController->Failed())
    1408              :     {
    1409            1 :         RIALTO_CLIENT_LOG_ERROR("failed to attach source due to '%s'", ipcController->ErrorText().c_str());
    1410            1 :         return false;
    1411              :     }
    1412              : 
    1413            2 :     return true;
    1414            4 : }
    1415              : 
    1416            2 : void MediaPipelineIpc::onPlaybackStateUpdated(const std::shared_ptr<firebolt::rialto::PlaybackStateChangeEvent> &event)
    1417              : {
    1418              :     /* Ignore event if not for this session */
    1419            2 :     if (event->session_id() == m_sessionId)
    1420              :     {
    1421            1 :         PlaybackState playbackState = PlaybackState::UNKNOWN;
    1422            1 :         switch (event->state())
    1423              :         {
    1424            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_IDLE:
    1425            0 :             playbackState = PlaybackState::IDLE;
    1426            0 :             break;
    1427            1 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_PLAYING:
    1428            1 :             playbackState = PlaybackState::PLAYING;
    1429            1 :             break;
    1430            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_PAUSED:
    1431            0 :             playbackState = PlaybackState::PAUSED;
    1432            0 :             break;
    1433            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_SEEKING:
    1434            0 :             playbackState = PlaybackState::SEEKING;
    1435            0 :             break;
    1436            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_SEEK_DONE:
    1437            0 :             playbackState = PlaybackState::SEEK_DONE;
    1438            0 :             break;
    1439            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_STOPPED:
    1440            0 :             playbackState = PlaybackState::STOPPED;
    1441            0 :             break;
    1442            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_END_OF_STREAM:
    1443            0 :             playbackState = PlaybackState::END_OF_STREAM;
    1444            0 :             break;
    1445            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_FAILURE:
    1446            0 :             playbackState = PlaybackState::FAILURE;
    1447            0 :             break;
    1448            0 :         default:
    1449            0 :             RIALTO_CLIENT_LOG_WARN("Received unknown playback state");
    1450            0 :             break;
    1451              :         }
    1452              : 
    1453            1 :         m_mediaPipelineIpcClient->notifyPlaybackState(playbackState);
    1454              :     }
    1455            2 : }
    1456              : 
    1457            0 : void MediaPipelineIpc::onPositionUpdated(const std::shared_ptr<firebolt::rialto::PositionChangeEvent> &event)
    1458              : {
    1459              :     // Ignore event if not for this session
    1460            0 :     if (event->session_id() == m_sessionId)
    1461              :     {
    1462            0 :         int64_t position = event->position();
    1463            0 :         m_mediaPipelineIpcClient->notifyPosition(position);
    1464              :     }
    1465              : }
    1466              : 
    1467            2 : void MediaPipelineIpc::onNetworkStateUpdated(const std::shared_ptr<firebolt::rialto::NetworkStateChangeEvent> &event)
    1468              : {
    1469              :     // Ignore event if not for this session
    1470            2 :     if (event->session_id() == m_sessionId)
    1471              :     {
    1472            1 :         NetworkState networkState = NetworkState::UNKNOWN;
    1473            1 :         switch (event->state())
    1474              :         {
    1475            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_IDLE:
    1476            0 :             networkState = NetworkState::IDLE;
    1477            0 :             break;
    1478            1 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERING:
    1479            1 :             networkState = NetworkState::BUFFERING;
    1480            1 :             break;
    1481            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERING_PROGRESS:
    1482            0 :             networkState = NetworkState::BUFFERING_PROGRESS;
    1483            0 :             break;
    1484            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERED:
    1485            0 :             networkState = NetworkState::BUFFERED;
    1486            0 :             break;
    1487            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_STALLED:
    1488            0 :             networkState = NetworkState::STALLED;
    1489            0 :             break;
    1490            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_FORMAT_ERROR:
    1491            0 :             networkState = NetworkState::FORMAT_ERROR;
    1492            0 :             break;
    1493            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_NETWORK_ERROR:
    1494            0 :             networkState = NetworkState::NETWORK_ERROR;
    1495            0 :             break;
    1496            0 :         default:
    1497            0 :             RIALTO_CLIENT_LOG_WARN("Received unknown network state");
    1498            0 :             break;
    1499              :         }
    1500              : 
    1501            1 :         m_mediaPipelineIpcClient->notifyNetworkState(networkState);
    1502              :     }
    1503            2 : }
    1504              : 
    1505            3 : void MediaPipelineIpc::onNeedMediaData(const std::shared_ptr<firebolt::rialto::NeedMediaDataEvent> &event)
    1506              : {
    1507              :     // Ignore event if not for this session
    1508            3 :     if (event->session_id() == m_sessionId)
    1509              :     {
    1510            2 :         std::shared_ptr<MediaPlayerShmInfo> shmInfo;
    1511            2 :         if (event->has_shm_info())
    1512              :         {
    1513            1 :             shmInfo = std::make_shared<MediaPlayerShmInfo>();
    1514            1 :             shmInfo->maxMetadataBytes = event->shm_info().max_metadata_bytes();
    1515            1 :             shmInfo->metadataOffset = event->shm_info().metadata_offset();
    1516            1 :             shmInfo->mediaDataOffset = event->shm_info().media_data_offset();
    1517            1 :             shmInfo->maxMediaBytes = event->shm_info().max_media_bytes();
    1518              :         }
    1519            2 :         m_mediaPipelineIpcClient->notifyNeedMediaData(event->source_id(), event->frame_count(), event->request_id(),
    1520              :                                                       shmInfo);
    1521              :     }
    1522            3 : }
    1523              : 
    1524            2 : void MediaPipelineIpc::onQos(const std::shared_ptr<firebolt::rialto::QosEvent> &event)
    1525              : {
    1526              :     // Ignore event if not for this session
    1527            2 :     if (event->session_id() == m_sessionId)
    1528              :     {
    1529            1 :         QosInfo qosInfo = {event->qos_info().processed(), event->qos_info().dropped()};
    1530            1 :         m_mediaPipelineIpcClient->notifyQos(event->source_id(), qosInfo);
    1531              :     }
    1532            2 : }
    1533              : 
    1534            0 : void MediaPipelineIpc::onBufferUnderflow(const std::shared_ptr<firebolt::rialto::BufferUnderflowEvent> &event)
    1535              : {
    1536              :     // Ignore event if not for this session
    1537            0 :     if (event->session_id() == m_sessionId)
    1538              :     {
    1539            0 :         m_mediaPipelineIpcClient->notifyBufferUnderflow(event->source_id());
    1540              :     }
    1541              : }
    1542              : 
    1543            2 : void MediaPipelineIpc::onFirstFrameReceived(const std::shared_ptr<firebolt::rialto::FirstFrameReceivedEvent> &event)
    1544              : {
    1545              :     // Ignore event if not for this session
    1546            2 :     if (event->session_id() == m_sessionId)
    1547              :     {
    1548            1 :         m_mediaPipelineIpcClient->notifyFirstFrameReceived(event->source_id());
    1549              :     }
    1550            2 : }
    1551              : 
    1552            2 : void MediaPipelineIpc::onPlaybackError(const std::shared_ptr<firebolt::rialto::PlaybackErrorEvent> &event)
    1553              : {
    1554              :     // Ignore event if not for this session
    1555            2 :     if (event->session_id() == m_sessionId)
    1556              :     {
    1557            1 :         PlaybackError playbackError = PlaybackError::UNKNOWN;
    1558            1 :         switch (event->error())
    1559              :         {
    1560            1 :         case firebolt::rialto::PlaybackErrorEvent_PlaybackError_DECRYPTION:
    1561            1 :             playbackError = PlaybackError::DECRYPTION;
    1562            1 :             break;
    1563            0 :         case firebolt::rialto::PlaybackErrorEvent_PlaybackError_OUTPUT_PROTECTION:
    1564            0 :             playbackError = PlaybackError::OUTPUT_PROTECTION;
    1565            0 :             break;
    1566            0 :         default:
    1567            0 :             RIALTO_CLIENT_LOG_WARN("Received unknown playback error");
    1568            0 :             break;
    1569              :         }
    1570              : 
    1571            1 :         m_mediaPipelineIpcClient->notifyPlaybackError(event->source_id(), playbackError);
    1572              :     }
    1573            2 : }
    1574              : 
    1575            2 : void MediaPipelineIpc::onSourceFlushed(const std::shared_ptr<firebolt::rialto::SourceFlushedEvent> &event)
    1576              : {
    1577              :     // Ignore event if not for this session
    1578            2 :     if (event->session_id() == m_sessionId)
    1579              :     {
    1580            1 :         m_mediaPipelineIpcClient->notifySourceFlushed(event->source_id());
    1581              :     }
    1582            2 : }
    1583              : 
    1584            1 : void MediaPipelineIpc::onPlaybackInfo(const std::shared_ptr<firebolt::rialto::PlaybackInfoEvent> &event)
    1585              : {
    1586            1 :     if (event->session_id() == m_sessionId)
    1587              :     {
    1588            1 :         PlaybackInfo playbackInfo;
    1589            1 :         playbackInfo.currentPosition = event->current_position();
    1590            1 :         playbackInfo.volume = event->volume();
    1591            1 :         m_mediaPipelineIpcClient->notifyPlaybackInfo(playbackInfo);
    1592              :     }
    1593              : }
    1594              : 
    1595          180 : bool MediaPipelineIpc::createSession(const VideoRequirements &videoRequirements)
    1596              : {
    1597          180 :     if (!reattachChannelIfRequired())
    1598              :     {
    1599            0 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1600            0 :         return false;
    1601              :     }
    1602              : 
    1603          180 :     firebolt::rialto::CreateSessionRequest request;
    1604              : 
    1605          180 :     request.set_max_width(videoRequirements.maxWidth);
    1606          180 :     request.set_max_height(videoRequirements.maxHeight);
    1607              : 
    1608          180 :     firebolt::rialto::CreateSessionResponse response;
    1609          180 :     auto ipcController = m_ipc.createRpcController();
    1610          180 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1611          180 :     m_mediaPipelineStub->createSession(ipcController.get(), &request, &response, blockingClosure.get());
    1612              : 
    1613              :     // wait for the call to complete
    1614          180 :     blockingClosure->wait();
    1615              : 
    1616              :     // check the result
    1617          180 :     if (ipcController->Failed())
    1618              :     {
    1619            1 :         RIALTO_CLIENT_LOG_ERROR("failed to create session due to '%s'", ipcController->ErrorText().c_str());
    1620            1 :         return false;
    1621              :     }
    1622              : 
    1623          179 :     m_sessionId = response.session_id();
    1624              : 
    1625          179 :     return true;
    1626          180 : }
    1627              : 
    1628          179 : void MediaPipelineIpc::destroySession()
    1629              : {
    1630          179 :     if (!reattachChannelIfRequired())
    1631              :     {
    1632            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1633            1 :         return;
    1634              :     }
    1635              : 
    1636          178 :     firebolt::rialto::DestroySessionRequest request;
    1637          178 :     request.set_session_id(m_sessionId);
    1638              : 
    1639          178 :     firebolt::rialto::DestroySessionResponse response;
    1640          178 :     auto ipcController = m_ipc.createRpcController();
    1641          178 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1642          178 :     m_mediaPipelineStub->destroySession(ipcController.get(), &request, &response, blockingClosure.get());
    1643              : 
    1644              :     // wait for the call to complete
    1645          178 :     blockingClosure->wait();
    1646              : 
    1647              :     // check the result
    1648          178 :     if (ipcController->Failed())
    1649              :     {
    1650            1 :         RIALTO_CLIENT_LOG_ERROR("failed to destroy session due to '%s'", ipcController->ErrorText().c_str());
    1651              :     }
    1652          178 : }
    1653              : 
    1654            3 : firebolt::rialto::LoadRequest_MediaType MediaPipelineIpc::convertLoadRequestMediaType(MediaType mediaType) const
    1655              : {
    1656            3 :     firebolt::rialto::LoadRequest_MediaType protoMediaType = firebolt::rialto::LoadRequest_MediaType_UNKNOWN;
    1657            3 :     switch (mediaType)
    1658              :     {
    1659            3 :     case MediaType::MSE:
    1660            3 :         protoMediaType = firebolt::rialto::LoadRequest_MediaType_MSE;
    1661            3 :         break;
    1662            0 :     default:
    1663            0 :         break;
    1664              :     }
    1665              : 
    1666            3 :     return protoMediaType;
    1667              : }
    1668              : 
    1669              : firebolt::rialto::HaveDataRequest_MediaSourceStatus
    1670            3 : MediaPipelineIpc::convertHaveDataRequestMediaSourceStatus(MediaSourceStatus status) const
    1671              : {
    1672            3 :     firebolt::rialto::HaveDataRequest_MediaSourceStatus protoMediaSourceStatus =
    1673              :         firebolt::rialto::HaveDataRequest_MediaSourceStatus_UNKNOWN;
    1674            3 :     switch (status)
    1675              :     {
    1676            3 :     case MediaSourceStatus::OK:
    1677            3 :         protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_OK;
    1678            3 :         break;
    1679            0 :     case MediaSourceStatus::EOS:
    1680            0 :         protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_EOS;
    1681            0 :         break;
    1682            0 :     case MediaSourceStatus::ERROR:
    1683            0 :         protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_ERROR;
    1684            0 :         break;
    1685            0 :     case MediaSourceStatus::CODEC_CHANGED:
    1686            0 :         protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_CODEC_CHANGED;
    1687            0 :         break;
    1688            0 :     case MediaSourceStatus::NO_AVAILABLE_SAMPLES:
    1689            0 :         protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_NO_AVAILABLE_SAMPLES;
    1690            0 :         break;
    1691            0 :     default:
    1692            0 :         break;
    1693              :     }
    1694              : 
    1695            3 :     return protoMediaSourceStatus;
    1696              : }
    1697              : 
    1698              : firebolt::rialto::AttachSourceRequest_ConfigType
    1699           17 : MediaPipelineIpc::convertConfigType(const firebolt::rialto::SourceConfigType &configType) const
    1700              : {
    1701           17 :     switch (configType)
    1702              :     {
    1703            0 :     case firebolt::rialto::SourceConfigType::UNKNOWN:
    1704              :     {
    1705            0 :         return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_UNKNOWN;
    1706              :     }
    1707            9 :     case firebolt::rialto::SourceConfigType::AUDIO:
    1708              :     {
    1709            9 :         return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_AUDIO;
    1710              :     }
    1711            3 :     case firebolt::rialto::SourceConfigType::VIDEO:
    1712              :     {
    1713            3 :         return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_VIDEO;
    1714              :     }
    1715            3 :     case firebolt::rialto::SourceConfigType::VIDEO_DOLBY_VISION:
    1716              :     {
    1717            3 :         return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_VIDEO_DOLBY_VISION;
    1718              :     }
    1719            2 :     case firebolt::rialto::SourceConfigType::SUBTITLE:
    1720              :     {
    1721            2 :         return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_SUBTITLE;
    1722              :     }
    1723              :     }
    1724            0 :     return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_UNKNOWN;
    1725              : }
    1726              : 
    1727            3 : firebolt::rialto::SetVolumeRequest_EaseType MediaPipelineIpc::convertEaseType(const firebolt::rialto::EaseType &easeType) const
    1728              : {
    1729            3 :     switch (easeType)
    1730              :     {
    1731            3 :     case firebolt::rialto::EaseType::EASE_LINEAR:
    1732              :     {
    1733            3 :         return firebolt::rialto::SetVolumeRequest_EaseType_EASE_LINEAR;
    1734              :     }
    1735            0 :     case firebolt::rialto::EaseType::EASE_IN_CUBIC:
    1736              :     {
    1737            0 :         return firebolt::rialto::SetVolumeRequest_EaseType_EASE_IN_CUBIC;
    1738              :     }
    1739            0 :     case firebolt::rialto::EaseType::EASE_OUT_CUBIC:
    1740              :     {
    1741            0 :         return firebolt::rialto::SetVolumeRequest_EaseType_EASE_OUT_CUBIC;
    1742              :     }
    1743              :     }
    1744            0 :     return firebolt::rialto::SetVolumeRequest_EaseType_EASE_LINEAR;
    1745              : }
    1746              : 
    1747              : firebolt::rialto::AttachSourceRequest_SegmentAlignment
    1748           14 : MediaPipelineIpc::convertSegmentAlignment(const firebolt::rialto::SegmentAlignment &alignment) const
    1749              : {
    1750           14 :     switch (alignment)
    1751              :     {
    1752           14 :     case firebolt::rialto::SegmentAlignment::UNDEFINED:
    1753              :     {
    1754           14 :         return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_UNDEFINED;
    1755              :     }
    1756            0 :     case firebolt::rialto::SegmentAlignment::NAL:
    1757              :     {
    1758            0 :         return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_NAL;
    1759              :     }
    1760            0 :     case firebolt::rialto::SegmentAlignment::AU:
    1761              :     {
    1762            0 :         return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_AU;
    1763              :     }
    1764              :     }
    1765            0 :     return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_UNDEFINED;
    1766              : }
    1767              : 
    1768              : firebolt::rialto::AttachSourceRequest_StreamFormat
    1769           14 : MediaPipelineIpc::convertStreamFormat(const firebolt::rialto::StreamFormat &streamFormat) const
    1770              : {
    1771           14 :     switch (streamFormat)
    1772              :     {
    1773            8 :     case firebolt::rialto::StreamFormat::UNDEFINED:
    1774              :     {
    1775            8 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_UNDEFINED;
    1776              :     }
    1777            6 :     case firebolt::rialto::StreamFormat::RAW:
    1778              :     {
    1779            6 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_RAW;
    1780              :     }
    1781            0 :     case firebolt::rialto::StreamFormat::AVC:
    1782              :     {
    1783            0 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_AVC;
    1784              :     }
    1785            0 :     case firebolt::rialto::StreamFormat::BYTE_STREAM:
    1786              :     {
    1787            0 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_BYTE_STREAM;
    1788              :     }
    1789            0 :     case firebolt::rialto::StreamFormat::HVC1:
    1790              :     {
    1791            0 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_HVC1;
    1792              :     }
    1793            0 :     case firebolt::rialto::StreamFormat::HEV1:
    1794              :     {
    1795            0 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_HEV1;
    1796              :     }
    1797              :     }
    1798            0 :     return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_UNDEFINED;
    1799              : }
    1800              : 
    1801              : firebolt::rialto::AttachSourceRequest_CodecData_Type
    1802            3 : MediaPipelineIpc::convertCodecDataType(const firebolt::rialto::CodecDataType &codecDataType) const
    1803              : {
    1804            3 :     if (firebolt::rialto::CodecDataType::STRING == codecDataType)
    1805              :     {
    1806            0 :         return firebolt::rialto::AttachSourceRequest_CodecData_Type_STRING;
    1807              :     }
    1808            3 :     return firebolt::rialto::AttachSourceRequest_CodecData_Type_BUFFER;
    1809              : }
    1810              : 
    1811              : firebolt::rialto::AttachSourceRequest_AudioConfig_Format
    1812            0 : MediaPipelineIpc::convertFormat(const firebolt::rialto::Format &format) const
    1813              : {
    1814              :     static const std::unordered_map<firebolt::rialto::Format, firebolt::rialto::AttachSourceRequest_AudioConfig_Format>
    1815              :         kFormatConversionMap{
    1816              :             {firebolt::rialto::Format::S8, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S8},
    1817              :             {firebolt::rialto::Format::U8, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U8},
    1818              :             {firebolt::rialto::Format::S16LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S16LE},
    1819              :             {firebolt::rialto::Format::S16BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S16BE},
    1820              :             {firebolt::rialto::Format::U16LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U16LE},
    1821              :             {firebolt::rialto::Format::U16BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U16BE},
    1822              :             {firebolt::rialto::Format::S24_32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24_32LE},
    1823              :             {firebolt::rialto::Format::S24_32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24_32BE},
    1824              :             {firebolt::rialto::Format::U24_32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24_32LE},
    1825              :             {firebolt::rialto::Format::U24_32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24_32BE},
    1826              :             {firebolt::rialto::Format::S32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S32LE},
    1827              :             {firebolt::rialto::Format::S32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S32BE},
    1828              :             {firebolt::rialto::Format::U32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U32LE},
    1829              :             {firebolt::rialto::Format::U32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U32BE},
    1830              :             {firebolt::rialto::Format::S24LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24LE},
    1831              :             {firebolt::rialto::Format::S24BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24BE},
    1832              :             {firebolt::rialto::Format::U24LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24LE},
    1833              :             {firebolt::rialto::Format::U24BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24BE},
    1834              :             {firebolt::rialto::Format::S20LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S20LE},
    1835              :             {firebolt::rialto::Format::S20BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S20BE},
    1836              :             {firebolt::rialto::Format::U20LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U20LE},
    1837              :             {firebolt::rialto::Format::U20BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U20BE},
    1838              :             {firebolt::rialto::Format::S18LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S18LE},
    1839              :             {firebolt::rialto::Format::S18BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S18BE},
    1840              :             {firebolt::rialto::Format::U18LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U18LE},
    1841              :             {firebolt::rialto::Format::U18BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U18BE},
    1842              :             {firebolt::rialto::Format::F32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F32LE},
    1843              :             {firebolt::rialto::Format::F32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F32BE},
    1844              :             {firebolt::rialto::Format::F64LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F64LE},
    1845            0 :             {firebolt::rialto::Format::F64BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F64BE}};
    1846            0 :     const auto kIt = kFormatConversionMap.find(format);
    1847            0 :     if (kFormatConversionMap.end() != kIt)
    1848              :     {
    1849            0 :         return kIt->second;
    1850              :     }
    1851            0 :     return firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S8;
    1852              : }
    1853              : 
    1854              : firebolt::rialto::AttachSourceRequest_AudioConfig_Layout
    1855            0 : MediaPipelineIpc::convertLayout(const firebolt::rialto::Layout &layout) const
    1856              : {
    1857              :     static const std::unordered_map<firebolt::rialto::Layout, firebolt::rialto::AttachSourceRequest_AudioConfig_Layout>
    1858              :         kLayoutConversionMap{{firebolt::rialto::Layout::INTERLEAVED,
    1859              :                               firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_INTERLEAVED},
    1860              :                              {firebolt::rialto::Layout::NON_INTERLEAVED,
    1861            0 :                               firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_NON_INTERLEAVED}};
    1862            0 :     const auto kIt = kLayoutConversionMap.find(layout);
    1863            0 :     if (kLayoutConversionMap.end() != kIt)
    1864              :     {
    1865            0 :         return kIt->second;
    1866              :     }
    1867            0 :     return firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_INTERLEAVED;
    1868              : }
    1869              : 
    1870           17 : bool MediaPipelineIpc::buildAttachSourceRequest(firebolt::rialto::AttachSourceRequest &request,
    1871              :                                                 const std::unique_ptr<IMediaPipeline::MediaSource> &source) const
    1872              : {
    1873           17 :     SourceConfigType configType = source->getConfigType();
    1874           17 :     request.set_config_type(convertConfigType(configType));
    1875           34 :     request.set_mime_type(source->getMimeType());
    1876           17 :     request.set_has_drm(source->getHasDrm());
    1877              : 
    1878           17 :     if (configType == SourceConfigType::VIDEO_DOLBY_VISION || configType == SourceConfigType::VIDEO ||
    1879           11 :         configType == SourceConfigType::AUDIO)
    1880              :     {
    1881           15 :         IMediaPipeline::MediaSourceAV *mediaSourceAV = dynamic_cast<IMediaPipeline::MediaSourceAV *>(source.get());
    1882           15 :         if (!mediaSourceAV)
    1883              :         {
    1884            1 :             RIALTO_CLIENT_LOG_ERROR("Failed to get the audio video source");
    1885            1 :             return false;
    1886              :         }
    1887           14 :         request.set_segment_alignment(convertSegmentAlignment(mediaSourceAV->getSegmentAlignment()));
    1888              : 
    1889           14 :         if (mediaSourceAV->getCodecData())
    1890              :         {
    1891            6 :             request.mutable_codec_data()->set_data(mediaSourceAV->getCodecData()->data.data(),
    1892            3 :                                                    mediaSourceAV->getCodecData()->data.size());
    1893            3 :             request.mutable_codec_data()->set_type(convertCodecDataType(mediaSourceAV->getCodecData()->type));
    1894              :         }
    1895           14 :         request.set_stream_format(convertStreamFormat(mediaSourceAV->getStreamFormat()));
    1896              : 
    1897           14 :         if (configType == SourceConfigType::VIDEO_DOLBY_VISION)
    1898              :         {
    1899              :             IMediaPipeline::MediaSourceVideoDolbyVision *mediaSourceDolby =
    1900            2 :                 dynamic_cast<IMediaPipeline::MediaSourceVideoDolbyVision *>(source.get());
    1901            2 :             if (!mediaSourceDolby)
    1902              :             {
    1903            1 :                 RIALTO_CLIENT_LOG_ERROR("Failed to get the video dolby vision media source");
    1904            1 :                 return false;
    1905              :             }
    1906            1 :             request.set_width(mediaSourceDolby->getWidth());
    1907            1 :             request.set_height(mediaSourceDolby->getHeight());
    1908            1 :             request.set_dolby_vision_profile(mediaSourceDolby->getDolbyVisionProfile());
    1909              :         }
    1910           12 :         else if (configType == SourceConfigType::VIDEO)
    1911              :         {
    1912              :             IMediaPipeline::MediaSourceVideo *mediaSourceVideo =
    1913            3 :                 dynamic_cast<IMediaPipeline::MediaSourceVideo *>(source.get());
    1914            3 :             if (!mediaSourceVideo)
    1915              :             {
    1916            1 :                 RIALTO_CLIENT_LOG_ERROR("Failed to get the video media source");
    1917            1 :                 return false;
    1918              :             }
    1919            2 :             request.set_width(mediaSourceVideo->getWidth());
    1920            2 :             request.set_height(mediaSourceVideo->getHeight());
    1921              :         }
    1922            9 :         else if (configType == SourceConfigType::AUDIO)
    1923              :         {
    1924              :             IMediaPipeline::MediaSourceAudio *mediaSourceAudio =
    1925            9 :                 dynamic_cast<IMediaPipeline::MediaSourceAudio *>(source.get());
    1926            9 :             if (!mediaSourceAudio)
    1927              :             {
    1928            2 :                 RIALTO_CLIENT_LOG_ERROR("Failed to get the audio media source");
    1929            2 :                 return false;
    1930              :             }
    1931            7 :             request.mutable_audio_config()->set_number_of_channels(mediaSourceAudio->getAudioConfig().numberOfChannels);
    1932            7 :             request.mutable_audio_config()->set_sample_rate(mediaSourceAudio->getAudioConfig().sampleRate);
    1933            7 :             if (!mediaSourceAudio->getAudioConfig().codecSpecificConfig.empty())
    1934              :             {
    1935              :                 request.mutable_audio_config()
    1936            9 :                     ->set_codec_specific_config(mediaSourceAudio->getAudioConfig().codecSpecificConfig.data(),
    1937            3 :                                                 mediaSourceAudio->getAudioConfig().codecSpecificConfig.size());
    1938              :             }
    1939            7 :             if (mediaSourceAudio->getAudioConfig().format.has_value())
    1940              :             {
    1941            0 :                 request.mutable_audio_config()->set_format(
    1942            0 :                     convertFormat(mediaSourceAudio->getAudioConfig().format.value()));
    1943              :             }
    1944            7 :             if (mediaSourceAudio->getAudioConfig().layout.has_value())
    1945              :             {
    1946            0 :                 request.mutable_audio_config()->set_layout(
    1947            0 :                     convertLayout(mediaSourceAudio->getAudioConfig().layout.value()));
    1948              :             }
    1949            7 :             if (mediaSourceAudio->getAudioConfig().channelMask.has_value())
    1950              :             {
    1951            0 :                 request.mutable_audio_config()->set_channel_mask(mediaSourceAudio->getAudioConfig().channelMask.value());
    1952              :             }
    1953            7 :             for (auto &header : mediaSourceAudio->getAudioConfig().streamHeader)
    1954              :             {
    1955            0 :                 request.mutable_audio_config()->add_stream_header(header.data(), header.size());
    1956              :             }
    1957            7 :             if (mediaSourceAudio->getAudioConfig().framed.has_value())
    1958              :             {
    1959            0 :                 request.mutable_audio_config()->set_framed(mediaSourceAudio->getAudioConfig().framed.value());
    1960              :             }
    1961              :         }
    1962           10 :     }
    1963            2 :     else if (configType == SourceConfigType::SUBTITLE)
    1964              :     {
    1965              :         IMediaPipeline::MediaSourceSubtitle *mediaSourceSubtitle =
    1966            2 :             dynamic_cast<IMediaPipeline::MediaSourceSubtitle *>(source.get());
    1967            2 :         if (!mediaSourceSubtitle)
    1968              :         {
    1969            1 :             RIALTO_CLIENT_LOG_ERROR("Failed to get the subtitle source");
    1970            1 :             return false;
    1971              :         }
    1972            1 :         request.set_text_track_identifier(mediaSourceSubtitle->getTextTrackIdentifier());
    1973              :     }
    1974              :     else
    1975              :     {
    1976            0 :         RIALTO_CLIENT_LOG_ERROR("Unknown source type");
    1977            0 :         return false;
    1978              :     }
    1979           11 :     return true;
    1980              : }
    1981              : }; // namespace firebolt::rialto::client
        

Generated by: LCOV version 2.0-1