LCOV - code coverage report
Current view: top level - media/server/ipc/source - MediaPipelineModuleService.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.3 % 580 495
Test Date: 2026-10-23 12:56:16 Functions: 96.5 % 57 55

            Line data    Source code
       1              : /*
       2              :  * If not stated otherwise in this file or this component's LICENSE file the
       3              :  * following copyright and licenses apply:
       4              :  *
       5              :  * Copyright 2022 Sky UK
       6              :  *
       7              :  * Licensed under the Apache License, Version 2.0 (the "License");
       8              :  * you may not use this file except in compliance with the License.
       9              :  * You may obtain a copy of the License at
      10              :  *
      11              :  * http://www.apache.org/licenses/LICENSE-2.0
      12              :  *
      13              :  * Unless required by applicable law or agreed to in writing, software
      14              :  * distributed under the License is distributed on an "AS IS" BASIS,
      15              :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      16              :  * See the License for the specific language governing permissions and
      17              :  * limitations under the License.
      18              :  */
      19              : 
      20              : #include "MediaPipelineModuleService.h"
      21              : #include "IMediaPipelineService.h"
      22              : #include "IPrivateMetricsModuleService.h"
      23              : #include "MediaPipelineClient.h"
      24              : #include "RialtoCommonModule.h"
      25              : #include "RialtoServerLogging.h"
      26              : #include <IIpcController.h>
      27              : #include <algorithm>
      28              : #include <cstdint>
      29              : #include <optional>
      30              : #include <unordered_map>
      31              : #include <utility>
      32              : 
      33              : namespace
      34              : {
      35           38 : int generateSessionId()
      36              : {
      37              :     static int sessionId{0};
      38           38 :     return sessionId++;
      39              : }
      40              : 
      41            2 : firebolt::rialto::MediaType convertMediaType(const firebolt::rialto::LoadRequest_MediaType &mediaType)
      42              : {
      43            2 :     switch (mediaType)
      44              :     {
      45            0 :     case firebolt::rialto::LoadRequest_MediaType::LoadRequest_MediaType_UNKNOWN:
      46              :     {
      47            0 :         return firebolt::rialto::MediaType::UNKNOWN;
      48              :     }
      49            2 :     case firebolt::rialto::LoadRequest_MediaType::LoadRequest_MediaType_MSE:
      50              :     {
      51            2 :         return firebolt::rialto::MediaType::MSE;
      52              :     }
      53              :     }
      54            0 :     return firebolt::rialto::MediaType::UNKNOWN;
      55              : }
      56              : 
      57            2 : firebolt::rialto::EaseType convertEaseType(const firebolt::rialto::SetVolumeRequest_EaseType &easeType)
      58              : {
      59            2 :     switch (easeType)
      60              :     {
      61            2 :     case firebolt::rialto::SetVolumeRequest_EaseType::SetVolumeRequest_EaseType_EASE_LINEAR:
      62              :     {
      63            2 :         return firebolt::rialto::EaseType::EASE_LINEAR;
      64              :     }
      65            0 :     case firebolt::rialto::SetVolumeRequest_EaseType::SetVolumeRequest_EaseType_EASE_IN_CUBIC:
      66              :     {
      67            0 :         return firebolt::rialto::EaseType::EASE_IN_CUBIC;
      68              :     }
      69            0 :     case firebolt::rialto::SetVolumeRequest_EaseType::SetVolumeRequest_EaseType_EASE_OUT_CUBIC:
      70              :     {
      71            0 :         return firebolt::rialto::EaseType::EASE_OUT_CUBIC;
      72              :     }
      73              :     }
      74            0 :     return firebolt::rialto::EaseType::EASE_LINEAR;
      75              : }
      76              : 
      77              : firebolt::rialto::MediaSourceStatus
      78            2 : convertMediaSourceStatus(const firebolt::rialto::HaveDataRequest_MediaSourceStatus &status)
      79              : {
      80            2 :     switch (status)
      81              :     {
      82            0 :     case firebolt::rialto::HaveDataRequest_MediaSourceStatus_UNKNOWN:
      83              :     {
      84            0 :         return firebolt::rialto::MediaSourceStatus::ERROR;
      85              :     }
      86            0 :     case firebolt::rialto::HaveDataRequest_MediaSourceStatus_OK:
      87              :     {
      88            0 :         return firebolt::rialto::MediaSourceStatus::OK;
      89              :     }
      90            0 :     case firebolt::rialto::HaveDataRequest_MediaSourceStatus_EOS:
      91              :     {
      92            0 :         return firebolt::rialto::MediaSourceStatus::EOS;
      93              :     }
      94            0 :     case firebolt::rialto::HaveDataRequest_MediaSourceStatus_ERROR:
      95              :     {
      96            0 :         return firebolt::rialto::MediaSourceStatus::ERROR;
      97              :     }
      98            2 :     case firebolt::rialto::HaveDataRequest_MediaSourceStatus_CODEC_CHANGED:
      99              :     {
     100            2 :         return firebolt::rialto::MediaSourceStatus::CODEC_CHANGED;
     101              :     }
     102            0 :     case firebolt::rialto::HaveDataRequest_MediaSourceStatus_NO_AVAILABLE_SAMPLES:
     103              :     {
     104            0 :         return firebolt::rialto::MediaSourceStatus::NO_AVAILABLE_SAMPLES;
     105              :     }
     106            0 :     case firebolt::rialto::HaveDataRequest_MediaSourceStatus_NO_SPACE_FOR_SAMPLES:
     107              :     {
     108            0 :         return firebolt::rialto::MediaSourceStatus::NO_SPACE_FOR_SAMPLES;
     109              :     }
     110              :     }
     111            0 :     return firebolt::rialto::MediaSourceStatus::ERROR;
     112              : }
     113              : 
     114           24 : firebolt::rialto::SourceConfigType convertConfigType(const firebolt::rialto::AttachSourceRequest_ConfigType &configType)
     115              : {
     116           24 :     switch (configType)
     117              :     {
     118            1 :     case firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_UNKNOWN:
     119              :     {
     120            1 :         return firebolt::rialto::SourceConfigType::UNKNOWN;
     121              :     }
     122           14 :     case firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_AUDIO:
     123              :     {
     124           14 :         return firebolt::rialto::SourceConfigType::AUDIO;
     125              :     }
     126            7 :     case firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_VIDEO:
     127              :     {
     128            7 :         return firebolt::rialto::SourceConfigType::VIDEO;
     129              :     }
     130            1 :     case firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_VIDEO_DOLBY_VISION:
     131              :     {
     132            1 :         return firebolt::rialto::SourceConfigType::VIDEO_DOLBY_VISION;
     133              :     }
     134            1 :     case firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_SUBTITLE:
     135              :     {
     136            1 :         return firebolt::rialto::SourceConfigType::SUBTITLE;
     137              :     }
     138              :     }
     139            0 :     return firebolt::rialto::SourceConfigType::UNKNOWN;
     140              : }
     141              : 
     142              : firebolt::rialto::SegmentAlignment
     143           22 : convertSegmentAlignment(const firebolt::rialto::AttachSourceRequest_SegmentAlignment &alignment)
     144              : {
     145           22 :     switch (alignment)
     146              :     {
     147           22 :     case firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_UNDEFINED:
     148              :     {
     149           22 :         return firebolt::rialto::SegmentAlignment::UNDEFINED;
     150              :     }
     151            0 :     case firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_NAL:
     152              :     {
     153            0 :         return firebolt::rialto::SegmentAlignment::NAL;
     154              :     }
     155            0 :     case firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_AU:
     156              :     {
     157            0 :         return firebolt::rialto::SegmentAlignment::AU;
     158              :     }
     159              :     }
     160              : 
     161            0 :     return firebolt::rialto::SegmentAlignment::UNDEFINED;
     162              : }
     163              : 
     164           22 : firebolt::rialto::StreamFormat convertStreamFormat(const firebolt::rialto::AttachSourceRequest_StreamFormat &streamFormat)
     165              : {
     166           22 :     switch (streamFormat)
     167              :     {
     168            1 :     case firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_RAW:
     169              :     {
     170            1 :         return firebolt::rialto::StreamFormat::RAW;
     171              :     }
     172            0 :     case firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_AVC:
     173              :     {
     174            0 :         return firebolt::rialto::StreamFormat::AVC;
     175              :     }
     176            0 :     case firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_BYTE_STREAM:
     177              :     {
     178            0 :         return firebolt::rialto::StreamFormat::BYTE_STREAM;
     179              :     }
     180            0 :     case firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_HVC1:
     181              :     {
     182            0 :         return firebolt::rialto::StreamFormat::HVC1;
     183              :     }
     184            0 :     case firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_HEV1:
     185              :     {
     186            0 :         return firebolt::rialto::StreamFormat::HEV1;
     187              :     }
     188           21 :     default:
     189           21 :         return firebolt::rialto::StreamFormat::UNDEFINED;
     190              :     }
     191              : }
     192              : 
     193            1 : firebolt::rialto::CodecDataType convertCodecDataType(const firebolt::rialto::AttachSourceRequest_CodecData_Type &type)
     194              : {
     195            1 :     if (firebolt::rialto::AttachSourceRequest_CodecData_Type_STRING == type)
     196              :     {
     197            0 :         return firebolt::rialto::CodecDataType::STRING;
     198              :     }
     199            1 :     return firebolt::rialto::CodecDataType::BUFFER;
     200              : }
     201              : 
     202            1 : firebolt::rialto::Format convertFormat(const firebolt::rialto::AttachSourceRequest_AudioConfig_Format &format)
     203              : {
     204              :     static const std::unordered_map<firebolt::rialto::AttachSourceRequest_AudioConfig_Format, firebolt::rialto::Format>
     205              :         kFormatConversionMap{
     206              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S8, firebolt::rialto::Format::S8},
     207              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U8, firebolt::rialto::Format::U8},
     208              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S16LE, firebolt::rialto::Format::S16LE},
     209              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S16BE, firebolt::rialto::Format::S16BE},
     210              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U16LE, firebolt::rialto::Format::U16LE},
     211              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U16BE, firebolt::rialto::Format::U16BE},
     212              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24_32LE, firebolt::rialto::Format::S24_32LE},
     213              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24_32BE, firebolt::rialto::Format::S24_32BE},
     214              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24_32LE, firebolt::rialto::Format::U24_32LE},
     215              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24_32BE, firebolt::rialto::Format::U24_32BE},
     216              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S32LE, firebolt::rialto::Format::S32LE},
     217              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S32BE, firebolt::rialto::Format::S32BE},
     218              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U32LE, firebolt::rialto::Format::U32LE},
     219              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U32BE, firebolt::rialto::Format::U32BE},
     220              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24LE, firebolt::rialto::Format::S24LE},
     221              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24BE, firebolt::rialto::Format::S24BE},
     222              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24LE, firebolt::rialto::Format::U24LE},
     223              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24BE, firebolt::rialto::Format::U24BE},
     224              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S20LE, firebolt::rialto::Format::S20LE},
     225              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S20BE, firebolt::rialto::Format::S20BE},
     226              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U20LE, firebolt::rialto::Format::U20LE},
     227              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U20BE, firebolt::rialto::Format::U20BE},
     228              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S18LE, firebolt::rialto::Format::S18LE},
     229              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S18BE, firebolt::rialto::Format::S18BE},
     230              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U18LE, firebolt::rialto::Format::U18LE},
     231              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U18BE, firebolt::rialto::Format::U18BE},
     232              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F32LE, firebolt::rialto::Format::F32LE},
     233              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F32BE, firebolt::rialto::Format::F32BE},
     234              :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F64LE, firebolt::rialto::Format::F64LE},
     235            3 :             {firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F64BE, firebolt::rialto::Format::F64BE}};
     236            1 :     const auto kIt = kFormatConversionMap.find(format);
     237            1 :     if (kFormatConversionMap.end() != kIt)
     238              :     {
     239            1 :         return kIt->second;
     240              :     }
     241            0 :     return firebolt::rialto::Format::S8;
     242              : }
     243              : 
     244            1 : firebolt::rialto::Layout convertLayout(const firebolt::rialto::AttachSourceRequest_AudioConfig_Layout &layout)
     245              : {
     246              :     static const std::unordered_map<firebolt::rialto::AttachSourceRequest_AudioConfig_Layout, firebolt::rialto::Layout>
     247              :         kLayoutConversionMap{{firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_INTERLEAVED,
     248              :                               firebolt::rialto::Layout::INTERLEAVED},
     249              :                              {firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_NON_INTERLEAVED,
     250            3 :                               firebolt::rialto::Layout::NON_INTERLEAVED}};
     251            1 :     const auto kIt = kLayoutConversionMap.find(layout);
     252            1 :     if (kLayoutConversionMap.end() != kIt)
     253              :     {
     254            1 :         return kIt->second;
     255              :     }
     256            0 :     return firebolt::rialto::Layout::INTERLEAVED;
     257              : }
     258              : } // namespace
     259              : 
     260              : namespace firebolt::rialto::server::ipc
     261              : {
     262            1 : std::shared_ptr<IMediaPipelineModuleServiceFactory> IMediaPipelineModuleServiceFactory::createFactory()
     263              : {
     264            1 :     std::shared_ptr<IMediaPipelineModuleServiceFactory> factory;
     265              : 
     266              :     try
     267              :     {
     268            1 :         factory = std::make_shared<MediaPipelineModuleServiceFactory>();
     269              :     }
     270            0 :     catch (const std::exception &e)
     271              :     {
     272            0 :         RIALTO_SERVER_LOG_ERROR("Failed to create the media player module service factory, reason: %s", e.what());
     273              :     }
     274              : 
     275            1 :     return factory;
     276              : }
     277              : 
     278              : std::shared_ptr<IMediaPipelineModuleService>
     279            1 : MediaPipelineModuleServiceFactory::create(service::IMediaPipelineService &mediaPipelineService) const
     280              : {
     281            1 :     std::shared_ptr<IMediaPipelineModuleService> mediaPipelineModule;
     282              : 
     283              :     try
     284              :     {
     285            1 :         mediaPipelineModule = std::make_shared<MediaPipelineModuleService>(mediaPipelineService);
     286              :     }
     287            0 :     catch (const std::exception &e)
     288              :     {
     289            0 :         RIALTO_SERVER_LOG_ERROR("Failed to create the media player module service, reason: %s", e.what());
     290              :     }
     291              : 
     292            1 :     return mediaPipelineModule;
     293              : }
     294              : 
     295          104 : MediaPipelineModuleService::MediaPipelineModuleService(service::IMediaPipelineService &mediaPipelineService)
     296          104 :     : m_mediaPipelineService{mediaPipelineService}
     297              : {
     298              : }
     299              : 
     300              : MediaPipelineModuleService::~MediaPipelineModuleService() {}
     301              : 
     302            2 : void MediaPipelineModuleService::clientConnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &ipcClient)
     303              : {
     304            2 :     RIALTO_SERVER_LOG_INFO("Client Connected!");
     305              :     {
     306            2 :         m_clientSessions.emplace(ipcClient, std::set<int>());
     307              :     }
     308            2 :     ipcClient->exportService(shared_from_this());
     309              : }
     310              : 
     311            1 : void MediaPipelineModuleService::clientDisconnected(const std::shared_ptr<::firebolt::rialto::ipc::IClient> &ipcClient)
     312              : {
     313            1 :     RIALTO_SERVER_LOG_INFO("Client disconnected!");
     314            1 :     std::set<int> sessionIds;
     315              :     {
     316            1 :         auto sessionIter = m_clientSessions.find(ipcClient);
     317            1 :         if (sessionIter == m_clientSessions.end())
     318              :         {
     319            0 :             RIALTO_SERVER_LOG_ERROR("unknown client disconnected");
     320            0 :             return;
     321              :         }
     322            1 :         sessionIds = sessionIter->second; // copy to avoid deadlock
     323            1 :         m_clientSessions.erase(sessionIter);
     324              :     }
     325            2 :     for (const auto &sessionId : sessionIds)
     326              :     {
     327            1 :         m_mediaPipelineService.destroySession(sessionId);
     328            1 :         m_sessionSources.erase(sessionId);
     329            1 :         m_sessionImmediateOutput.erase(sessionId);
     330              :     }
     331              : }
     332              : 
     333           38 : void MediaPipelineModuleService::createSession(::google::protobuf::RpcController *controller,
     334              :                                                const ::firebolt::rialto::CreateSessionRequest *request,
     335              :                                                ::firebolt::rialto::CreateSessionResponse *response,
     336              :                                                ::google::protobuf::Closure *done)
     337              : {
     338           38 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     339           38 :     auto ipcController = dynamic_cast<firebolt::rialto::ipc::IController *>(controller);
     340           38 :     if (!ipcController)
     341              :     {
     342            0 :         RIALTO_SERVER_LOG_ERROR("ipc library provided incompatible controller object");
     343            0 :         controller->SetFailed("ipc library provided incompatible controller object");
     344            0 :         done->Run();
     345            0 :         return;
     346              :     }
     347              : 
     348           38 :     int sessionId = generateSessionId();
     349              :     bool sessionCreated =
     350           76 :         m_mediaPipelineService.createSession(sessionId,
     351           76 :                                              std::make_shared<MediaPipelineClient>(sessionId, ipcController->getClient()),
     352              :                                              request->max_width(), request->max_height());
     353           38 :     if (sessionCreated)
     354              :     {
     355              :         // Assume that IPC library works well and client is present
     356           37 :         m_clientSessions[ipcController->getClient()].insert(sessionId);
     357           37 :         m_sessionSources.emplace(sessionId, std::map<int32_t, MediaSourceType>{});
     358           37 :         response->set_session_id(sessionId);
     359              :     }
     360              :     else
     361              :     {
     362            1 :         RIALTO_SERVER_LOG_ERROR("Create session failed");
     363            3 :         controller->SetFailed("Operation failed");
     364              :     }
     365           38 :     done->Run();
     366              : }
     367              : 
     368            2 : void MediaPipelineModuleService::destroySession(::google::protobuf::RpcController *controller,
     369              :                                                 const ::firebolt::rialto::DestroySessionRequest *request,
     370              :                                                 ::firebolt::rialto::DestroySessionResponse *response,
     371              :                                                 ::google::protobuf::Closure *done)
     372              : {
     373            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     374            2 :     auto ipcController = dynamic_cast<firebolt::rialto::ipc::IController *>(controller);
     375            2 :     if (!ipcController)
     376              :     {
     377            0 :         RIALTO_SERVER_LOG_ERROR("ipc library provided incompatible controller object");
     378            0 :         controller->SetFailed("ipc library provided incompatible controller object");
     379            0 :         done->Run();
     380            1 :         return;
     381              :     }
     382              : 
     383            2 :     if (!m_mediaPipelineService.destroySession(request->session_id()))
     384              :     {
     385            1 :         RIALTO_SERVER_LOG_ERROR("Destroy session failed");
     386            2 :         controller->SetFailed("Operation failed");
     387            1 :         done->Run();
     388            1 :         return;
     389              :     }
     390            1 :     auto sessionIter = m_clientSessions.find(ipcController->getClient());
     391            1 :     if (sessionIter != m_clientSessions.end())
     392              :     {
     393            0 :         sessionIter->second.erase(request->session_id());
     394              :     }
     395            1 :     m_sessionSources.erase(request->session_id());
     396            1 :     m_sessionImmediateOutput.erase(request->session_id());
     397            1 :     done->Run();
     398              : }
     399              : 
     400            2 : void MediaPipelineModuleService::load(::google::protobuf::RpcController *controller,
     401              :                                       const ::firebolt::rialto::LoadRequest *request,
     402              :                                       ::firebolt::rialto::LoadResponse *response, ::google::protobuf::Closure *done)
     403              : {
     404            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     405            2 :     if (!m_mediaPipelineService.load(request->session_id(), convertMediaType(request->type()), request->mime_type(),
     406            2 :                                      request->url(), request->is_live()))
     407              :     {
     408            1 :         RIALTO_SERVER_LOG_ERROR("Load failed");
     409            3 :         controller->SetFailed("Operation failed");
     410              :     }
     411            2 :     done->Run();
     412              : }
     413              : 
     414            2 : void MediaPipelineModuleService::setVideoWindow(::google::protobuf::RpcController *controller,
     415              :                                                 const ::firebolt::rialto::SetVideoWindowRequest *request,
     416              :                                                 ::firebolt::rialto::SetVideoWindowResponse *response,
     417              :                                                 ::google::protobuf::Closure *done)
     418              : {
     419            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     420            2 :     if (!m_mediaPipelineService.setVideoWindow(request->session_id(), request->x(), request->y(), request->width(),
     421              :                                                request->height()))
     422              :     {
     423            1 :         RIALTO_SERVER_LOG_ERROR("Set Video Window failed");
     424            3 :         controller->SetFailed("Operation failed");
     425              :     }
     426            2 :     done->Run();
     427              : }
     428              : 
     429           24 : void MediaPipelineModuleService::attachSource(::google::protobuf::RpcController *controller,
     430              :                                               const ::firebolt::rialto::AttachSourceRequest *request,
     431              :                                               ::firebolt::rialto::AttachSourceResponse *response,
     432              :                                               ::google::protobuf::Closure *done)
     433              : {
     434           24 :     RIALTO_SERVER_LOG_DEBUG("mime_type: %s", request->mime_type().c_str());
     435              : 
     436           24 :     std::shared_ptr<CodecData> codecData{};
     437           24 :     if (request->has_codec_data())
     438              :     {
     439            1 :         const auto &kCodecDataProto = request->codec_data();
     440            1 :         codecData = std::make_shared<CodecData>();
     441            1 :         codecData->data = std::vector<std::uint8_t>(kCodecDataProto.data().begin(), kCodecDataProto.data().end());
     442            1 :         codecData->type = convertCodecDataType(kCodecDataProto.type());
     443              :     }
     444           24 :     std::unique_ptr<IMediaPipeline::MediaSource> mediaSource;
     445           24 :     firebolt::rialto::SourceConfigType configType = convertConfigType(request->config_type());
     446           24 :     bool hasDrm = request->has_drm();
     447              : 
     448           24 :     if (configType == firebolt::rialto::SourceConfigType::AUDIO)
     449              :     {
     450           14 :         const auto &kConfig = request->audio_config();
     451           14 :         uint32_t numberofchannels = kConfig.number_of_channels();
     452           14 :         uint32_t sampleRate = kConfig.sample_rate();
     453              : 
     454           14 :         std::vector<uint8_t> codecSpecificConfig;
     455           14 :         if (kConfig.has_codec_specific_config())
     456              :         {
     457            1 :             auto codecSpecificConfigStr = kConfig.codec_specific_config();
     458            1 :             codecSpecificConfig.assign(codecSpecificConfigStr.begin(), codecSpecificConfigStr.end());
     459              :         }
     460           14 :         std::optional<firebolt::rialto::Format> format{std::nullopt};
     461           14 :         if (kConfig.has_format())
     462              :         {
     463            1 :             format = convertFormat(kConfig.format());
     464              :         }
     465           14 :         std::optional<firebolt::rialto::Layout> layout{std::nullopt};
     466           14 :         if (kConfig.has_layout())
     467              :         {
     468            1 :             layout = convertLayout(kConfig.layout());
     469              :         }
     470           14 :         std::optional<uint64_t> channelMask{std::nullopt};
     471           14 :         if (kConfig.has_channel_mask())
     472              :         {
     473            1 :             channelMask = kConfig.channel_mask();
     474              :         }
     475           14 :         std::vector<std::vector<uint8_t>> streamHeaders;
     476           15 :         for (int i = 0; i < kConfig.stream_header_size(); ++i)
     477              :         {
     478            1 :             auto streamHeaderStr = kConfig.stream_header(i);
     479            2 :             streamHeaders.push_back(std::vector<uint8_t>{streamHeaderStr.begin(), streamHeaderStr.end()});
     480            1 :         }
     481           14 :         std::optional<bool> framed;
     482           14 :         if (kConfig.has_framed())
     483              :         {
     484            1 :             framed = kConfig.framed();
     485              :         }
     486           14 :         AudioConfig audioConfig{numberofchannels, sampleRate,  std::move(codecSpecificConfig), format,
     487           14 :                                 layout,           channelMask, std::move(streamHeaders),       framed};
     488              : 
     489              :         mediaSource =
     490           28 :             std::make_unique<IMediaPipeline::MediaSourceAudio>(request->mime_type(), hasDrm, audioConfig,
     491           14 :                                                                convertSegmentAlignment(request->segment_alignment()),
     492           28 :                                                                convertStreamFormat(request->stream_format()), codecData);
     493           14 :     }
     494           10 :     else if (configType == firebolt::rialto::SourceConfigType::VIDEO)
     495              :     {
     496              :         mediaSource =
     497           14 :             std::make_unique<IMediaPipeline::MediaSourceVideo>(request->mime_type().c_str(), hasDrm, request->width(),
     498            7 :                                                                request->height(),
     499            7 :                                                                convertSegmentAlignment(request->segment_alignment()),
     500           21 :                                                                convertStreamFormat(request->stream_format()), codecData);
     501              :     }
     502            3 :     else if (configType == firebolt::rialto::SourceConfigType::VIDEO_DOLBY_VISION)
     503              :     {
     504              :         mediaSource =
     505            2 :             std::make_unique<IMediaPipeline::MediaSourceVideoDolbyVision>(request->mime_type().c_str(),
     506            1 :                                                                           request->dolby_vision_profile(), hasDrm,
     507            1 :                                                                           request->width(), request->height(),
     508            1 :                                                                           convertSegmentAlignment(
     509            1 :                                                                               request->segment_alignment()),
     510            2 :                                                                           convertStreamFormat(request->stream_format()),
     511            1 :                                                                           codecData);
     512              :     }
     513            2 :     else if (configType == firebolt::rialto::SourceConfigType::SUBTITLE)
     514              :     {
     515            2 :         mediaSource = std::make_unique<IMediaPipeline::MediaSourceSubtitle>(request->mime_type().c_str(),
     516            2 :                                                                             request->text_track_identifier());
     517              :     }
     518              :     else
     519              :     {
     520            1 :         RIALTO_SERVER_LOG_ERROR("Unknown source type");
     521            2 :         controller->SetFailed("Operation failed");
     522            1 :         done->Run();
     523            1 :         return;
     524              :     }
     525              : 
     526           23 :     bool sourceAttached{false};
     527           23 :     if (!request->has_switch_source() || !request->switch_source())
     528              :     {
     529           20 :         RIALTO_SERVER_LOG_DEBUG("Attaching source");
     530           20 :         sourceAttached = m_mediaPipelineService.attachSource(request->session_id(), mediaSource);
     531           20 :         if (!sourceAttached)
     532              :         {
     533            1 :             RIALTO_SERVER_LOG_ERROR("Attach source failed");
     534            3 :             controller->SetFailed("Operation failed");
     535              :         }
     536              :     }
     537              :     else
     538              :     {
     539            3 :         RIALTO_SERVER_LOG_DEBUG("Switching source");
     540            3 :         const auto sessionSourcesIter = m_sessionSources.find(request->session_id());
     541            3 :         if (sessionSourcesIter != m_sessionSources.end())
     542              :         {
     543              :             const auto existingSourceIter =
     544            1 :                 std::find_if(sessionSourcesIter->second.begin(), sessionSourcesIter->second.end(),
     545            2 :                              [&mediaSource](const auto &source) { return source.second == mediaSource->getType(); });
     546            1 :             if (existingSourceIter != sessionSourcesIter->second.end())
     547              :             {
     548            1 :                 mediaSource->setId(existingSourceIter->first);
     549              :             }
     550              :             else
     551              :             {
     552            0 :                 RIALTO_SERVER_LOG_WARN("Switching source with no tracked source id");
     553              :             }
     554              :         }
     555            3 :         sourceAttached = m_mediaPipelineService.switchSource(request->session_id(), mediaSource);
     556            3 :         if (!sourceAttached)
     557              :         {
     558            1 :             RIALTO_SERVER_LOG_ERROR("Switch source failed");
     559            3 :             controller->SetFailed("Operation failed");
     560              :         }
     561              :     }
     562           23 :     if (sourceAttached)
     563              :     {
     564           21 :         if (!request->has_switch_source() || !request->switch_source())
     565              :         {
     566           19 :             auto &sessionSources = m_sessionSources[request->session_id()];
     567           19 :             sessionSources[mediaSource->getId()] = mediaSource->getType();
     568              :         }
     569              : 
     570           21 :         if (mediaSource->getType() == MediaSourceType::AUDIO)
     571              :         {
     572           12 :             const auto immediateOutputIter = m_sessionImmediateOutput.find(request->session_id());
     573           12 :             if (immediateOutputIter != m_sessionImmediateOutput.end())
     574              :             {
     575            2 :                 RIALTO_SERVER_LOG_INFO("Applying saved immediate-output to AUDIO source in session %d",
     576              :                                        request->session_id());
     577            2 :                 if (!m_mediaPipelineService.setImmediateOutput(request->session_id(), mediaSource->getId(),
     578            2 :                                                                immediateOutputIter->second))
     579              :                 {
     580            0 :                     RIALTO_SERVER_LOG_ERROR("Failed to apply saved immediate-output to AUDIO source");
     581            0 :                     controller->SetFailed("Operation failed");
     582              :                 }
     583              :             }
     584              :         }
     585              :     }
     586           23 :     response->set_source_id(mediaSource->getId());
     587           23 :     done->Run();
     588           25 : }
     589              : 
     590            0 : void MediaPipelineModuleService::removeSource(::google::protobuf::RpcController *controller,
     591              :                                               const ::firebolt::rialto::RemoveSourceRequest *request,
     592              :                                               ::firebolt::rialto::RemoveSourceResponse *response,
     593              :                                               ::google::protobuf::Closure *done)
     594              : {
     595            0 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     596            0 :     if (!m_mediaPipelineService.removeSource(request->session_id(), request->source_id()))
     597              :     {
     598            0 :         RIALTO_SERVER_LOG_ERROR("Remove source failed");
     599            0 :         controller->SetFailed("Operation failed");
     600              :     }
     601              :     else
     602              :     {
     603            0 :         const auto sessionSourcesIter = m_sessionSources.find(request->session_id());
     604            0 :         if (sessionSourcesIter != m_sessionSources.end())
     605              :         {
     606            0 :             sessionSourcesIter->second.erase(request->source_id());
     607              :         }
     608              :     }
     609            0 :     done->Run();
     610              : }
     611              : 
     612            2 : void MediaPipelineModuleService::allSourcesAttached(::google::protobuf::RpcController *controller,
     613              :                                                     const ::firebolt::rialto::AllSourcesAttachedRequest *request,
     614              :                                                     ::firebolt::rialto::AllSourcesAttachedResponse *response,
     615              :                                                     ::google::protobuf::Closure *done)
     616              : {
     617            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     618            2 :     if (!m_mediaPipelineService.allSourcesAttached(request->session_id()))
     619              :     {
     620            1 :         RIALTO_SERVER_LOG_ERROR("All sources attached failed");
     621            3 :         controller->SetFailed("Operation failed");
     622              :     }
     623            2 :     done->Run();
     624              : }
     625              : 
     626            2 : void MediaPipelineModuleService::play(::google::protobuf::RpcController *controller,
     627              :                                       const ::firebolt::rialto::PlayRequest *request,
     628              :                                       ::firebolt::rialto::PlayResponse *response, ::google::protobuf::Closure *done)
     629              : {
     630            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     631            2 :     bool async{false};
     632            2 :     if (!m_mediaPipelineService.play(request->session_id(), async))
     633              :     {
     634            1 :         RIALTO_SERVER_LOG_ERROR("Play failed");
     635            3 :         controller->SetFailed("Operation failed");
     636              :     }
     637            2 :     response->set_async(async);
     638            2 :     done->Run();
     639              : }
     640              : 
     641            2 : void MediaPipelineModuleService::pause(::google::protobuf::RpcController *controller,
     642              :                                        const ::firebolt::rialto::PauseRequest *request,
     643              :                                        ::firebolt::rialto::PauseResponse *response, ::google::protobuf::Closure *done)
     644              : {
     645            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     646            2 :     if (!m_mediaPipelineService.pause(request->session_id()))
     647              :     {
     648            1 :         RIALTO_SERVER_LOG_ERROR("pause failed");
     649            3 :         controller->SetFailed("Operation failed");
     650              :     }
     651            2 :     done->Run();
     652              : }
     653              : 
     654            2 : void MediaPipelineModuleService::stop(::google::protobuf::RpcController *controller,
     655              :                                       const ::firebolt::rialto::StopRequest *request,
     656              :                                       ::firebolt::rialto::StopResponse *response, ::google::protobuf::Closure *done)
     657              : {
     658            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     659            2 :     if (!m_mediaPipelineService.stop(request->session_id()))
     660              :     {
     661            1 :         RIALTO_SERVER_LOG_ERROR("Stop failed");
     662            3 :         controller->SetFailed("Operation failed");
     663              :     }
     664            2 :     done->Run();
     665              : }
     666              : 
     667            2 : void MediaPipelineModuleService::setPosition(::google::protobuf::RpcController *controller,
     668              :                                              const ::firebolt::rialto::SetPositionRequest *request,
     669              :                                              ::firebolt::rialto::SetPositionResponse *response,
     670              :                                              ::google::protobuf::Closure *done)
     671              : {
     672            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     673            2 :     if (!m_mediaPipelineService.setPosition(request->session_id(), request->position()))
     674              :     {
     675            1 :         RIALTO_SERVER_LOG_ERROR("Set Position failed");
     676            3 :         controller->SetFailed("Operation failed");
     677              :     }
     678            2 :     done->Run();
     679              : }
     680              : 
     681            2 : void MediaPipelineModuleService::haveData(::google::protobuf::RpcController *controller,
     682              :                                           const ::firebolt::rialto::HaveDataRequest *request,
     683              :                                           ::firebolt::rialto::HaveDataResponse *response,
     684              :                                           ::google::protobuf::Closure *done)
     685              : {
     686            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     687            2 :     firebolt::rialto::MediaSourceStatus status{convertMediaSourceStatus(request->status())};
     688            2 :     if (!m_mediaPipelineService.haveData(request->session_id(), status, request->num_frames(), request->request_id()))
     689              :     {
     690            1 :         RIALTO_SERVER_LOG_ERROR("Have data failed");
     691            3 :         controller->SetFailed("Operation failed");
     692              :     }
     693            2 :     done->Run();
     694              : }
     695              : 
     696            2 : void MediaPipelineModuleService::setPlaybackRate(::google::protobuf::RpcController *controller,
     697              :                                                  const ::firebolt::rialto::SetPlaybackRateRequest *request,
     698              :                                                  ::firebolt::rialto::SetPlaybackRateResponse *response,
     699              :                                                  ::google::protobuf::Closure *done)
     700              : {
     701            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     702            2 :     if (!m_mediaPipelineService.setPlaybackRate(request->session_id(), request->rate()))
     703              :     {
     704            1 :         RIALTO_SERVER_LOG_ERROR("Set playback rate failed");
     705            3 :         controller->SetFailed("Operation failed");
     706              :     }
     707            2 :     done->Run();
     708              : }
     709              : 
     710            2 : void MediaPipelineModuleService::getPosition(::google::protobuf::RpcController *controller,
     711              :                                              const ::firebolt::rialto::GetPositionRequest *request,
     712              :                                              ::firebolt::rialto::GetPositionResponse *response,
     713              :                                              ::google::protobuf::Closure *done)
     714              : {
     715            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     716            2 :     int64_t position{};
     717            2 :     if (!m_mediaPipelineService.getPosition(request->session_id(), position))
     718              :     {
     719            1 :         RIALTO_SERVER_LOG_ERROR("Get position failed");
     720            3 :         controller->SetFailed("Operation failed");
     721              :     }
     722              :     else
     723              :     {
     724            1 :         response->set_position(position);
     725              :     }
     726            2 :     done->Run();
     727              : }
     728              : 
     729            2 : void MediaPipelineModuleService::getDuration(::google::protobuf::RpcController *controller,
     730              :                                              const ::firebolt::rialto::GetDurationRequest *request,
     731              :                                              ::firebolt::rialto::GetDurationResponse *response,
     732              :                                              ::google::protobuf::Closure *done)
     733              : {
     734            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     735            2 :     int64_t duration{};
     736            2 :     if (!m_mediaPipelineService.getDuration(request->session_id(), duration))
     737              :     {
     738            1 :         RIALTO_SERVER_LOG_ERROR("Get duration failed");
     739            3 :         controller->SetFailed("Operation failed");
     740              :     }
     741              :     else
     742              :     {
     743            1 :         response->set_duration(duration);
     744              :     }
     745            2 :     done->Run();
     746              : }
     747              : 
     748            8 : void MediaPipelineModuleService::setImmediateOutput(::google::protobuf::RpcController *controller,
     749              :                                                     const ::firebolt::rialto::SetImmediateOutputRequest *request,
     750              :                                                     ::firebolt::rialto::SetImmediateOutputResponse *response,
     751              :                                                     ::google::protobuf::Closure *done)
     752              : {
     753            8 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     754            8 :     auto ipcController = dynamic_cast<firebolt::rialto::ipc::IController *>(controller);
     755            8 :     if (!ipcController)
     756              :     {
     757            0 :         RIALTO_SERVER_LOG_ERROR("ipc library provided incompatible controller object");
     758            0 :         controller->SetFailed("ipc library provided incompatible controller object");
     759            0 :         done->Run();
     760            0 :         return;
     761              :     }
     762              : 
     763            8 :     const auto clientSessionsIter = m_clientSessions.find(ipcController->getClient());
     764            8 :     if (clientSessionsIter == m_clientSessions.end())
     765              :     {
     766            0 :         RIALTO_SERVER_LOG_ERROR("Set immediate output requested by unknown client");
     767            0 :         controller->SetFailed("Operation failed");
     768            0 :         done->Run();
     769            0 :         return;
     770              :     }
     771              : 
     772            8 :     const auto sourceSessionIter = m_sessionSources.find(request->session_id());
     773            8 :     const auto ownedSessionIter = clientSessionsIter->second.find(request->session_id());
     774            8 :     if (ownedSessionIter == clientSessionsIter->second.end())
     775              :     {
     776            0 :         RIALTO_SERVER_LOG_ERROR("Set immediate output requested for session not owned by client");
     777            0 :         controller->SetFailed("Operation failed");
     778            0 :         done->Run();
     779            0 :         return;
     780              :     }
     781              : 
     782            8 :     bool success = m_mediaPipelineService.setImmediateOutput(request->session_id(), request->source_id(),
     783            8 :                                                              request->immediate_output());
     784            8 :     if (success && sourceSessionIter != m_sessionSources.end())
     785              :     {
     786            7 :         const auto sourceIter = sourceSessionIter->second.find(request->source_id());
     787            7 :         if (sourceIter != sourceSessionIter->second.end() && sourceIter->second == MediaSourceType::VIDEO)
     788              :         {
     789            6 :             std::vector<int32_t> sameSessionAudioSourceIds;
     790            6 :             std::map<int, std::vector<int32_t>> peerSessionAudioSourceIds;
     791            6 :             std::vector<int> emptyPeerSessions;
     792           16 :             for (const int sessionId : clientSessionsIter->second)
     793              :             {
     794           10 :                 const auto sessionSourcesIter = m_sessionSources.find(sessionId);
     795           10 :                 if (sessionSourcesIter == m_sessionSources.end())
     796              :                 {
     797            0 :                     continue;
     798              :                 }
     799           10 :                 bool hasAudioOrVideoSource{false};
     800           22 :                 for (const auto &[sourceId, sourceType] : sessionSourcesIter->second)
     801              :                 {
     802           12 :                     if (sourceType == MediaSourceType::AUDIO)
     803              :                     {
     804            6 :                         hasAudioOrVideoSource = true;
     805            6 :                         auto &audioSourceIds = sessionId == request->session_id() ? sameSessionAudioSourceIds
     806            3 :                                                                                   : peerSessionAudioSourceIds[sessionId];
     807            6 :                         audioSourceIds.push_back(sourceId);
     808              :                     }
     809            6 :                     else if (sourceType == MediaSourceType::VIDEO)
     810              :                     {
     811            6 :                         hasAudioOrVideoSource = true;
     812              :                     }
     813              :                 }
     814           10 :                 if (sessionId != request->session_id() && !hasAudioOrVideoSource)
     815              :                 {
     816            1 :                     emptyPeerSessions.push_back(sessionId);
     817              :                 }
     818              :             }
     819              : 
     820            6 :             m_sessionImmediateOutput[request->session_id()] = request->immediate_output();
     821            6 :             int audioSessionId{request->session_id()};
     822            6 :             std::vector<int32_t> *audioSourceIds{&sameSessionAudioSourceIds};
     823            6 :             bool pendingAudioSource{false};
     824            6 :             if (sameSessionAudioSourceIds.empty())
     825              :             {
     826            4 :                 if (peerSessionAudioSourceIds.size() == 1)
     827              :                 {
     828            1 :                     audioSessionId = peerSessionAudioSourceIds.begin()->first;
     829            1 :                     audioSourceIds = &peerSessionAudioSourceIds.begin()->second;
     830              :                 }
     831            3 :                 else if (peerSessionAudioSourceIds.size() > 1)
     832              :                 {
     833            1 :                     RIALTO_SERVER_LOG_WARN(
     834              :                         "Cannot pair immediate-output with AUDIO: multiple AUDIO sessions belong to client");
     835              :                 }
     836            2 :                 else if (emptyPeerSessions.size() == 1)
     837              :                 {
     838            1 :                     audioSessionId = emptyPeerSessions.front();
     839            1 :                     pendingAudioSource = true;
     840            1 :                     m_sessionImmediateOutput[audioSessionId] = request->immediate_output();
     841            1 :                     RIALTO_SERVER_LOG_INFO("Saved immediate-output for pending AUDIO source in session %d",
     842              :                                            audioSessionId);
     843              :                 }
     844            1 :                 else if (emptyPeerSessions.size() > 1)
     845              :                 {
     846            0 :                     RIALTO_SERVER_LOG_WARN(
     847              :                         "Cannot pair immediate-output with pending AUDIO: multiple empty sessions belong to client");
     848              :                 }
     849              :             }
     850              : 
     851            6 :             if (!pendingAudioSource && !audioSourceIds->empty())
     852              :             {
     853            3 :                 m_sessionImmediateOutput[audioSessionId] = request->immediate_output();
     854            7 :                 for (const int32_t audioSourceId : *audioSourceIds)
     855              :                 {
     856            4 :                     RIALTO_SERVER_LOG_INFO("Applying immediate-output to AUDIO source %d in session %d", audioSourceId,
     857              :                                            audioSessionId);
     858            4 :                     if (!m_mediaPipelineService.setImmediateOutput(audioSessionId, audioSourceId,
     859            4 :                                                                    request->immediate_output()))
     860              :                     {
     861            0 :                         success = false;
     862              :                     }
     863              :                 }
     864              :             }
     865            6 :         }
     866              :     }
     867            8 :     if (!success)
     868              :     {
     869            1 :         RIALTO_SERVER_LOG_ERROR("Set Immediate Output failed");
     870            3 :         controller->SetFailed("Operation failed");
     871              :     }
     872            8 :     done->Run();
     873              : }
     874              : 
     875            2 : void MediaPipelineModuleService::setReportDecodeErrors(::google::protobuf::RpcController *controller,
     876              :                                                        const ::firebolt::rialto::SetReportDecodeErrorsRequest *request,
     877              :                                                        ::firebolt::rialto::SetReportDecodeErrorsResponse *response,
     878              :                                                        ::google::protobuf::Closure *done)
     879              : {
     880            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     881            2 :     if (!m_mediaPipelineService.setReportDecodeErrors(request->session_id(), request->source_id(),
     882            2 :                                                       request->report_decode_errors()))
     883              :     {
     884            1 :         RIALTO_SERVER_LOG_ERROR("Set Report Decode Error failed");
     885            3 :         controller->SetFailed("Operation failed");
     886              :     }
     887            2 :     done->Run();
     888              : }
     889              : 
     890            2 : void MediaPipelineModuleService::getQueuedFrames(::google::protobuf::RpcController *controller,
     891              :                                                  const ::firebolt::rialto::GetQueuedFramesRequest *request,
     892              :                                                  ::firebolt::rialto::GetQueuedFramesResponse *response,
     893              :                                                  ::google::protobuf::Closure *done)
     894              : {
     895            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     896              :     uint32_t queuedFramesNumber;
     897            2 :     if (!m_mediaPipelineService.getQueuedFrames(request->session_id(), request->source_id(), queuedFramesNumber))
     898              :     {
     899            1 :         RIALTO_SERVER_LOG_ERROR("Get queued frames failed");
     900            3 :         controller->SetFailed("Operation failed");
     901              :     }
     902              :     else
     903              :     {
     904            1 :         response->set_queued_frames(queuedFramesNumber);
     905              :     }
     906            2 :     done->Run();
     907              : }
     908              : 
     909            2 : void MediaPipelineModuleService::getImmediateOutput(::google::protobuf::RpcController *controller,
     910              :                                                     const ::firebolt::rialto::GetImmediateOutputRequest *request,
     911              :                                                     ::firebolt::rialto::GetImmediateOutputResponse *response,
     912              :                                                     ::google::protobuf::Closure *done)
     913              : {
     914            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     915              :     bool immediateOutputState;
     916            2 :     if (!m_mediaPipelineService.getImmediateOutput(request->session_id(), request->source_id(), immediateOutputState))
     917              :     {
     918            1 :         RIALTO_SERVER_LOG_ERROR("Get Immediate Output failed");
     919            3 :         controller->SetFailed("Operation failed");
     920              :     }
     921              :     else
     922              :     {
     923            1 :         response->set_immediate_output(immediateOutputState);
     924              :     }
     925            2 :     done->Run();
     926              : }
     927              : 
     928            2 : void MediaPipelineModuleService::getStats(::google::protobuf::RpcController *controller,
     929              :                                           const ::firebolt::rialto::GetStatsRequest *request,
     930              :                                           ::firebolt::rialto::GetStatsResponse *response,
     931              :                                           ::google::protobuf::Closure *done)
     932              : {
     933            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     934              :     uint64_t renderedFrames;
     935              :     uint64_t droppedFrames;
     936            2 :     if (!m_mediaPipelineService.getStats(request->session_id(), request->source_id(), renderedFrames, droppedFrames))
     937              :     {
     938            1 :         RIALTO_SERVER_LOG_ERROR("Get stats failed");
     939            3 :         controller->SetFailed("Operation failed");
     940              :     }
     941              :     else
     942              :     {
     943            1 :         response->set_rendered_frames(renderedFrames);
     944            1 :         response->set_dropped_frames(droppedFrames);
     945              :     }
     946            2 :     done->Run();
     947              : }
     948              : 
     949            2 : void MediaPipelineModuleService::renderFrame(::google::protobuf::RpcController *controller,
     950              :                                              const ::firebolt::rialto::RenderFrameRequest *request,
     951              :                                              ::firebolt::rialto::RenderFrameResponse *response,
     952              :                                              ::google::protobuf::Closure *done)
     953              : {
     954            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     955              : 
     956            2 :     if (!m_mediaPipelineService.renderFrame(request->session_id()))
     957              :     {
     958            1 :         RIALTO_SERVER_LOG_ERROR("Render frame");
     959            3 :         controller->SetFailed("Operation failed");
     960              :     }
     961              : 
     962            2 :     done->Run();
     963              : }
     964              : 
     965            2 : void MediaPipelineModuleService::setVolume(::google::protobuf::RpcController *controller,
     966              :                                            const ::firebolt::rialto::SetVolumeRequest *request,
     967              :                                            ::firebolt::rialto::SetVolumeResponse *response,
     968              :                                            ::google::protobuf::Closure *done)
     969              : {
     970            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     971              : 
     972            2 :     if (!m_mediaPipelineService.setVolume(request->session_id(), request->volume(), request->volume_duration(),
     973            4 :                                           convertEaseType(request->ease_type())))
     974              :     {
     975            1 :         RIALTO_SERVER_LOG_ERROR("Set volume failed.");
     976            3 :         controller->SetFailed("Operation failed");
     977              :     }
     978              : 
     979            2 :     done->Run();
     980              : }
     981              : 
     982            2 : void MediaPipelineModuleService::getVolume(::google::protobuf::RpcController *controller,
     983              :                                            const ::firebolt::rialto::GetVolumeRequest *request,
     984              :                                            ::firebolt::rialto::GetVolumeResponse *response,
     985              :                                            ::google::protobuf::Closure *done)
     986              : {
     987            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
     988            2 :     double volume{};
     989              : 
     990            2 :     if (!m_mediaPipelineService.getVolume(request->session_id(), volume))
     991              :     {
     992            1 :         RIALTO_SERVER_LOG_ERROR("Get volume failed.");
     993            3 :         controller->SetFailed("Operation failed");
     994              :     }
     995              :     else
     996              :     {
     997            1 :         response->set_volume(volume);
     998              :     }
     999              : 
    1000            2 :     done->Run();
    1001              : }
    1002              : 
    1003            2 : void MediaPipelineModuleService::setMute(::google::protobuf::RpcController *controller,
    1004              :                                          const ::firebolt::rialto::SetMuteRequest *request,
    1005              :                                          ::firebolt::rialto::SetMuteResponse *response, ::google::protobuf::Closure *done)
    1006              : {
    1007            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1008              : 
    1009            2 :     if (!m_mediaPipelineService.setMute(request->session_id(), request->source_id(), request->mute()))
    1010              :     {
    1011            1 :         RIALTO_SERVER_LOG_ERROR("Set mute failed.");
    1012            3 :         controller->SetFailed("Operation failed");
    1013              :     }
    1014              : 
    1015            2 :     done->Run();
    1016              : }
    1017              : 
    1018            2 : void MediaPipelineModuleService::getMute(::google::protobuf::RpcController *controller,
    1019              :                                          const ::firebolt::rialto::GetMuteRequest *request,
    1020              :                                          ::firebolt::rialto::GetMuteResponse *response, ::google::protobuf::Closure *done)
    1021              : {
    1022            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1023            2 :     bool mute{};
    1024              : 
    1025            2 :     if (!m_mediaPipelineService.getMute(request->session_id(), request->source_id(), mute))
    1026              :     {
    1027            1 :         RIALTO_SERVER_LOG_ERROR("Get mute failed.");
    1028            3 :         controller->SetFailed("Operation failed");
    1029              :     }
    1030              :     else
    1031              :     {
    1032            1 :         response->set_mute(mute);
    1033              :     }
    1034              : 
    1035            2 :     done->Run();
    1036              : }
    1037              : 
    1038            2 : void MediaPipelineModuleService::setTextTrackIdentifier(::google::protobuf::RpcController *controller,
    1039              :                                                         const ::firebolt::rialto::SetTextTrackIdentifierRequest *request,
    1040              :                                                         ::firebolt::rialto::SetTextTrackIdentifierResponse *response,
    1041              :                                                         ::google::protobuf::Closure *done)
    1042              : {
    1043            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1044              : 
    1045            2 :     if (!m_mediaPipelineService.setTextTrackIdentifier(request->session_id(), request->text_track_identifier()))
    1046              :     {
    1047            1 :         RIALTO_SERVER_LOG_ERROR("Set text track identifier failed.");
    1048            3 :         controller->SetFailed("Operation failed");
    1049              :     }
    1050              : 
    1051            2 :     done->Run();
    1052              : }
    1053              : 
    1054            2 : void MediaPipelineModuleService::getTextTrackIdentifier(::google::protobuf::RpcController *controller,
    1055              :                                                         const ::firebolt::rialto::GetTextTrackIdentifierRequest *request,
    1056              :                                                         ::firebolt::rialto::GetTextTrackIdentifierResponse *response,
    1057              :                                                         ::google::protobuf::Closure *done)
    1058              : {
    1059            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1060            2 :     std::string textTrackIdentifier{};
    1061              : 
    1062            2 :     if (!m_mediaPipelineService.getTextTrackIdentifier(request->session_id(), textTrackIdentifier))
    1063              :     {
    1064            1 :         RIALTO_SERVER_LOG_ERROR("Get TextTrackIdentifier failed.");
    1065            3 :         controller->SetFailed("Operation failed");
    1066              :     }
    1067              :     else
    1068              :     {
    1069              :         response->set_text_track_identifier(textTrackIdentifier);
    1070              :     }
    1071              : 
    1072            2 :     done->Run();
    1073              : }
    1074              : 
    1075            2 : void MediaPipelineModuleService::setLowLatency(::google::protobuf::RpcController *controller,
    1076              :                                                const ::firebolt::rialto::SetLowLatencyRequest *request,
    1077              :                                                ::firebolt::rialto::SetLowLatencyResponse *response,
    1078              :                                                ::google::protobuf::Closure *done)
    1079              : {
    1080            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1081              : 
    1082            2 :     if (!m_mediaPipelineService.setLowLatency(request->session_id(), request->low_latency()))
    1083              :     {
    1084            1 :         RIALTO_SERVER_LOG_ERROR("Set low latency failed.");
    1085            3 :         controller->SetFailed("Operation failed");
    1086              :     }
    1087              : 
    1088            2 :     done->Run();
    1089              : }
    1090              : 
    1091            2 : void MediaPipelineModuleService::setSync(::google::protobuf::RpcController *controller,
    1092              :                                          const ::firebolt::rialto::SetSyncRequest *request,
    1093              :                                          ::firebolt::rialto::SetSyncResponse *response, ::google::protobuf::Closure *done)
    1094              : {
    1095            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1096              : 
    1097            2 :     if (!m_mediaPipelineService.setSync(request->session_id(), request->sync()))
    1098              :     {
    1099            1 :         RIALTO_SERVER_LOG_ERROR("Set sync failed.");
    1100            3 :         controller->SetFailed("Operation failed");
    1101              :     }
    1102              : 
    1103            2 :     done->Run();
    1104              : }
    1105              : 
    1106            2 : void MediaPipelineModuleService::getSync(::google::protobuf::RpcController *controller,
    1107              :                                          const ::firebolt::rialto::GetSyncRequest *request,
    1108              :                                          ::firebolt::rialto::GetSyncResponse *response, ::google::protobuf::Closure *done)
    1109              : {
    1110            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1111            2 :     bool sync{};
    1112              : 
    1113            2 :     if (!m_mediaPipelineService.getSync(request->session_id(), sync))
    1114              :     {
    1115            1 :         RIALTO_SERVER_LOG_ERROR("Get sync failed.");
    1116            3 :         controller->SetFailed("Operation failed");
    1117              :     }
    1118              :     else
    1119              :     {
    1120            1 :         response->set_sync(sync);
    1121              :     }
    1122              : 
    1123            2 :     done->Run();
    1124              : }
    1125              : 
    1126            2 : void MediaPipelineModuleService::setSyncOff(::google::protobuf::RpcController *controller,
    1127              :                                             const ::firebolt::rialto::SetSyncOffRequest *request,
    1128              :                                             ::firebolt::rialto::SetSyncOffResponse *response,
    1129              :                                             ::google::protobuf::Closure *done)
    1130              : {
    1131            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1132              : 
    1133            2 :     if (!m_mediaPipelineService.setSyncOff(request->session_id(), request->sync_off()))
    1134              :     {
    1135            1 :         RIALTO_SERVER_LOG_ERROR("Set sync off failed.");
    1136            3 :         controller->SetFailed("Operation failed");
    1137              :     }
    1138              : 
    1139            2 :     done->Run();
    1140              : }
    1141              : 
    1142            2 : void MediaPipelineModuleService::setStreamSyncMode(::google::protobuf::RpcController *controller,
    1143              :                                                    const ::firebolt::rialto::SetStreamSyncModeRequest *request,
    1144              :                                                    ::firebolt::rialto::SetStreamSyncModeResponse *response,
    1145              :                                                    ::google::protobuf::Closure *done)
    1146              : {
    1147            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1148              : 
    1149            2 :     if (!m_mediaPipelineService.setStreamSyncMode(request->session_id(), request->source_id(),
    1150              :                                                   request->stream_sync_mode()))
    1151              :     {
    1152            1 :         RIALTO_SERVER_LOG_ERROR("Set stream sync mode failed.");
    1153            3 :         controller->SetFailed("Operation failed");
    1154              :     }
    1155              : 
    1156            2 :     done->Run();
    1157              : }
    1158              : 
    1159            2 : void MediaPipelineModuleService::getStreamSyncMode(::google::protobuf::RpcController *controller,
    1160              :                                                    const ::firebolt::rialto::GetStreamSyncModeRequest *request,
    1161              :                                                    ::firebolt::rialto::GetStreamSyncModeResponse *response,
    1162              :                                                    ::google::protobuf::Closure *done)
    1163              : {
    1164            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1165            2 :     int32_t streamSyncMode{};
    1166              : 
    1167            2 :     if (!m_mediaPipelineService.getStreamSyncMode(request->session_id(), streamSyncMode))
    1168              :     {
    1169            1 :         RIALTO_SERVER_LOG_ERROR("Get stream sync mode failed.");
    1170            3 :         controller->SetFailed("Operation failed");
    1171              :     }
    1172              :     else
    1173              :     {
    1174            1 :         response->set_stream_sync_mode(streamSyncMode);
    1175              :     }
    1176              : 
    1177            2 :     done->Run();
    1178              : }
    1179              : 
    1180            2 : void MediaPipelineModuleService::flush(::google::protobuf::RpcController *controller,
    1181              :                                        const ::firebolt::rialto::FlushRequest *request,
    1182              :                                        ::firebolt::rialto::FlushResponse *response, ::google::protobuf::Closure *done)
    1183              : {
    1184            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1185              : 
    1186            2 :     bool isAsync{false};
    1187            2 :     if (!m_mediaPipelineService.flush(request->session_id(), request->source_id(), request->reset_time(), isAsync))
    1188              :     {
    1189            1 :         RIALTO_SERVER_LOG_ERROR("Flush failed.");
    1190            3 :         controller->SetFailed("Operation failed");
    1191              :     }
    1192            2 :     response->set_async(isAsync);
    1193              : 
    1194            2 :     done->Run();
    1195              : }
    1196              : 
    1197            2 : void MediaPipelineModuleService::setSourcePosition(::google::protobuf::RpcController *controller,
    1198              :                                                    const ::firebolt::rialto::SetSourcePositionRequest *request,
    1199              :                                                    ::firebolt::rialto::SetSourcePositionResponse *response,
    1200              :                                                    ::google::protobuf::Closure *done)
    1201              : {
    1202            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1203            4 :     if (!m_mediaPipelineService.setSourcePosition(request->session_id(), request->source_id(), request->position(),
    1204            2 :                                                   request->reset_time(), request->applied_rate(),
    1205              :                                                   request->stop_position()))
    1206              :     {
    1207            1 :         RIALTO_SERVER_LOG_ERROR("Set Source Position failed.");
    1208            3 :         controller->SetFailed("Operation failed");
    1209              :     }
    1210            2 :     done->Run();
    1211              : }
    1212              : 
    1213            0 : void MediaPipelineModuleService::setSubtitleOffset(::google::protobuf::RpcController *controller,
    1214              :                                                    const ::firebolt::rialto::SetSubtitleOffsetRequest *request,
    1215              :                                                    ::firebolt::rialto::SetSubtitleOffsetResponse *response,
    1216              :                                                    ::google::protobuf::Closure *done)
    1217              : {
    1218            0 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1219            0 :     if (!m_mediaPipelineService.setSubtitleOffset(request->session_id(), request->source_id(), request->position()))
    1220              :     {
    1221            0 :         RIALTO_SERVER_LOG_ERROR("Set Subtitle Offset failed.");
    1222            0 :         controller->SetFailed("Operation failed");
    1223              :     }
    1224            0 :     done->Run();
    1225              : }
    1226              : 
    1227            2 : void MediaPipelineModuleService::processAudioGap(::google::protobuf::RpcController *controller,
    1228              :                                                  const ::firebolt::rialto::ProcessAudioGapRequest *request,
    1229              :                                                  ::firebolt::rialto::ProcessAudioGapResponse *response,
    1230              :                                                  ::google::protobuf::Closure *done)
    1231              : {
    1232            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1233            2 :     if (!m_mediaPipelineService.processAudioGap(request->session_id(), request->position(), request->duration(),
    1234            2 :                                                 request->discontinuity_gap(), request->audio_aac()))
    1235              :     {
    1236            1 :         RIALTO_SERVER_LOG_ERROR("Process audio gap failed.");
    1237            3 :         controller->SetFailed("Operation failed");
    1238              :     }
    1239            2 :     done->Run();
    1240              : }
    1241              : 
    1242            2 : void MediaPipelineModuleService::setBufferingLimit(::google::protobuf::RpcController *controller,
    1243              :                                                    const ::firebolt::rialto::SetBufferingLimitRequest *request,
    1244              :                                                    ::firebolt::rialto::SetBufferingLimitResponse *response,
    1245              :                                                    ::google::protobuf::Closure *done)
    1246              : {
    1247            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1248            2 :     if (!m_mediaPipelineService.setBufferingLimit(request->session_id(), request->limit_buffering_ms()))
    1249              :     {
    1250            1 :         RIALTO_SERVER_LOG_ERROR("Set buffering limit failed.");
    1251            3 :         controller->SetFailed("Operation failed");
    1252              :     }
    1253            2 :     done->Run();
    1254              : }
    1255              : 
    1256            2 : void MediaPipelineModuleService::getBufferingLimit(::google::protobuf::RpcController *controller,
    1257              :                                                    const ::firebolt::rialto::GetBufferingLimitRequest *request,
    1258              :                                                    ::firebolt::rialto::GetBufferingLimitResponse *response,
    1259              :                                                    ::google::protobuf::Closure *done)
    1260              : {
    1261            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1262            2 :     uint32_t bufferingLimit{};
    1263              : 
    1264            2 :     if (!m_mediaPipelineService.getBufferingLimit(request->session_id(), bufferingLimit))
    1265              :     {
    1266            1 :         RIALTO_SERVER_LOG_ERROR("Get buffering limit failed.");
    1267            3 :         controller->SetFailed("Operation failed");
    1268              :     }
    1269              :     else
    1270              :     {
    1271            1 :         response->set_limit_buffering_ms(bufferingLimit);
    1272              :     }
    1273              : 
    1274            2 :     done->Run();
    1275              : }
    1276              : 
    1277            2 : void MediaPipelineModuleService::setUseBuffering(::google::protobuf::RpcController *controller,
    1278              :                                                  const ::firebolt::rialto::SetUseBufferingRequest *request,
    1279              :                                                  ::firebolt::rialto::SetUseBufferingResponse *response,
    1280              :                                                  ::google::protobuf::Closure *done)
    1281              : {
    1282            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1283            2 :     if (!m_mediaPipelineService.setUseBuffering(request->session_id(), request->use_buffering()))
    1284              :     {
    1285            1 :         RIALTO_SERVER_LOG_ERROR("Set use buffering failed.");
    1286            3 :         controller->SetFailed("Operation failed");
    1287              :     }
    1288            2 :     done->Run();
    1289              : }
    1290              : 
    1291            2 : void MediaPipelineModuleService::getUseBuffering(::google::protobuf::RpcController *controller,
    1292              :                                                  const ::firebolt::rialto::GetUseBufferingRequest *request,
    1293              :                                                  ::firebolt::rialto::GetUseBufferingResponse *response,
    1294              :                                                  ::google::protobuf::Closure *done)
    1295              : {
    1296            2 :     RIALTO_SERVER_LOG_DEBUG("entry:");
    1297            2 :     bool useBuffering{};
    1298              : 
    1299            2 :     if (!m_mediaPipelineService.getUseBuffering(request->session_id(), useBuffering))
    1300              :     {
    1301            1 :         RIALTO_SERVER_LOG_ERROR("Get use buffering failed.");
    1302            3 :         controller->SetFailed("Operation failed");
    1303              :     }
    1304              :     else
    1305              :     {
    1306            1 :         response->set_use_buffering(useBuffering);
    1307              :     }
    1308              : 
    1309            2 :     done->Run();
    1310              : }
    1311              : } // namespace firebolt::rialto::server::ipc
        

Generated by: LCOV version 2.0-1