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