LCOV - code coverage report
Current view: top level - media/client/ipc/source - MediaPipelineIpc.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 86.3 % 1082 934
Test Date: 2026-03-04 13:20:25 Functions: 90.7 % 75 68

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

Generated by: LCOV version 2.0-1