LCOV - code coverage report
Current view: top level - media/client/ipc/source - MediaPipelineIpc.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.6 % 1010 865
Test Date: 2025-03-21 11:02:39 Functions: 90.0 % 70 63

            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          174 : MediaPipelineIpc::MediaPipelineIpc(IMediaPipelineIpcClient *client, const VideoRequirements &videoRequirements,
      72              :                                    IIpcClient &ipcClient,
      73          174 :                                    const std::shared_ptr<common::IEventThreadFactory> &eventThreadFactory)
      74          174 :     : IpcModule(ipcClient), m_mediaPipelineIpcClient(client),
      75          348 :       m_eventThread(eventThreadFactory->createEventThread("rialto-media-player-events"))
      76              : {
      77          174 :     if (!attachChannel())
      78              :     {
      79            4 :         throw std::runtime_error("Failed attach to the ipc channel");
      80              :     }
      81              : 
      82              :     // create media player session
      83          170 :     if (!createSession(videoRequirements))
      84              :     {
      85            1 :         detachChannel();
      86            1 :         throw std::runtime_error("Could not create the media player session");
      87              :     }
      88          189 : }
      89              : 
      90          338 : MediaPipelineIpc::~MediaPipelineIpc()
      91              : {
      92              :     // destroy media player session
      93          169 :     destroySession();
      94              : 
      95              :     // detach the Ipc channel
      96          169 :     detachChannel();
      97              : 
      98              :     // destroy the thread processing async notifications
      99          169 :     m_eventThread.reset();
     100          338 : }
     101              : 
     102          241 : bool MediaPipelineIpc::createRpcStubs(const std::shared_ptr<ipc::IChannel> &ipcChannel)
     103              : {
     104          241 :     m_mediaPipelineStub = std::make_unique<::firebolt::rialto::MediaPipelineModule_Stub>(ipcChannel.get());
     105          241 :     if (!m_mediaPipelineStub)
     106              :     {
     107            0 :         return false;
     108              :     }
     109          241 :     return true;
     110              : }
     111              : 
     112          241 : bool MediaPipelineIpc::subscribeToEvents(const std::shared_ptr<ipc::IChannel> &ipcChannel)
     113              : {
     114          241 :     if (!ipcChannel)
     115              :     {
     116            0 :         return false;
     117              :     }
     118              : 
     119          482 :     int eventTag = ipcChannel->subscribe<firebolt::rialto::PlaybackStateChangeEvent>(
     120          241 :         [this](const std::shared_ptr<firebolt::rialto::PlaybackStateChangeEvent> &event)
     121          243 :         { m_eventThread->add(&MediaPipelineIpc::onPlaybackStateUpdated, this, event); });
     122          241 :     if (eventTag < 0)
     123            0 :         return false;
     124          241 :     m_eventTags.push_back(eventTag);
     125              : 
     126          482 :     eventTag = ipcChannel->subscribe<firebolt::rialto::PositionChangeEvent>(
     127          241 :         [this](const std::shared_ptr<firebolt::rialto::PositionChangeEvent> &event)
     128            0 :         { m_eventThread->add(&MediaPipelineIpc::onPositionUpdated, this, event); });
     129          241 :     if (eventTag < 0)
     130            1 :         return false;
     131          240 :     m_eventTags.push_back(eventTag);
     132              : 
     133          480 :     eventTag = ipcChannel->subscribe<firebolt::rialto::NetworkStateChangeEvent>(
     134          240 :         [this](const std::shared_ptr<firebolt::rialto::NetworkStateChangeEvent> &event)
     135            2 :         { m_eventThread->add(&MediaPipelineIpc::onNetworkStateUpdated, this, event); });
     136          240 :     if (eventTag < 0)
     137            0 :         return false;
     138          240 :     m_eventTags.push_back(eventTag);
     139              : 
     140          480 :     eventTag = ipcChannel->subscribe<firebolt::rialto::NeedMediaDataEvent>(
     141          240 :         [this](const std::shared_ptr<firebolt::rialto::NeedMediaDataEvent> &event)
     142            3 :         { m_eventThread->add(&MediaPipelineIpc::onNeedMediaData, this, event); });
     143          240 :     if (eventTag < 0)
     144            0 :         return false;
     145          240 :     m_eventTags.push_back(eventTag);
     146              : 
     147          480 :     eventTag = ipcChannel->subscribe<firebolt::rialto::QosEvent>(
     148          240 :         [this](const std::shared_ptr<firebolt::rialto::QosEvent> &event)
     149            2 :         { m_eventThread->add(&MediaPipelineIpc::onQos, this, event); });
     150          240 :     if (eventTag < 0)
     151            0 :         return false;
     152          240 :     m_eventTags.push_back(eventTag);
     153              : 
     154          480 :     eventTag = ipcChannel->subscribe<firebolt::rialto::BufferUnderflowEvent>(
     155          240 :         [this](const std::shared_ptr<firebolt::rialto::BufferUnderflowEvent> &event)
     156            0 :         { m_eventThread->add(&MediaPipelineIpc::onBufferUnderflow, this, event); });
     157          240 :     if (eventTag < 0)
     158            0 :         return false;
     159          240 :     m_eventTags.push_back(eventTag);
     160              : 
     161          480 :     eventTag = ipcChannel->subscribe<firebolt::rialto::PlaybackErrorEvent>(
     162          240 :         [this](const std::shared_ptr<firebolt::rialto::PlaybackErrorEvent> &event)
     163            2 :         { m_eventThread->add(&MediaPipelineIpc::onPlaybackError, this, event); });
     164          240 :     if (eventTag < 0)
     165            0 :         return false;
     166          240 :     m_eventTags.push_back(eventTag);
     167              : 
     168          480 :     eventTag = ipcChannel->subscribe<firebolt::rialto::SourceFlushedEvent>(
     169          240 :         [this](const std::shared_ptr<firebolt::rialto::SourceFlushedEvent> &event)
     170            2 :         { m_eventThread->add(&MediaPipelineIpc::onSourceFlushed, this, event); });
     171          240 :     if (eventTag < 0)
     172            0 :         return false;
     173          240 :     m_eventTags.push_back(eventTag);
     174              : 
     175          240 :     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)
    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            2 :     return true;
    1099            3 : }
    1100              : 
    1101            4 : bool MediaPipelineIpc::setSourcePosition(int32_t sourceId, int64_t position, bool resetTime, double appliedRate,
    1102              :                                          uint64_t stopPosition)
    1103              : {
    1104            4 :     if (!reattachChannelIfRequired())
    1105              :     {
    1106            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1107            1 :         return false;
    1108              :     }
    1109              : 
    1110            3 :     firebolt::rialto::SetSourcePositionRequest request;
    1111              : 
    1112            3 :     request.set_session_id(m_sessionId);
    1113            3 :     request.set_source_id(sourceId);
    1114            3 :     request.set_position(position);
    1115            3 :     request.set_reset_time(resetTime);
    1116            3 :     request.set_applied_rate(appliedRate);
    1117            3 :     request.set_stop_position(stopPosition);
    1118              : 
    1119            3 :     firebolt::rialto::SetSourcePositionResponse response;
    1120            3 :     auto ipcController = m_ipc.createRpcController();
    1121            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1122            3 :     m_mediaPipelineStub->setSourcePosition(ipcController.get(), &request, &response, blockingClosure.get());
    1123              : 
    1124              :     // wait for the call to complete
    1125            3 :     blockingClosure->wait();
    1126              : 
    1127              :     // check the result
    1128            3 :     if (ipcController->Failed())
    1129              :     {
    1130            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set source position due to '%s'", ipcController->ErrorText().c_str());
    1131            1 :         return false;
    1132              :     }
    1133              : 
    1134            2 :     return true;
    1135            3 : }
    1136              : 
    1137            4 : bool MediaPipelineIpc::processAudioGap(int64_t position, uint32_t duration, int64_t discontinuityGap, bool audioAac)
    1138              : {
    1139            4 :     if (!reattachChannelIfRequired())
    1140              :     {
    1141            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1142            1 :         return false;
    1143              :     }
    1144              : 
    1145            3 :     firebolt::rialto::ProcessAudioGapRequest request;
    1146              : 
    1147            3 :     request.set_session_id(m_sessionId);
    1148            3 :     request.set_position(position);
    1149            3 :     request.set_duration(duration);
    1150            3 :     request.set_discontinuity_gap(discontinuityGap);
    1151            3 :     request.set_audio_aac(audioAac);
    1152              : 
    1153            3 :     firebolt::rialto::ProcessAudioGapResponse response;
    1154            3 :     auto ipcController = m_ipc.createRpcController();
    1155            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1156            3 :     m_mediaPipelineStub->processAudioGap(ipcController.get(), &request, &response, blockingClosure.get());
    1157              : 
    1158              :     // wait for the call to complete
    1159            3 :     blockingClosure->wait();
    1160              : 
    1161              :     // check the result
    1162            3 :     if (ipcController->Failed())
    1163              :     {
    1164            1 :         RIALTO_CLIENT_LOG_ERROR("failed to process audio gap due to '%s'", ipcController->ErrorText().c_str());
    1165            1 :         return false;
    1166              :     }
    1167              : 
    1168            2 :     return true;
    1169            3 : }
    1170              : 
    1171            4 : bool MediaPipelineIpc::setBufferingLimit(uint32_t limitBufferingMs)
    1172              : {
    1173            4 :     if (!reattachChannelIfRequired())
    1174              :     {
    1175            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1176            1 :         return false;
    1177              :     }
    1178              : 
    1179            3 :     firebolt::rialto::SetBufferingLimitRequest request;
    1180              : 
    1181            3 :     request.set_session_id(m_sessionId);
    1182            3 :     request.set_limit_buffering_ms(limitBufferingMs);
    1183              : 
    1184            3 :     firebolt::rialto::SetBufferingLimitResponse response;
    1185            3 :     auto ipcController = m_ipc.createRpcController();
    1186            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1187            3 :     m_mediaPipelineStub->setBufferingLimit(ipcController.get(), &request, &response, blockingClosure.get());
    1188              : 
    1189              :     // wait for the call to complete
    1190            3 :     blockingClosure->wait();
    1191              : 
    1192              :     // check the result
    1193            3 :     if (ipcController->Failed())
    1194              :     {
    1195            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set buffering limit due to '%s'", ipcController->ErrorText().c_str());
    1196            1 :         return false;
    1197              :     }
    1198              : 
    1199            2 :     return true;
    1200            3 : }
    1201              : 
    1202            4 : bool MediaPipelineIpc::getBufferingLimit(uint32_t &limitBufferingMs)
    1203              : {
    1204            4 :     if (!reattachChannelIfRequired())
    1205              :     {
    1206            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1207            1 :         return false;
    1208              :     }
    1209              : 
    1210            3 :     firebolt::rialto::GetBufferingLimitRequest request;
    1211              : 
    1212            3 :     request.set_session_id(m_sessionId);
    1213              : 
    1214            3 :     firebolt::rialto::GetBufferingLimitResponse response;
    1215            3 :     auto ipcController = m_ipc.createRpcController();
    1216            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1217            3 :     m_mediaPipelineStub->getBufferingLimit(ipcController.get(), &request, &response, blockingClosure.get());
    1218              : 
    1219              :     // wait for the call to complete
    1220            3 :     blockingClosure->wait();
    1221              : 
    1222              :     // check the result
    1223            3 :     if (ipcController->Failed())
    1224              :     {
    1225            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get buffering limit due to '%s'", ipcController->ErrorText().c_str());
    1226            1 :         return false;
    1227              :     }
    1228              : 
    1229            2 :     limitBufferingMs = response.limit_buffering_ms();
    1230              : 
    1231            2 :     return true;
    1232            3 : }
    1233              : 
    1234            4 : bool MediaPipelineIpc::setUseBuffering(bool useBuffering)
    1235              : {
    1236            4 :     if (!reattachChannelIfRequired())
    1237              :     {
    1238            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1239            1 :         return false;
    1240              :     }
    1241              : 
    1242            3 :     firebolt::rialto::SetUseBufferingRequest request;
    1243              : 
    1244            3 :     request.set_session_id(m_sessionId);
    1245            3 :     request.set_use_buffering(useBuffering);
    1246              : 
    1247            3 :     firebolt::rialto::SetUseBufferingResponse response;
    1248            3 :     auto ipcController = m_ipc.createRpcController();
    1249            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1250            3 :     m_mediaPipelineStub->setUseBuffering(ipcController.get(), &request, &response, blockingClosure.get());
    1251              : 
    1252              :     // wait for the call to complete
    1253            3 :     blockingClosure->wait();
    1254              : 
    1255              :     // check the result
    1256            3 :     if (ipcController->Failed())
    1257              :     {
    1258            1 :         RIALTO_CLIENT_LOG_ERROR("failed to set use buffering due to '%s'", ipcController->ErrorText().c_str());
    1259            1 :         return false;
    1260              :     }
    1261              : 
    1262            2 :     return true;
    1263            3 : }
    1264              : 
    1265            4 : bool MediaPipelineIpc::getUseBuffering(bool &useBuffering)
    1266              : {
    1267            4 :     if (!reattachChannelIfRequired())
    1268              :     {
    1269            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1270            1 :         return false;
    1271              :     }
    1272              : 
    1273            3 :     firebolt::rialto::GetUseBufferingRequest request;
    1274              : 
    1275            3 :     request.set_session_id(m_sessionId);
    1276              : 
    1277            3 :     firebolt::rialto::GetUseBufferingResponse response;
    1278            3 :     auto ipcController = m_ipc.createRpcController();
    1279            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1280            3 :     m_mediaPipelineStub->getUseBuffering(ipcController.get(), &request, &response, blockingClosure.get());
    1281              : 
    1282              :     // wait for the call to complete
    1283            3 :     blockingClosure->wait();
    1284              : 
    1285              :     // check the result
    1286            3 :     if (ipcController->Failed())
    1287              :     {
    1288            1 :         RIALTO_CLIENT_LOG_ERROR("failed to get use buffering due to '%s'", ipcController->ErrorText().c_str());
    1289            1 :         return false;
    1290              :     }
    1291              : 
    1292            2 :     useBuffering = response.use_buffering();
    1293              : 
    1294            2 :     return true;
    1295            3 : }
    1296              : 
    1297            5 : bool MediaPipelineIpc::switchSource(const std::unique_ptr<IMediaPipeline::MediaSource> &source)
    1298              : {
    1299            5 :     if (!reattachChannelIfRequired())
    1300              :     {
    1301            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1302            1 :         return false;
    1303              :     }
    1304              : 
    1305            4 :     firebolt::rialto::AttachSourceRequest request;
    1306              : 
    1307            4 :     request.set_session_id(m_sessionId);
    1308            4 :     request.set_switch_source(true);
    1309            4 :     if (!buildAttachSourceRequest(request, source))
    1310              :     {
    1311            1 :         RIALTO_CLIENT_LOG_ERROR("Failed to parse source");
    1312            1 :         return false;
    1313              :     }
    1314              : 
    1315            3 :     firebolt::rialto::AttachSourceResponse response;
    1316            3 :     auto ipcController = m_ipc.createRpcController();
    1317            3 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1318            3 :     m_mediaPipelineStub->attachSource(ipcController.get(), &request, &response, blockingClosure.get());
    1319              : 
    1320              :     // wait for the call to complete
    1321            3 :     blockingClosure->wait();
    1322              : 
    1323              :     // check the result
    1324            3 :     if (ipcController->Failed())
    1325              :     {
    1326            1 :         RIALTO_CLIENT_LOG_ERROR("failed to attach source due to '%s'", ipcController->ErrorText().c_str());
    1327            1 :         return false;
    1328              :     }
    1329              : 
    1330            2 :     return true;
    1331            4 : }
    1332              : 
    1333            2 : void MediaPipelineIpc::onPlaybackStateUpdated(const std::shared_ptr<firebolt::rialto::PlaybackStateChangeEvent> &event)
    1334              : {
    1335              :     /* Ignore event if not for this session */
    1336            2 :     if (event->session_id() == m_sessionId)
    1337              :     {
    1338            1 :         PlaybackState playbackState = PlaybackState::UNKNOWN;
    1339            1 :         switch (event->state())
    1340              :         {
    1341            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_IDLE:
    1342            0 :             playbackState = PlaybackState::IDLE;
    1343            0 :             break;
    1344            1 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_PLAYING:
    1345            1 :             playbackState = PlaybackState::PLAYING;
    1346            1 :             break;
    1347            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_PAUSED:
    1348            0 :             playbackState = PlaybackState::PAUSED;
    1349            0 :             break;
    1350            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_SEEKING:
    1351            0 :             playbackState = PlaybackState::SEEKING;
    1352            0 :             break;
    1353            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_SEEK_DONE:
    1354            0 :             playbackState = PlaybackState::SEEK_DONE;
    1355            0 :             break;
    1356            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_STOPPED:
    1357            0 :             playbackState = PlaybackState::STOPPED;
    1358            0 :             break;
    1359            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_END_OF_STREAM:
    1360            0 :             playbackState = PlaybackState::END_OF_STREAM;
    1361            0 :             break;
    1362            0 :         case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_FAILURE:
    1363            0 :             playbackState = PlaybackState::FAILURE;
    1364            0 :             break;
    1365            0 :         default:
    1366            0 :             RIALTO_CLIENT_LOG_WARN("Received unknown playback state");
    1367            0 :             break;
    1368              :         }
    1369              : 
    1370            1 :         m_mediaPipelineIpcClient->notifyPlaybackState(playbackState);
    1371              :     }
    1372            2 : }
    1373              : 
    1374            0 : void MediaPipelineIpc::onPositionUpdated(const std::shared_ptr<firebolt::rialto::PositionChangeEvent> &event)
    1375              : {
    1376              :     // Ignore event if not for this session
    1377            0 :     if (event->session_id() == m_sessionId)
    1378              :     {
    1379            0 :         int64_t position = event->position();
    1380            0 :         m_mediaPipelineIpcClient->notifyPosition(position);
    1381              :     }
    1382              : }
    1383              : 
    1384            2 : void MediaPipelineIpc::onNetworkStateUpdated(const std::shared_ptr<firebolt::rialto::NetworkStateChangeEvent> &event)
    1385              : {
    1386              :     // Ignore event if not for this session
    1387            2 :     if (event->session_id() == m_sessionId)
    1388              :     {
    1389            1 :         NetworkState networkState = NetworkState::UNKNOWN;
    1390            1 :         switch (event->state())
    1391              :         {
    1392            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_IDLE:
    1393            0 :             networkState = NetworkState::IDLE;
    1394            0 :             break;
    1395            1 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERING:
    1396            1 :             networkState = NetworkState::BUFFERING;
    1397            1 :             break;
    1398            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERING_PROGRESS:
    1399            0 :             networkState = NetworkState::BUFFERING_PROGRESS;
    1400            0 :             break;
    1401            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERED:
    1402            0 :             networkState = NetworkState::BUFFERED;
    1403            0 :             break;
    1404            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_STALLED:
    1405            0 :             networkState = NetworkState::STALLED;
    1406            0 :             break;
    1407            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_FORMAT_ERROR:
    1408            0 :             networkState = NetworkState::FORMAT_ERROR;
    1409            0 :             break;
    1410            0 :         case firebolt::rialto::NetworkStateChangeEvent_NetworkState_NETWORK_ERROR:
    1411            0 :             networkState = NetworkState::NETWORK_ERROR;
    1412            0 :             break;
    1413            0 :         default:
    1414            0 :             RIALTO_CLIENT_LOG_WARN("Received unknown network state");
    1415            0 :             break;
    1416              :         }
    1417              : 
    1418            1 :         m_mediaPipelineIpcClient->notifyNetworkState(networkState);
    1419              :     }
    1420            2 : }
    1421              : 
    1422            3 : void MediaPipelineIpc::onNeedMediaData(const std::shared_ptr<firebolt::rialto::NeedMediaDataEvent> &event)
    1423              : {
    1424              :     // Ignore event if not for this session
    1425            3 :     if (event->session_id() == m_sessionId)
    1426              :     {
    1427            2 :         std::shared_ptr<MediaPlayerShmInfo> shmInfo;
    1428            2 :         if (event->has_shm_info())
    1429              :         {
    1430            1 :             shmInfo = std::make_shared<MediaPlayerShmInfo>();
    1431            1 :             shmInfo->maxMetadataBytes = event->shm_info().max_metadata_bytes();
    1432            1 :             shmInfo->metadataOffset = event->shm_info().metadata_offset();
    1433            1 :             shmInfo->mediaDataOffset = event->shm_info().media_data_offset();
    1434            1 :             shmInfo->maxMediaBytes = event->shm_info().max_media_bytes();
    1435              :         }
    1436            2 :         m_mediaPipelineIpcClient->notifyNeedMediaData(event->source_id(), event->frame_count(), event->request_id(),
    1437              :                                                       shmInfo);
    1438              :     }
    1439            3 : }
    1440              : 
    1441            2 : void MediaPipelineIpc::onQos(const std::shared_ptr<firebolt::rialto::QosEvent> &event)
    1442              : {
    1443              :     // Ignore event if not for this session
    1444            2 :     if (event->session_id() == m_sessionId)
    1445              :     {
    1446            1 :         QosInfo qosInfo = {event->qos_info().processed(), event->qos_info().dropped()};
    1447            1 :         m_mediaPipelineIpcClient->notifyQos(event->source_id(), qosInfo);
    1448              :     }
    1449            2 : }
    1450              : 
    1451            0 : void MediaPipelineIpc::onBufferUnderflow(const std::shared_ptr<firebolt::rialto::BufferUnderflowEvent> &event)
    1452              : {
    1453              :     // Ignore event if not for this session
    1454            0 :     if (event->session_id() == m_sessionId)
    1455              :     {
    1456            0 :         m_mediaPipelineIpcClient->notifyBufferUnderflow(event->source_id());
    1457              :     }
    1458              : }
    1459              : 
    1460            2 : void MediaPipelineIpc::onPlaybackError(const std::shared_ptr<firebolt::rialto::PlaybackErrorEvent> &event)
    1461              : {
    1462              :     // Ignore event if not for this session
    1463            2 :     if (event->session_id() == m_sessionId)
    1464              :     {
    1465            1 :         PlaybackError playbackError = PlaybackError::UNKNOWN;
    1466            1 :         switch (event->error())
    1467              :         {
    1468            1 :         case firebolt::rialto::PlaybackErrorEvent_PlaybackError_DECRYPTION:
    1469            1 :             playbackError = PlaybackError::DECRYPTION;
    1470            1 :             break;
    1471            0 :         default:
    1472            0 :             RIALTO_CLIENT_LOG_WARN("Received unknown playback error");
    1473            0 :             break;
    1474              :         }
    1475              : 
    1476            1 :         m_mediaPipelineIpcClient->notifyPlaybackError(event->source_id(), playbackError);
    1477              :     }
    1478            2 : }
    1479              : 
    1480            2 : void MediaPipelineIpc::onSourceFlushed(const std::shared_ptr<firebolt::rialto::SourceFlushedEvent> &event)
    1481              : {
    1482              :     // Ignore event if not for this session
    1483            2 :     if (event->session_id() == m_sessionId)
    1484              :     {
    1485            1 :         m_mediaPipelineIpcClient->notifySourceFlushed(event->source_id());
    1486              :     }
    1487            2 : }
    1488              : 
    1489          170 : bool MediaPipelineIpc::createSession(const VideoRequirements &videoRequirements)
    1490              : {
    1491          170 :     if (!reattachChannelIfRequired())
    1492              :     {
    1493            0 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1494            0 :         return false;
    1495              :     }
    1496              : 
    1497          170 :     firebolt::rialto::CreateSessionRequest request;
    1498              : 
    1499          170 :     request.set_max_width(videoRequirements.maxWidth);
    1500          170 :     request.set_max_height(videoRequirements.maxHeight);
    1501              : 
    1502          170 :     firebolt::rialto::CreateSessionResponse response;
    1503          170 :     auto ipcController = m_ipc.createRpcController();
    1504          170 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1505          170 :     m_mediaPipelineStub->createSession(ipcController.get(), &request, &response, blockingClosure.get());
    1506              : 
    1507              :     // wait for the call to complete
    1508          170 :     blockingClosure->wait();
    1509              : 
    1510              :     // check the result
    1511          170 :     if (ipcController->Failed())
    1512              :     {
    1513            1 :         RIALTO_CLIENT_LOG_ERROR("failed to create session due to '%s'", ipcController->ErrorText().c_str());
    1514            1 :         return false;
    1515              :     }
    1516              : 
    1517          169 :     m_sessionId = response.session_id();
    1518              : 
    1519          169 :     return true;
    1520          170 : }
    1521              : 
    1522          169 : void MediaPipelineIpc::destroySession()
    1523              : {
    1524          169 :     if (!reattachChannelIfRequired())
    1525              :     {
    1526            1 :         RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
    1527            1 :         return;
    1528              :     }
    1529              : 
    1530          168 :     firebolt::rialto::DestroySessionRequest request;
    1531          168 :     request.set_session_id(m_sessionId);
    1532              : 
    1533          168 :     firebolt::rialto::DestroySessionResponse response;
    1534          168 :     auto ipcController = m_ipc.createRpcController();
    1535          168 :     auto blockingClosure = m_ipc.createBlockingClosure();
    1536          168 :     m_mediaPipelineStub->destroySession(ipcController.get(), &request, &response, blockingClosure.get());
    1537              : 
    1538              :     // wait for the call to complete
    1539          168 :     blockingClosure->wait();
    1540              : 
    1541              :     // check the result
    1542          168 :     if (ipcController->Failed())
    1543              :     {
    1544            1 :         RIALTO_CLIENT_LOG_ERROR("failed to destroy session due to '%s'", ipcController->ErrorText().c_str());
    1545              :     }
    1546          168 : }
    1547              : 
    1548            3 : firebolt::rialto::LoadRequest_MediaType MediaPipelineIpc::convertLoadRequestMediaType(MediaType mediaType) const
    1549              : {
    1550            3 :     firebolt::rialto::LoadRequest_MediaType protoMediaType = firebolt::rialto::LoadRequest_MediaType_UNKNOWN;
    1551            3 :     switch (mediaType)
    1552              :     {
    1553            3 :     case MediaType::MSE:
    1554            3 :         protoMediaType = firebolt::rialto::LoadRequest_MediaType_MSE;
    1555            3 :         break;
    1556            0 :     default:
    1557            0 :         break;
    1558              :     }
    1559              : 
    1560            3 :     return protoMediaType;
    1561              : }
    1562              : 
    1563              : firebolt::rialto::HaveDataRequest_MediaSourceStatus
    1564            3 : MediaPipelineIpc::convertHaveDataRequestMediaSourceStatus(MediaSourceStatus status) const
    1565              : {
    1566            3 :     firebolt::rialto::HaveDataRequest_MediaSourceStatus protoMediaSourceStatus =
    1567              :         firebolt::rialto::HaveDataRequest_MediaSourceStatus_UNKNOWN;
    1568            3 :     switch (status)
    1569              :     {
    1570            3 :     case MediaSourceStatus::OK:
    1571            3 :         protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_OK;
    1572            3 :         break;
    1573            0 :     case MediaSourceStatus::EOS:
    1574            0 :         protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_EOS;
    1575            0 :         break;
    1576            0 :     case MediaSourceStatus::ERROR:
    1577            0 :         protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_ERROR;
    1578            0 :         break;
    1579            0 :     case MediaSourceStatus::CODEC_CHANGED:
    1580            0 :         protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_CODEC_CHANGED;
    1581            0 :         break;
    1582            0 :     case MediaSourceStatus::NO_AVAILABLE_SAMPLES:
    1583            0 :         protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_NO_AVAILABLE_SAMPLES;
    1584            0 :         break;
    1585            0 :     default:
    1586            0 :         break;
    1587              :     }
    1588              : 
    1589            3 :     return protoMediaSourceStatus;
    1590              : }
    1591              : 
    1592              : firebolt::rialto::AttachSourceRequest_ConfigType
    1593           17 : MediaPipelineIpc::convertConfigType(const firebolt::rialto::SourceConfigType &configType) const
    1594              : {
    1595           17 :     switch (configType)
    1596              :     {
    1597            0 :     case firebolt::rialto::SourceConfigType::UNKNOWN:
    1598              :     {
    1599            0 :         return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_UNKNOWN;
    1600              :     }
    1601            9 :     case firebolt::rialto::SourceConfigType::AUDIO:
    1602              :     {
    1603            9 :         return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_AUDIO;
    1604              :     }
    1605            3 :     case firebolt::rialto::SourceConfigType::VIDEO:
    1606              :     {
    1607            3 :         return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_VIDEO;
    1608              :     }
    1609            3 :     case firebolt::rialto::SourceConfigType::VIDEO_DOLBY_VISION:
    1610              :     {
    1611            3 :         return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_VIDEO_DOLBY_VISION;
    1612              :     }
    1613            2 :     case firebolt::rialto::SourceConfigType::SUBTITLE:
    1614              :     {
    1615            2 :         return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_SUBTITLE;
    1616              :     }
    1617              :     }
    1618            0 :     return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_UNKNOWN;
    1619              : }
    1620              : 
    1621            3 : firebolt::rialto::SetVolumeRequest_EaseType MediaPipelineIpc::convertEaseType(const firebolt::rialto::EaseType &easeType) const
    1622              : {
    1623            3 :     switch (easeType)
    1624              :     {
    1625            3 :     case firebolt::rialto::EaseType::EASE_LINEAR:
    1626              :     {
    1627            3 :         return firebolt::rialto::SetVolumeRequest_EaseType_EASE_LINEAR;
    1628              :     }
    1629            0 :     case firebolt::rialto::EaseType::EASE_IN_CUBIC:
    1630              :     {
    1631            0 :         return firebolt::rialto::SetVolumeRequest_EaseType_EASE_IN_CUBIC;
    1632              :     }
    1633            0 :     case firebolt::rialto::EaseType::EASE_OUT_CUBIC:
    1634              :     {
    1635            0 :         return firebolt::rialto::SetVolumeRequest_EaseType_EASE_OUT_CUBIC;
    1636              :     }
    1637              :     }
    1638            0 :     return firebolt::rialto::SetVolumeRequest_EaseType_EASE_LINEAR;
    1639              : }
    1640              : 
    1641              : firebolt::rialto::AttachSourceRequest_SegmentAlignment
    1642           14 : MediaPipelineIpc::convertSegmentAlignment(const firebolt::rialto::SegmentAlignment &alignment) const
    1643              : {
    1644           14 :     switch (alignment)
    1645              :     {
    1646           14 :     case firebolt::rialto::SegmentAlignment::UNDEFINED:
    1647              :     {
    1648           14 :         return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_UNDEFINED;
    1649              :     }
    1650            0 :     case firebolt::rialto::SegmentAlignment::NAL:
    1651              :     {
    1652            0 :         return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_NAL;
    1653              :     }
    1654            0 :     case firebolt::rialto::SegmentAlignment::AU:
    1655              :     {
    1656            0 :         return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_AU;
    1657              :     }
    1658              :     }
    1659            0 :     return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_UNDEFINED;
    1660              : }
    1661              : 
    1662              : firebolt::rialto::AttachSourceRequest_StreamFormat
    1663           14 : MediaPipelineIpc::convertStreamFormat(const firebolt::rialto::StreamFormat &streamFormat) const
    1664              : {
    1665           14 :     switch (streamFormat)
    1666              :     {
    1667            8 :     case firebolt::rialto::StreamFormat::UNDEFINED:
    1668              :     {
    1669            8 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_UNDEFINED;
    1670              :     }
    1671            6 :     case firebolt::rialto::StreamFormat::RAW:
    1672              :     {
    1673            6 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_RAW;
    1674              :     }
    1675            0 :     case firebolt::rialto::StreamFormat::AVC:
    1676              :     {
    1677            0 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_AVC;
    1678              :     }
    1679            0 :     case firebolt::rialto::StreamFormat::BYTE_STREAM:
    1680              :     {
    1681            0 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_BYTE_STREAM;
    1682              :     }
    1683            0 :     case firebolt::rialto::StreamFormat::HVC1:
    1684              :     {
    1685            0 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_HVC1;
    1686              :     }
    1687            0 :     case firebolt::rialto::StreamFormat::HEV1:
    1688              :     {
    1689            0 :         return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_HEV1;
    1690              :     }
    1691              :     }
    1692            0 :     return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_UNDEFINED;
    1693              : }
    1694              : 
    1695              : firebolt::rialto::AttachSourceRequest_CodecData_Type
    1696            3 : MediaPipelineIpc::convertCodecDataType(const firebolt::rialto::CodecDataType &codecDataType) const
    1697              : {
    1698            3 :     if (firebolt::rialto::CodecDataType::STRING == codecDataType)
    1699              :     {
    1700            0 :         return firebolt::rialto::AttachSourceRequest_CodecData_Type_STRING;
    1701              :     }
    1702            3 :     return firebolt::rialto::AttachSourceRequest_CodecData_Type_BUFFER;
    1703              : }
    1704              : 
    1705              : firebolt::rialto::AttachSourceRequest_AudioConfig_Format
    1706            0 : MediaPipelineIpc::convertFormat(const firebolt::rialto::Format &format) const
    1707              : {
    1708              :     static const std::unordered_map<firebolt::rialto::Format, firebolt::rialto::AttachSourceRequest_AudioConfig_Format>
    1709              :         kFormatConversionMap{
    1710              :             {firebolt::rialto::Format::S8, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S8},
    1711              :             {firebolt::rialto::Format::U8, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U8},
    1712              :             {firebolt::rialto::Format::S16LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S16LE},
    1713              :             {firebolt::rialto::Format::S16BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S16BE},
    1714              :             {firebolt::rialto::Format::U16LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U16LE},
    1715              :             {firebolt::rialto::Format::U16BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U16BE},
    1716              :             {firebolt::rialto::Format::S24_32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24_32LE},
    1717              :             {firebolt::rialto::Format::S24_32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24_32BE},
    1718              :             {firebolt::rialto::Format::U24_32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24_32LE},
    1719              :             {firebolt::rialto::Format::U24_32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24_32BE},
    1720              :             {firebolt::rialto::Format::S32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S32LE},
    1721              :             {firebolt::rialto::Format::S32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S32BE},
    1722              :             {firebolt::rialto::Format::U32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U32LE},
    1723              :             {firebolt::rialto::Format::U32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U32BE},
    1724              :             {firebolt::rialto::Format::S24LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24LE},
    1725              :             {firebolt::rialto::Format::S24BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24BE},
    1726              :             {firebolt::rialto::Format::U24LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24LE},
    1727              :             {firebolt::rialto::Format::U24BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24BE},
    1728              :             {firebolt::rialto::Format::S20LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S20LE},
    1729              :             {firebolt::rialto::Format::S20BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S20BE},
    1730              :             {firebolt::rialto::Format::U20LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U20LE},
    1731              :             {firebolt::rialto::Format::U20BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U20BE},
    1732              :             {firebolt::rialto::Format::S18LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S18LE},
    1733              :             {firebolt::rialto::Format::S18BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S18BE},
    1734              :             {firebolt::rialto::Format::U18LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U18LE},
    1735              :             {firebolt::rialto::Format::U18BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U18BE},
    1736              :             {firebolt::rialto::Format::F32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F32LE},
    1737              :             {firebolt::rialto::Format::F32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F32BE},
    1738              :             {firebolt::rialto::Format::F64LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F64LE},
    1739            0 :             {firebolt::rialto::Format::F64BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F64BE}};
    1740            0 :     const auto kIt = kFormatConversionMap.find(format);
    1741            0 :     if (kFormatConversionMap.end() != kIt)
    1742              :     {
    1743            0 :         return kIt->second;
    1744              :     }
    1745            0 :     return firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S8;
    1746              : }
    1747              : 
    1748              : firebolt::rialto::AttachSourceRequest_AudioConfig_Layout
    1749            0 : MediaPipelineIpc::convertLayout(const firebolt::rialto::Layout &layout) const
    1750              : {
    1751              :     static const std::unordered_map<firebolt::rialto::Layout, firebolt::rialto::AttachSourceRequest_AudioConfig_Layout>
    1752              :         kLayoutConversionMap{{firebolt::rialto::Layout::INTERLEAVED,
    1753              :                               firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_INTERLEAVED},
    1754              :                              {firebolt::rialto::Layout::NON_INTERLEAVED,
    1755            0 :                               firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_NON_INTERLEAVED}};
    1756            0 :     const auto kIt = kLayoutConversionMap.find(layout);
    1757            0 :     if (kLayoutConversionMap.end() != kIt)
    1758              :     {
    1759            0 :         return kIt->second;
    1760              :     }
    1761            0 :     return firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_INTERLEAVED;
    1762              : }
    1763              : 
    1764           17 : bool MediaPipelineIpc::buildAttachSourceRequest(firebolt::rialto::AttachSourceRequest &request,
    1765              :                                                 const std::unique_ptr<IMediaPipeline::MediaSource> &source) const
    1766              : {
    1767           17 :     SourceConfigType configType = source->getConfigType();
    1768           17 :     request.set_config_type(convertConfigType(configType));
    1769           34 :     request.set_mime_type(source->getMimeType());
    1770           17 :     request.set_has_drm(source->getHasDrm());
    1771              : 
    1772           17 :     if (configType == SourceConfigType::VIDEO_DOLBY_VISION || configType == SourceConfigType::VIDEO ||
    1773           11 :         configType == SourceConfigType::AUDIO)
    1774              :     {
    1775           15 :         IMediaPipeline::MediaSourceAV *mediaSourceAV = dynamic_cast<IMediaPipeline::MediaSourceAV *>(source.get());
    1776           15 :         if (!mediaSourceAV)
    1777              :         {
    1778            1 :             RIALTO_CLIENT_LOG_ERROR("Failed to get the audio video source");
    1779            1 :             return false;
    1780              :         }
    1781           14 :         request.set_segment_alignment(convertSegmentAlignment(mediaSourceAV->getSegmentAlignment()));
    1782              : 
    1783           14 :         if (mediaSourceAV->getCodecData())
    1784              :         {
    1785            6 :             request.mutable_codec_data()->set_data(mediaSourceAV->getCodecData()->data.data(),
    1786            3 :                                                    mediaSourceAV->getCodecData()->data.size());
    1787            3 :             request.mutable_codec_data()->set_type(convertCodecDataType(mediaSourceAV->getCodecData()->type));
    1788              :         }
    1789           14 :         request.set_stream_format(convertStreamFormat(mediaSourceAV->getStreamFormat()));
    1790              : 
    1791           14 :         if (configType == SourceConfigType::VIDEO_DOLBY_VISION)
    1792              :         {
    1793              :             IMediaPipeline::MediaSourceVideoDolbyVision *mediaSourceDolby =
    1794            2 :                 dynamic_cast<IMediaPipeline::MediaSourceVideoDolbyVision *>(source.get());
    1795            2 :             if (!mediaSourceDolby)
    1796              :             {
    1797            1 :                 RIALTO_CLIENT_LOG_ERROR("Failed to get the video dolby vision media source");
    1798            1 :                 return false;
    1799              :             }
    1800            1 :             request.set_width(mediaSourceDolby->getWidth());
    1801            1 :             request.set_height(mediaSourceDolby->getHeight());
    1802            1 :             request.set_dolby_vision_profile(mediaSourceDolby->getDolbyVisionProfile());
    1803              :         }
    1804           12 :         else if (configType == SourceConfigType::VIDEO)
    1805              :         {
    1806              :             IMediaPipeline::MediaSourceVideo *mediaSourceVideo =
    1807            3 :                 dynamic_cast<IMediaPipeline::MediaSourceVideo *>(source.get());
    1808            3 :             if (!mediaSourceVideo)
    1809              :             {
    1810            1 :                 RIALTO_CLIENT_LOG_ERROR("Failed to get the video media source");
    1811            1 :                 return false;
    1812              :             }
    1813            2 :             request.set_width(mediaSourceVideo->getWidth());
    1814            2 :             request.set_height(mediaSourceVideo->getHeight());
    1815              :         }
    1816            9 :         else if (configType == SourceConfigType::AUDIO)
    1817              :         {
    1818              :             IMediaPipeline::MediaSourceAudio *mediaSourceAudio =
    1819            9 :                 dynamic_cast<IMediaPipeline::MediaSourceAudio *>(source.get());
    1820            9 :             if (!mediaSourceAudio)
    1821              :             {
    1822            2 :                 RIALTO_CLIENT_LOG_ERROR("Failed to get the audio media source");
    1823            2 :                 return false;
    1824              :             }
    1825            7 :             request.mutable_audio_config()->set_number_of_channels(mediaSourceAudio->getAudioConfig().numberOfChannels);
    1826            7 :             request.mutable_audio_config()->set_sample_rate(mediaSourceAudio->getAudioConfig().sampleRate);
    1827            7 :             if (!mediaSourceAudio->getAudioConfig().codecSpecificConfig.empty())
    1828              :             {
    1829              :                 request.mutable_audio_config()
    1830            9 :                     ->set_codec_specific_config(mediaSourceAudio->getAudioConfig().codecSpecificConfig.data(),
    1831            3 :                                                 mediaSourceAudio->getAudioConfig().codecSpecificConfig.size());
    1832              :             }
    1833            7 :             if (mediaSourceAudio->getAudioConfig().format.has_value())
    1834              :             {
    1835            0 :                 request.mutable_audio_config()->set_format(
    1836            0 :                     convertFormat(mediaSourceAudio->getAudioConfig().format.value()));
    1837              :             }
    1838            7 :             if (mediaSourceAudio->getAudioConfig().layout.has_value())
    1839              :             {
    1840            0 :                 request.mutable_audio_config()->set_layout(
    1841            0 :                     convertLayout(mediaSourceAudio->getAudioConfig().layout.value()));
    1842              :             }
    1843            7 :             if (mediaSourceAudio->getAudioConfig().channelMask.has_value())
    1844              :             {
    1845            0 :                 request.mutable_audio_config()->set_channel_mask(mediaSourceAudio->getAudioConfig().channelMask.value());
    1846              :             }
    1847              :         }
    1848           10 :     }
    1849            2 :     else if (configType == SourceConfigType::SUBTITLE)
    1850              :     {
    1851              :         IMediaPipeline::MediaSourceSubtitle *mediaSourceSubtitle =
    1852            2 :             dynamic_cast<IMediaPipeline::MediaSourceSubtitle *>(source.get());
    1853            2 :         if (!mediaSourceSubtitle)
    1854              :         {
    1855            1 :             RIALTO_CLIENT_LOG_ERROR("Failed to get the subtitle source");
    1856            1 :             return false;
    1857              :         }
    1858            1 :         request.set_text_track_identifier(mediaSourceSubtitle->getTextTrackIdentifier());
    1859              :     }
    1860              :     else
    1861              :     {
    1862            0 :         RIALTO_CLIENT_LOG_ERROR("Unknown source type");
    1863            0 :         return false;
    1864              :     }
    1865           11 :     return true;
    1866              : }
    1867              : }; // namespace firebolt::rialto::client
        

Generated by: LCOV version 2.0-1