LCOV - code coverage report
Current view: top level - media/client/ipc/source - MediaPipelineIpc.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.8 % 1033 886
Test Date: 2025-10-07 14:22:52 Functions: 90.1 % 71 64

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

Generated by: LCOV version 2.0-1