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 192 : MediaPipelineIpc::MediaPipelineIpc(IMediaPipelineIpcClient *client, const VideoRequirements &videoRequirements,
72 : IIpcClient &ipcClient,
73 192 : const std::shared_ptr<common::IEventThreadFactory> &eventThreadFactory)
74 192 : : IpcModule(ipcClient), m_mediaPipelineIpcClient(client),
75 384 : m_eventThread(eventThreadFactory->createEventThread("rialto-media-player-events"))
76 : {
77 192 : if (!attachChannel())
78 : {
79 4 : throw std::runtime_error("Failed attach to the ipc channel");
80 : }
81 :
82 : // create media player session
83 188 : if (!createSession(videoRequirements))
84 : {
85 1 : detachChannel();
86 1 : throw std::runtime_error("Could not create the media player session");
87 : }
88 207 : }
89 :
90 374 : MediaPipelineIpc::~MediaPipelineIpc()
91 : {
92 : // destroy media player session
93 187 : destroySession();
94 :
95 : // detach the Ipc channel
96 187 : detachChannel();
97 :
98 : // destroy the thread processing async notifications
99 187 : m_eventThread.reset();
100 374 : }
101 :
102 266 : bool MediaPipelineIpc::createRpcStubs(const std::shared_ptr<ipc::IChannel> &ipcChannel)
103 : {
104 266 : m_mediaPipelineStub = std::make_unique<::firebolt::rialto::MediaPipelineModule_Stub>(ipcChannel.get());
105 266 : if (!m_mediaPipelineStub)
106 : {
107 0 : return false;
108 : }
109 266 : return true;
110 : }
111 :
112 266 : bool MediaPipelineIpc::subscribeToEvents(const std::shared_ptr<ipc::IChannel> &ipcChannel)
113 : {
114 266 : if (!ipcChannel)
115 : {
116 0 : return false;
117 : }
118 :
119 532 : int eventTag = ipcChannel->subscribe<firebolt::rialto::PlaybackStateChangeEvent>(
120 266 : [this](const std::shared_ptr<firebolt::rialto::PlaybackStateChangeEvent> &event)
121 268 : { m_eventThread->add(&MediaPipelineIpc::onPlaybackStateUpdated, this, event); });
122 266 : if (eventTag < 0)
123 0 : return false;
124 266 : m_eventTags.push_back(eventTag);
125 :
126 532 : eventTag = ipcChannel->subscribe<firebolt::rialto::PositionChangeEvent>(
127 266 : [this](const std::shared_ptr<firebolt::rialto::PositionChangeEvent> &event)
128 0 : { m_eventThread->add(&MediaPipelineIpc::onPositionUpdated, this, event); });
129 266 : if (eventTag < 0)
130 1 : return false;
131 265 : m_eventTags.push_back(eventTag);
132 :
133 530 : eventTag = ipcChannel->subscribe<firebolt::rialto::NetworkStateChangeEvent>(
134 265 : [this](const std::shared_ptr<firebolt::rialto::NetworkStateChangeEvent> &event)
135 2 : { m_eventThread->add(&MediaPipelineIpc::onNetworkStateUpdated, this, event); });
136 265 : if (eventTag < 0)
137 0 : return false;
138 265 : m_eventTags.push_back(eventTag);
139 :
140 530 : eventTag = ipcChannel->subscribe<firebolt::rialto::NeedMediaDataEvent>(
141 265 : [this](const std::shared_ptr<firebolt::rialto::NeedMediaDataEvent> &event)
142 3 : { m_eventThread->add(&MediaPipelineIpc::onNeedMediaData, this, event); });
143 265 : if (eventTag < 0)
144 0 : return false;
145 265 : m_eventTags.push_back(eventTag);
146 :
147 530 : eventTag = ipcChannel->subscribe<firebolt::rialto::QosEvent>(
148 265 : [this](const std::shared_ptr<firebolt::rialto::QosEvent> &event)
149 2 : { m_eventThread->add(&MediaPipelineIpc::onQos, this, event); });
150 265 : if (eventTag < 0)
151 0 : return false;
152 265 : m_eventTags.push_back(eventTag);
153 :
154 530 : eventTag = ipcChannel->subscribe<firebolt::rialto::BufferUnderflowEvent>(
155 265 : [this](const std::shared_ptr<firebolt::rialto::BufferUnderflowEvent> &event)
156 0 : { m_eventThread->add(&MediaPipelineIpc::onBufferUnderflow, this, event); });
157 265 : if (eventTag < 0)
158 0 : return false;
159 265 : m_eventTags.push_back(eventTag);
160 :
161 530 : eventTag = ipcChannel->subscribe<firebolt::rialto::FirstFrameReceivedEvent>(
162 265 : [this](const std::shared_ptr<firebolt::rialto::FirstFrameReceivedEvent> &event)
163 2 : { m_eventThread->add(&MediaPipelineIpc::onFirstFrameReceived, this, event); });
164 265 : if (eventTag < 0)
165 0 : return false;
166 265 : m_eventTags.push_back(eventTag);
167 :
168 530 : eventTag = ipcChannel->subscribe<firebolt::rialto::PlaybackErrorEvent>(
169 265 : [this](const std::shared_ptr<firebolt::rialto::PlaybackErrorEvent> &event)
170 2 : { m_eventThread->add(&MediaPipelineIpc::onPlaybackError, this, event); });
171 265 : if (eventTag < 0)
172 0 : return false;
173 265 : m_eventTags.push_back(eventTag);
174 :
175 530 : eventTag = ipcChannel->subscribe<firebolt::rialto::SourceFlushedEvent>(
176 265 : [this](const std::shared_ptr<firebolt::rialto::SourceFlushedEvent> &event)
177 2 : { m_eventThread->add(&MediaPipelineIpc::onSourceFlushed, this, event); });
178 265 : if (eventTag < 0)
179 0 : return false;
180 265 : m_eventTags.push_back(eventTag);
181 :
182 530 : eventTag = ipcChannel->subscribe<firebolt::rialto::PlaybackInfoEvent>(
183 265 : [this](const std::shared_ptr<firebolt::rialto::PlaybackInfoEvent> &event)
184 1 : { m_eventThread->add(&MediaPipelineIpc::onPlaybackInfo, this, event); });
185 265 : if (eventTag < 0)
186 0 : return false;
187 265 : m_eventTags.push_back(eventTag);
188 :
189 265 : 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::setReportDecodeErrors(int32_t sourceId, bool reportDecodeErrors)
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::SetReportDecodeErrorsRequest request;
618 :
619 3 : request.set_session_id(m_sessionId);
620 3 : request.set_source_id(sourceId);
621 3 : request.set_report_decode_errors(reportDecodeErrors);
622 :
623 3 : firebolt::rialto::SetReportDecodeErrorsResponse response;
624 3 : auto ipcController = m_ipc.createRpcController();
625 3 : auto blockingClosure = m_ipc.createBlockingClosure();
626 3 : m_mediaPipelineStub->setReportDecodeErrors(ipcController.get(), &request, &response, blockingClosure.get());
627 :
628 : // wait for the call to complete
629 3 : blockingClosure->wait();
630 :
631 : // check the result
632 3 : if (ipcController->Failed())
633 : {
634 1 : RIALTO_CLIENT_LOG_ERROR("failed to set report decode error due to '%s'", ipcController->ErrorText().c_str());
635 1 : return false;
636 : }
637 :
638 2 : return true;
639 3 : }
640 :
641 4 : bool MediaPipelineIpc::getQueuedFrames(int32_t sourceId, uint32_t &queuedFrames)
642 : {
643 4 : if (!reattachChannelIfRequired())
644 : {
645 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
646 1 : return false;
647 : }
648 :
649 3 : firebolt::rialto::GetQueuedFramesRequest request;
650 :
651 3 : request.set_session_id(m_sessionId);
652 3 : request.set_source_id(sourceId);
653 :
654 3 : firebolt::rialto::GetQueuedFramesResponse response;
655 3 : auto ipcController = m_ipc.createRpcController();
656 3 : auto blockingClosure = m_ipc.createBlockingClosure();
657 3 : m_mediaPipelineStub->getQueuedFrames(ipcController.get(), &request, &response, blockingClosure.get());
658 :
659 : // wait for the call to complete
660 3 : blockingClosure->wait();
661 :
662 : // check the result
663 3 : if (ipcController->Failed())
664 : {
665 1 : RIALTO_CLIENT_LOG_ERROR("failed to get queued frames due to '%s'", ipcController->ErrorText().c_str());
666 1 : return false;
667 : }
668 : else
669 : {
670 2 : queuedFrames = response.queued_frames();
671 : }
672 :
673 2 : return true;
674 3 : }
675 :
676 4 : bool MediaPipelineIpc::getImmediateOutput(int32_t sourceId, bool &immediateOutput)
677 : {
678 4 : if (!reattachChannelIfRequired())
679 : {
680 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
681 1 : return false;
682 : }
683 :
684 3 : firebolt::rialto::GetImmediateOutputRequest request;
685 :
686 3 : request.set_session_id(m_sessionId);
687 3 : request.set_source_id(sourceId);
688 :
689 3 : firebolt::rialto::GetImmediateOutputResponse response;
690 3 : auto ipcController = m_ipc.createRpcController();
691 3 : auto blockingClosure = m_ipc.createBlockingClosure();
692 3 : m_mediaPipelineStub->getImmediateOutput(ipcController.get(), &request, &response, blockingClosure.get());
693 :
694 : // wait for the call to complete
695 3 : blockingClosure->wait();
696 :
697 : // check the result
698 3 : if (ipcController->Failed())
699 : {
700 1 : RIALTO_CLIENT_LOG_ERROR("failed to get immediate-output due to '%s'", ipcController->ErrorText().c_str());
701 1 : return false;
702 : }
703 : else
704 : {
705 2 : immediateOutput = response.immediate_output();
706 : }
707 :
708 2 : return true;
709 3 : }
710 :
711 4 : bool MediaPipelineIpc::getStats(int32_t sourceId, uint64_t &renderedFrames, uint64_t &droppedFrames)
712 : {
713 4 : if (!reattachChannelIfRequired())
714 : {
715 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
716 1 : return false;
717 : }
718 :
719 3 : firebolt::rialto::GetStatsRequest request;
720 :
721 3 : request.set_session_id(m_sessionId);
722 3 : request.set_source_id(sourceId);
723 :
724 3 : firebolt::rialto::GetStatsResponse response;
725 3 : auto ipcController = m_ipc.createRpcController();
726 3 : auto blockingClosure = m_ipc.createBlockingClosure();
727 3 : m_mediaPipelineStub->getStats(ipcController.get(), &request, &response, blockingClosure.get());
728 :
729 : // wait for the call to complete
730 3 : blockingClosure->wait();
731 :
732 : // check the result
733 3 : if (ipcController->Failed())
734 : {
735 1 : RIALTO_CLIENT_LOG_ERROR("failed to get stats due to '%s'", ipcController->ErrorText().c_str());
736 1 : return false;
737 : }
738 :
739 2 : renderedFrames = response.rendered_frames();
740 2 : droppedFrames = response.dropped_frames();
741 2 : return true;
742 3 : }
743 :
744 4 : bool MediaPipelineIpc::setPlaybackRate(double rate)
745 : {
746 4 : if (!reattachChannelIfRequired())
747 : {
748 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
749 1 : return false;
750 : }
751 :
752 3 : firebolt::rialto::SetPlaybackRateRequest request;
753 :
754 3 : request.set_session_id(m_sessionId);
755 3 : request.set_rate(rate);
756 :
757 3 : firebolt::rialto::SetPlaybackRateResponse response;
758 3 : auto ipcController = m_ipc.createRpcController();
759 3 : auto blockingClosure = m_ipc.createBlockingClosure();
760 3 : m_mediaPipelineStub->setPlaybackRate(ipcController.get(), &request, &response, blockingClosure.get());
761 :
762 : // wait for the call to complete
763 3 : blockingClosure->wait();
764 :
765 : // check the result
766 3 : if (ipcController->Failed())
767 : {
768 1 : RIALTO_CLIENT_LOG_ERROR("failed to set playback rate due to '%s'", ipcController->ErrorText().c_str());
769 1 : return false;
770 : }
771 :
772 2 : return true;
773 3 : }
774 :
775 4 : bool MediaPipelineIpc::renderFrame()
776 : {
777 4 : if (!reattachChannelIfRequired())
778 : {
779 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
780 1 : return false;
781 : }
782 :
783 3 : firebolt::rialto::RenderFrameRequest request;
784 3 : request.set_session_id(m_sessionId);
785 :
786 3 : firebolt::rialto::RenderFrameResponse response;
787 3 : auto ipcController = m_ipc.createRpcController();
788 3 : auto blockingClosure = m_ipc.createBlockingClosure();
789 3 : m_mediaPipelineStub->renderFrame(ipcController.get(), &request, &response, blockingClosure.get());
790 :
791 : // wait for the call to complete
792 3 : blockingClosure->wait();
793 :
794 : // check the result
795 3 : if (ipcController->Failed())
796 : {
797 1 : RIALTO_CLIENT_LOG_ERROR("failed to render frame due to '%s'", ipcController->ErrorText().c_str());
798 1 : return false;
799 : }
800 :
801 2 : return true;
802 3 : }
803 :
804 4 : bool MediaPipelineIpc::setVolume(double targetVolume, uint32_t volumeDuration, EaseType easeType)
805 : {
806 4 : if (!reattachChannelIfRequired())
807 : {
808 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
809 1 : return false;
810 : }
811 :
812 3 : firebolt::rialto::SetVolumeRequest request;
813 :
814 3 : request.set_session_id(m_sessionId);
815 3 : request.set_volume(targetVolume);
816 3 : request.set_volume_duration(volumeDuration);
817 3 : request.set_ease_type(convertEaseType(easeType));
818 :
819 3 : firebolt::rialto::SetVolumeResponse response;
820 3 : auto ipcController = m_ipc.createRpcController();
821 3 : auto blockingClosure = m_ipc.createBlockingClosure();
822 3 : m_mediaPipelineStub->setVolume(ipcController.get(), &request, &response, blockingClosure.get());
823 :
824 : // wait for the call to complete
825 3 : blockingClosure->wait();
826 :
827 : // check the result
828 3 : if (ipcController->Failed())
829 : {
830 1 : RIALTO_CLIENT_LOG_ERROR("failed to set volume due to '%s'", ipcController->ErrorText().c_str());
831 1 : return false;
832 : }
833 :
834 2 : return true;
835 3 : }
836 :
837 4 : bool MediaPipelineIpc::getVolume(double &volume)
838 : {
839 4 : if (!reattachChannelIfRequired())
840 : {
841 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
842 1 : return false;
843 : }
844 :
845 3 : firebolt::rialto::GetVolumeRequest request;
846 :
847 3 : request.set_session_id(m_sessionId);
848 :
849 3 : firebolt::rialto::GetVolumeResponse response;
850 3 : auto ipcController = m_ipc.createRpcController();
851 3 : auto blockingClosure = m_ipc.createBlockingClosure();
852 3 : m_mediaPipelineStub->getVolume(ipcController.get(), &request, &response, blockingClosure.get());
853 :
854 : // wait for the call to complete
855 3 : blockingClosure->wait();
856 :
857 : // check the result
858 3 : if (ipcController->Failed())
859 : {
860 1 : RIALTO_CLIENT_LOG_ERROR("failed to get volume due to '%s'", ipcController->ErrorText().c_str());
861 1 : return false;
862 : }
863 2 : volume = response.volume();
864 :
865 2 : return true;
866 3 : }
867 :
868 4 : bool MediaPipelineIpc::setMute(int32_t sourceId, bool mute)
869 : {
870 4 : if (!reattachChannelIfRequired())
871 : {
872 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
873 1 : return false;
874 : }
875 :
876 3 : firebolt::rialto::SetMuteRequest request;
877 :
878 3 : request.set_session_id(m_sessionId);
879 3 : request.set_mute(mute);
880 3 : request.set_source_id(sourceId);
881 :
882 3 : firebolt::rialto::SetMuteResponse response;
883 3 : auto ipcController = m_ipc.createRpcController();
884 3 : auto blockingClosure = m_ipc.createBlockingClosure();
885 3 : m_mediaPipelineStub->setMute(ipcController.get(), &request, &response, blockingClosure.get());
886 :
887 : // waiting for call to complete
888 3 : blockingClosure->wait();
889 :
890 : // check the result
891 3 : if (ipcController->Failed())
892 : {
893 1 : RIALTO_CLIENT_LOG_ERROR("failed to set mute due to '%s'", ipcController->ErrorText().c_str());
894 1 : return false;
895 : }
896 :
897 2 : return true;
898 3 : }
899 :
900 4 : bool MediaPipelineIpc::getMute(std::int32_t sourceId, bool &mute)
901 : {
902 4 : if (!reattachChannelIfRequired())
903 : {
904 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
905 1 : return false;
906 : }
907 :
908 3 : firebolt::rialto::GetMuteRequest request;
909 :
910 3 : request.set_session_id(m_sessionId);
911 3 : request.set_source_id(sourceId);
912 :
913 3 : firebolt::rialto::GetMuteResponse response;
914 3 : auto ipcController = m_ipc.createRpcController();
915 3 : auto blockingClosure = m_ipc.createBlockingClosure();
916 3 : m_mediaPipelineStub->getMute(ipcController.get(), &request, &response, blockingClosure.get());
917 :
918 : // wait for the call to complete
919 3 : blockingClosure->wait();
920 :
921 : // check the result
922 3 : if (ipcController->Failed())
923 : {
924 1 : RIALTO_CLIENT_LOG_ERROR("failed to get mute due to '%s'", ipcController->ErrorText().c_str());
925 1 : return false;
926 : }
927 :
928 2 : mute = response.mute();
929 :
930 2 : return true;
931 3 : }
932 :
933 4 : bool MediaPipelineIpc::setTextTrackIdentifier(const std::string &textTrackIdentifier)
934 : {
935 4 : if (!reattachChannelIfRequired())
936 : {
937 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
938 1 : return false;
939 : }
940 :
941 3 : firebolt::rialto::SetTextTrackIdentifierRequest request;
942 :
943 3 : request.set_session_id(m_sessionId);
944 : request.set_text_track_identifier(textTrackIdentifier);
945 :
946 3 : firebolt::rialto::SetTextTrackIdentifierResponse response;
947 3 : auto ipcController = m_ipc.createRpcController();
948 3 : auto blockingClosure = m_ipc.createBlockingClosure();
949 3 : m_mediaPipelineStub->setTextTrackIdentifier(ipcController.get(), &request, &response, blockingClosure.get());
950 :
951 : // waiting for call to complete
952 3 : blockingClosure->wait();
953 :
954 : // check the result
955 3 : if (ipcController->Failed())
956 : {
957 1 : RIALTO_CLIENT_LOG_ERROR("failed to set text track identifier due to '%s'", ipcController->ErrorText().c_str());
958 1 : return false;
959 : }
960 :
961 2 : return true;
962 3 : }
963 :
964 4 : bool MediaPipelineIpc::getTextTrackIdentifier(std::string &textTrackIdentifier)
965 : {
966 4 : if (!reattachChannelIfRequired())
967 : {
968 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
969 1 : return false;
970 : }
971 :
972 3 : firebolt::rialto::GetTextTrackIdentifierRequest request;
973 :
974 3 : request.set_session_id(m_sessionId);
975 :
976 3 : firebolt::rialto::GetTextTrackIdentifierResponse response;
977 3 : auto ipcController = m_ipc.createRpcController();
978 3 : auto blockingClosure = m_ipc.createBlockingClosure();
979 3 : m_mediaPipelineStub->getTextTrackIdentifier(ipcController.get(), &request, &response, blockingClosure.get());
980 :
981 : // wait for the call to complete
982 3 : blockingClosure->wait();
983 :
984 : // check the result
985 3 : if (ipcController->Failed())
986 : {
987 1 : RIALTO_CLIENT_LOG_ERROR("failed to get mute due to '%s'", ipcController->ErrorText().c_str());
988 1 : return false;
989 : }
990 :
991 2 : textTrackIdentifier = response.text_track_identifier();
992 :
993 2 : return true;
994 3 : }
995 :
996 4 : bool MediaPipelineIpc::setLowLatency(bool lowLatency)
997 : {
998 4 : if (!reattachChannelIfRequired())
999 : {
1000 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1001 1 : return false;
1002 : }
1003 :
1004 3 : firebolt::rialto::SetLowLatencyRequest request;
1005 :
1006 3 : request.set_session_id(m_sessionId);
1007 3 : request.set_low_latency(lowLatency);
1008 :
1009 3 : firebolt::rialto::SetLowLatencyResponse response;
1010 3 : auto ipcController = m_ipc.createRpcController();
1011 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1012 3 : m_mediaPipelineStub->setLowLatency(ipcController.get(), &request, &response, blockingClosure.get());
1013 : // waiting for call to complete
1014 3 : blockingClosure->wait();
1015 :
1016 : // check the result
1017 3 : if (ipcController->Failed())
1018 : {
1019 1 : RIALTO_CLIENT_LOG_ERROR("failed to set low-latency due to '%s'", ipcController->ErrorText().c_str());
1020 1 : return false;
1021 : }
1022 :
1023 2 : return true;
1024 3 : }
1025 :
1026 4 : bool MediaPipelineIpc::setSync(bool sync)
1027 : {
1028 4 : if (!reattachChannelIfRequired())
1029 : {
1030 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1031 1 : return false;
1032 : }
1033 :
1034 3 : firebolt::rialto::SetSyncRequest request;
1035 :
1036 3 : request.set_session_id(m_sessionId);
1037 3 : request.set_sync(sync);
1038 :
1039 3 : firebolt::rialto::SetSyncResponse response;
1040 3 : auto ipcController = m_ipc.createRpcController();
1041 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1042 3 : m_mediaPipelineStub->setSync(ipcController.get(), &request, &response, blockingClosure.get());
1043 :
1044 : // waiting for call to complete
1045 3 : blockingClosure->wait();
1046 :
1047 : // check the result
1048 3 : if (ipcController->Failed())
1049 : {
1050 1 : RIALTO_CLIENT_LOG_ERROR("failed to set sync due to '%s'", ipcController->ErrorText().c_str());
1051 1 : return false;
1052 : }
1053 :
1054 2 : return true;
1055 3 : }
1056 :
1057 4 : bool MediaPipelineIpc::getSync(bool &sync)
1058 : {
1059 4 : if (!reattachChannelIfRequired())
1060 : {
1061 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1062 1 : return false;
1063 : }
1064 :
1065 3 : firebolt::rialto::GetSyncRequest request;
1066 :
1067 3 : request.set_session_id(m_sessionId);
1068 :
1069 3 : firebolt::rialto::GetSyncResponse response;
1070 3 : auto ipcController = m_ipc.createRpcController();
1071 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1072 3 : m_mediaPipelineStub->getSync(ipcController.get(), &request, &response, blockingClosure.get());
1073 :
1074 : // wait for the call to complete
1075 3 : blockingClosure->wait();
1076 :
1077 : // check the result
1078 3 : if (ipcController->Failed())
1079 : {
1080 1 : RIALTO_CLIENT_LOG_ERROR("failed to get sync due to '%s'", ipcController->ErrorText().c_str());
1081 1 : return false;
1082 : }
1083 :
1084 2 : sync = response.sync();
1085 :
1086 2 : return true;
1087 3 : }
1088 :
1089 4 : bool MediaPipelineIpc::setSyncOff(bool syncOff)
1090 : {
1091 4 : if (!reattachChannelIfRequired())
1092 : {
1093 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1094 1 : return false;
1095 : }
1096 :
1097 3 : firebolt::rialto::SetSyncOffRequest request;
1098 :
1099 3 : request.set_session_id(m_sessionId);
1100 3 : request.set_sync_off(syncOff);
1101 :
1102 3 : firebolt::rialto::SetSyncOffResponse response;
1103 3 : auto ipcController = m_ipc.createRpcController();
1104 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1105 3 : m_mediaPipelineStub->setSyncOff(ipcController.get(), &request, &response, blockingClosure.get());
1106 :
1107 : // waiting for call to complete
1108 3 : blockingClosure->wait();
1109 :
1110 : // check the result
1111 3 : if (ipcController->Failed())
1112 : {
1113 1 : RIALTO_CLIENT_LOG_ERROR("failed to set sync-off due to '%s'", ipcController->ErrorText().c_str());
1114 1 : return false;
1115 : }
1116 :
1117 2 : return true;
1118 3 : }
1119 :
1120 4 : bool MediaPipelineIpc::setStreamSyncMode(int32_t sourceId, int32_t streamSyncMode)
1121 : {
1122 4 : if (!reattachChannelIfRequired())
1123 : {
1124 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1125 1 : return false;
1126 : }
1127 :
1128 3 : firebolt::rialto::SetStreamSyncModeRequest request;
1129 :
1130 3 : request.set_session_id(m_sessionId);
1131 3 : request.set_source_id(sourceId);
1132 3 : request.set_stream_sync_mode(streamSyncMode);
1133 :
1134 3 : firebolt::rialto::SetStreamSyncModeResponse response;
1135 3 : auto ipcController = m_ipc.createRpcController();
1136 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1137 3 : m_mediaPipelineStub->setStreamSyncMode(ipcController.get(), &request, &response, blockingClosure.get());
1138 :
1139 : // waiting for call to complete
1140 3 : blockingClosure->wait();
1141 :
1142 : // check the result
1143 3 : if (ipcController->Failed())
1144 : {
1145 1 : RIALTO_CLIENT_LOG_ERROR("failed to set stream-sync-mode due to '%s'", ipcController->ErrorText().c_str());
1146 1 : return false;
1147 : }
1148 :
1149 2 : return true;
1150 3 : }
1151 :
1152 4 : bool MediaPipelineIpc::getStreamSyncMode(int32_t &streamSyncMode)
1153 : {
1154 4 : if (!reattachChannelIfRequired())
1155 : {
1156 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1157 1 : return false;
1158 : }
1159 :
1160 3 : firebolt::rialto::GetStreamSyncModeRequest request;
1161 :
1162 3 : request.set_session_id(m_sessionId);
1163 :
1164 3 : firebolt::rialto::GetStreamSyncModeResponse response;
1165 3 : auto ipcController = m_ipc.createRpcController();
1166 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1167 3 : m_mediaPipelineStub->getStreamSyncMode(ipcController.get(), &request, &response, blockingClosure.get());
1168 :
1169 : // wait for the call to complete
1170 3 : blockingClosure->wait();
1171 :
1172 : // check the result
1173 3 : if (ipcController->Failed())
1174 : {
1175 1 : RIALTO_CLIENT_LOG_ERROR("failed to get stream-sync-mode due to '%s'", ipcController->ErrorText().c_str());
1176 1 : return false;
1177 : }
1178 :
1179 2 : streamSyncMode = response.stream_sync_mode();
1180 :
1181 2 : return true;
1182 3 : }
1183 :
1184 4 : bool MediaPipelineIpc::flush(int32_t sourceId, bool resetTime, bool &async)
1185 : {
1186 4 : if (!reattachChannelIfRequired())
1187 : {
1188 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1189 1 : return false;
1190 : }
1191 :
1192 3 : firebolt::rialto::FlushRequest request;
1193 :
1194 3 : request.set_session_id(m_sessionId);
1195 3 : request.set_source_id(sourceId);
1196 3 : request.set_reset_time(resetTime);
1197 :
1198 3 : firebolt::rialto::FlushResponse response;
1199 3 : auto ipcController = m_ipc.createRpcController();
1200 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1201 3 : m_mediaPipelineStub->flush(ipcController.get(), &request, &response, blockingClosure.get());
1202 :
1203 : // wait for the call to complete
1204 3 : blockingClosure->wait();
1205 :
1206 : // check the result
1207 3 : if (ipcController->Failed())
1208 : {
1209 1 : RIALTO_CLIENT_LOG_ERROR("failed to flush due to '%s'", ipcController->ErrorText().c_str());
1210 1 : return false;
1211 : }
1212 :
1213 : // Async is true by default
1214 2 : async = response.has_async() ? response.async() : true;
1215 :
1216 2 : return true;
1217 3 : }
1218 :
1219 4 : bool MediaPipelineIpc::setSourcePosition(int32_t sourceId, int64_t position, bool resetTime, double appliedRate,
1220 : uint64_t stopPosition)
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::SetSourcePositionRequest request;
1229 :
1230 3 : request.set_session_id(m_sessionId);
1231 3 : request.set_source_id(sourceId);
1232 3 : request.set_position(position);
1233 3 : request.set_reset_time(resetTime);
1234 3 : request.set_applied_rate(appliedRate);
1235 3 : request.set_stop_position(stopPosition);
1236 :
1237 3 : firebolt::rialto::SetSourcePositionResponse response;
1238 3 : auto ipcController = m_ipc.createRpcController();
1239 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1240 3 : m_mediaPipelineStub->setSourcePosition(ipcController.get(), &request, &response, blockingClosure.get());
1241 :
1242 : // wait for the call to complete
1243 3 : blockingClosure->wait();
1244 :
1245 : // check the result
1246 3 : if (ipcController->Failed())
1247 : {
1248 1 : RIALTO_CLIENT_LOG_ERROR("failed to set source position due to '%s'", ipcController->ErrorText().c_str());
1249 1 : return false;
1250 : }
1251 :
1252 2 : return true;
1253 3 : }
1254 :
1255 3 : bool MediaPipelineIpc::setSubtitleOffset(int32_t sourceId, int64_t position)
1256 : {
1257 3 : if (!reattachChannelIfRequired())
1258 : {
1259 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1260 1 : return false;
1261 : }
1262 :
1263 2 : firebolt::rialto::SetSubtitleOffsetRequest request;
1264 :
1265 2 : request.set_session_id(m_sessionId);
1266 2 : request.set_source_id(sourceId);
1267 2 : request.set_position(position);
1268 :
1269 2 : firebolt::rialto::SetSubtitleOffsetResponse response;
1270 2 : auto ipcController = m_ipc.createRpcController();
1271 2 : auto blockingClosure = m_ipc.createBlockingClosure();
1272 2 : m_mediaPipelineStub->setSubtitleOffset(ipcController.get(), &request, &response, blockingClosure.get());
1273 :
1274 : // wait for the call to complete
1275 2 : blockingClosure->wait();
1276 :
1277 : // check the result
1278 2 : if (ipcController->Failed())
1279 : {
1280 1 : RIALTO_CLIENT_LOG_ERROR("failed to set subtitle offset due to '%s'", ipcController->ErrorText().c_str());
1281 1 : return false;
1282 : }
1283 :
1284 1 : return true;
1285 2 : }
1286 :
1287 4 : bool MediaPipelineIpc::processAudioGap(int64_t position, uint32_t duration, int64_t discontinuityGap, bool audioAac)
1288 : {
1289 4 : if (!reattachChannelIfRequired())
1290 : {
1291 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1292 1 : return false;
1293 : }
1294 :
1295 3 : firebolt::rialto::ProcessAudioGapRequest request;
1296 :
1297 3 : request.set_session_id(m_sessionId);
1298 3 : request.set_position(position);
1299 3 : request.set_duration(duration);
1300 3 : request.set_discontinuity_gap(discontinuityGap);
1301 3 : request.set_audio_aac(audioAac);
1302 :
1303 3 : firebolt::rialto::ProcessAudioGapResponse response;
1304 3 : auto ipcController = m_ipc.createRpcController();
1305 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1306 3 : m_mediaPipelineStub->processAudioGap(ipcController.get(), &request, &response, blockingClosure.get());
1307 :
1308 : // wait for the call to complete
1309 3 : blockingClosure->wait();
1310 :
1311 : // check the result
1312 3 : if (ipcController->Failed())
1313 : {
1314 1 : RIALTO_CLIENT_LOG_ERROR("failed to process audio gap due to '%s'", ipcController->ErrorText().c_str());
1315 1 : return false;
1316 : }
1317 :
1318 2 : return true;
1319 3 : }
1320 :
1321 4 : bool MediaPipelineIpc::setBufferingLimit(uint32_t limitBufferingMs)
1322 : {
1323 4 : if (!reattachChannelIfRequired())
1324 : {
1325 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1326 1 : return false;
1327 : }
1328 :
1329 3 : firebolt::rialto::SetBufferingLimitRequest request;
1330 :
1331 3 : request.set_session_id(m_sessionId);
1332 3 : request.set_limit_buffering_ms(limitBufferingMs);
1333 :
1334 3 : firebolt::rialto::SetBufferingLimitResponse response;
1335 3 : auto ipcController = m_ipc.createRpcController();
1336 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1337 3 : m_mediaPipelineStub->setBufferingLimit(ipcController.get(), &request, &response, blockingClosure.get());
1338 :
1339 : // wait for the call to complete
1340 3 : blockingClosure->wait();
1341 :
1342 : // check the result
1343 3 : if (ipcController->Failed())
1344 : {
1345 1 : RIALTO_CLIENT_LOG_ERROR("failed to set buffering limit due to '%s'", ipcController->ErrorText().c_str());
1346 1 : return false;
1347 : }
1348 :
1349 2 : return true;
1350 3 : }
1351 :
1352 4 : bool MediaPipelineIpc::getBufferingLimit(uint32_t &limitBufferingMs)
1353 : {
1354 4 : if (!reattachChannelIfRequired())
1355 : {
1356 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1357 1 : return false;
1358 : }
1359 :
1360 3 : firebolt::rialto::GetBufferingLimitRequest request;
1361 :
1362 3 : request.set_session_id(m_sessionId);
1363 :
1364 3 : firebolt::rialto::GetBufferingLimitResponse response;
1365 3 : auto ipcController = m_ipc.createRpcController();
1366 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1367 3 : m_mediaPipelineStub->getBufferingLimit(ipcController.get(), &request, &response, blockingClosure.get());
1368 :
1369 : // wait for the call to complete
1370 3 : blockingClosure->wait();
1371 :
1372 : // check the result
1373 3 : if (ipcController->Failed())
1374 : {
1375 1 : RIALTO_CLIENT_LOG_ERROR("failed to get buffering limit due to '%s'", ipcController->ErrorText().c_str());
1376 1 : return false;
1377 : }
1378 :
1379 2 : limitBufferingMs = response.limit_buffering_ms();
1380 :
1381 2 : return true;
1382 3 : }
1383 :
1384 4 : bool MediaPipelineIpc::setUseBuffering(bool useBuffering)
1385 : {
1386 4 : if (!reattachChannelIfRequired())
1387 : {
1388 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1389 1 : return false;
1390 : }
1391 :
1392 3 : firebolt::rialto::SetUseBufferingRequest request;
1393 :
1394 3 : request.set_session_id(m_sessionId);
1395 3 : request.set_use_buffering(useBuffering);
1396 :
1397 3 : firebolt::rialto::SetUseBufferingResponse response;
1398 3 : auto ipcController = m_ipc.createRpcController();
1399 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1400 3 : m_mediaPipelineStub->setUseBuffering(ipcController.get(), &request, &response, blockingClosure.get());
1401 :
1402 : // wait for the call to complete
1403 3 : blockingClosure->wait();
1404 :
1405 : // check the result
1406 3 : if (ipcController->Failed())
1407 : {
1408 1 : RIALTO_CLIENT_LOG_ERROR("failed to set use buffering due to '%s'", ipcController->ErrorText().c_str());
1409 1 : return false;
1410 : }
1411 :
1412 2 : return true;
1413 3 : }
1414 :
1415 4 : bool MediaPipelineIpc::getUseBuffering(bool &useBuffering)
1416 : {
1417 4 : if (!reattachChannelIfRequired())
1418 : {
1419 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1420 1 : return false;
1421 : }
1422 :
1423 3 : firebolt::rialto::GetUseBufferingRequest request;
1424 :
1425 3 : request.set_session_id(m_sessionId);
1426 :
1427 3 : firebolt::rialto::GetUseBufferingResponse response;
1428 3 : auto ipcController = m_ipc.createRpcController();
1429 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1430 3 : m_mediaPipelineStub->getUseBuffering(ipcController.get(), &request, &response, blockingClosure.get());
1431 :
1432 : // wait for the call to complete
1433 3 : blockingClosure->wait();
1434 :
1435 : // check the result
1436 3 : if (ipcController->Failed())
1437 : {
1438 1 : RIALTO_CLIENT_LOG_ERROR("failed to get use buffering due to '%s'", ipcController->ErrorText().c_str());
1439 1 : return false;
1440 : }
1441 :
1442 2 : useBuffering = response.use_buffering();
1443 :
1444 2 : return true;
1445 3 : }
1446 :
1447 5 : bool MediaPipelineIpc::switchSource(const std::unique_ptr<IMediaPipeline::MediaSource> &source)
1448 : {
1449 5 : if (!reattachChannelIfRequired())
1450 : {
1451 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1452 1 : return false;
1453 : }
1454 :
1455 4 : firebolt::rialto::AttachSourceRequest request;
1456 :
1457 4 : request.set_session_id(m_sessionId);
1458 4 : request.set_switch_source(true);
1459 4 : if (!buildAttachSourceRequest(request, source))
1460 : {
1461 1 : RIALTO_CLIENT_LOG_ERROR("Failed to parse source");
1462 1 : return false;
1463 : }
1464 :
1465 3 : firebolt::rialto::AttachSourceResponse response;
1466 3 : auto ipcController = m_ipc.createRpcController();
1467 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1468 3 : m_mediaPipelineStub->attachSource(ipcController.get(), &request, &response, blockingClosure.get());
1469 :
1470 : // wait for the call to complete
1471 3 : blockingClosure->wait();
1472 :
1473 : // check the result
1474 3 : if (ipcController->Failed())
1475 : {
1476 1 : RIALTO_CLIENT_LOG_ERROR("failed to attach source due to '%s'", ipcController->ErrorText().c_str());
1477 1 : return false;
1478 : }
1479 :
1480 2 : return true;
1481 4 : }
1482 :
1483 2 : void MediaPipelineIpc::onPlaybackStateUpdated(const std::shared_ptr<firebolt::rialto::PlaybackStateChangeEvent> &event)
1484 : {
1485 : /* Ignore event if not for this session */
1486 2 : if (event->session_id() == m_sessionId)
1487 : {
1488 1 : PlaybackState playbackState = PlaybackState::UNKNOWN;
1489 1 : switch (event->state())
1490 : {
1491 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_IDLE:
1492 0 : playbackState = PlaybackState::IDLE;
1493 0 : break;
1494 1 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_PLAYING:
1495 1 : playbackState = PlaybackState::PLAYING;
1496 1 : break;
1497 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_PAUSED:
1498 0 : playbackState = PlaybackState::PAUSED;
1499 0 : break;
1500 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_SEEKING:
1501 0 : playbackState = PlaybackState::SEEKING;
1502 0 : break;
1503 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_SEEK_DONE:
1504 0 : playbackState = PlaybackState::SEEK_DONE;
1505 0 : break;
1506 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_STOPPED:
1507 0 : playbackState = PlaybackState::STOPPED;
1508 0 : break;
1509 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_END_OF_STREAM:
1510 0 : playbackState = PlaybackState::END_OF_STREAM;
1511 0 : break;
1512 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_FAILURE:
1513 0 : playbackState = PlaybackState::FAILURE;
1514 0 : break;
1515 0 : default:
1516 0 : RIALTO_CLIENT_LOG_WARN("Received unknown playback state");
1517 0 : break;
1518 : }
1519 :
1520 1 : m_mediaPipelineIpcClient->notifyPlaybackState(playbackState);
1521 : }
1522 2 : }
1523 :
1524 0 : void MediaPipelineIpc::onPositionUpdated(const std::shared_ptr<firebolt::rialto::PositionChangeEvent> &event)
1525 : {
1526 : // Ignore event if not for this session
1527 0 : if (event->session_id() == m_sessionId)
1528 : {
1529 0 : int64_t position = event->position();
1530 0 : m_mediaPipelineIpcClient->notifyPosition(position);
1531 : }
1532 : }
1533 :
1534 2 : void MediaPipelineIpc::onNetworkStateUpdated(const std::shared_ptr<firebolt::rialto::NetworkStateChangeEvent> &event)
1535 : {
1536 : // Ignore event if not for this session
1537 2 : if (event->session_id() == m_sessionId)
1538 : {
1539 1 : NetworkState networkState = NetworkState::UNKNOWN;
1540 1 : switch (event->state())
1541 : {
1542 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_IDLE:
1543 0 : networkState = NetworkState::IDLE;
1544 0 : break;
1545 1 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERING:
1546 1 : networkState = NetworkState::BUFFERING;
1547 1 : break;
1548 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERING_PROGRESS:
1549 0 : networkState = NetworkState::BUFFERING_PROGRESS;
1550 0 : break;
1551 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERED:
1552 0 : networkState = NetworkState::BUFFERED;
1553 0 : break;
1554 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_STALLED:
1555 0 : networkState = NetworkState::STALLED;
1556 0 : break;
1557 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_FORMAT_ERROR:
1558 0 : networkState = NetworkState::FORMAT_ERROR;
1559 0 : break;
1560 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_NETWORK_ERROR:
1561 0 : networkState = NetworkState::NETWORK_ERROR;
1562 0 : break;
1563 0 : default:
1564 0 : RIALTO_CLIENT_LOG_WARN("Received unknown network state");
1565 0 : break;
1566 : }
1567 :
1568 1 : m_mediaPipelineIpcClient->notifyNetworkState(networkState);
1569 : }
1570 2 : }
1571 :
1572 3 : void MediaPipelineIpc::onNeedMediaData(const std::shared_ptr<firebolt::rialto::NeedMediaDataEvent> &event)
1573 : {
1574 : // Ignore event if not for this session
1575 3 : if (event->session_id() == m_sessionId)
1576 : {
1577 2 : std::shared_ptr<MediaPlayerShmInfo> shmInfo;
1578 2 : if (event->has_shm_info())
1579 : {
1580 1 : shmInfo = std::make_shared<MediaPlayerShmInfo>();
1581 1 : shmInfo->maxMetadataBytes = event->shm_info().max_metadata_bytes();
1582 1 : shmInfo->metadataOffset = event->shm_info().metadata_offset();
1583 1 : shmInfo->mediaDataOffset = event->shm_info().media_data_offset();
1584 1 : shmInfo->maxMediaBytes = event->shm_info().max_media_bytes();
1585 : }
1586 2 : m_mediaPipelineIpcClient->notifyNeedMediaData(event->source_id(), event->frame_count(), event->request_id(),
1587 : shmInfo);
1588 : }
1589 3 : }
1590 :
1591 2 : void MediaPipelineIpc::onQos(const std::shared_ptr<firebolt::rialto::QosEvent> &event)
1592 : {
1593 : // Ignore event if not for this session
1594 2 : if (event->session_id() == m_sessionId)
1595 : {
1596 1 : QosInfo qosInfo = {event->qos_info().processed(), event->qos_info().dropped()};
1597 1 : m_mediaPipelineIpcClient->notifyQos(event->source_id(), qosInfo);
1598 : }
1599 2 : }
1600 :
1601 0 : void MediaPipelineIpc::onBufferUnderflow(const std::shared_ptr<firebolt::rialto::BufferUnderflowEvent> &event)
1602 : {
1603 : // Ignore event if not for this session
1604 0 : if (event->session_id() == m_sessionId)
1605 : {
1606 0 : m_mediaPipelineIpcClient->notifyBufferUnderflow(event->source_id());
1607 : }
1608 : }
1609 :
1610 2 : void MediaPipelineIpc::onFirstFrameReceived(const std::shared_ptr<firebolt::rialto::FirstFrameReceivedEvent> &event)
1611 : {
1612 : // Ignore event if not for this session
1613 2 : if (event->session_id() == m_sessionId)
1614 : {
1615 1 : m_mediaPipelineIpcClient->notifyFirstFrameReceived(event->source_id());
1616 : }
1617 2 : }
1618 :
1619 2 : void MediaPipelineIpc::onPlaybackError(const std::shared_ptr<firebolt::rialto::PlaybackErrorEvent> &event)
1620 : {
1621 : // Ignore event if not for this session
1622 2 : if (event->session_id() == m_sessionId)
1623 : {
1624 1 : PlaybackError playbackError = PlaybackError::UNKNOWN;
1625 1 : switch (event->error())
1626 : {
1627 1 : case firebolt::rialto::PlaybackErrorEvent_PlaybackError_DECRYPTION:
1628 1 : playbackError = PlaybackError::DECRYPTION;
1629 1 : break;
1630 0 : case firebolt::rialto::PlaybackErrorEvent_PlaybackError_OUTPUT_PROTECTION:
1631 0 : playbackError = PlaybackError::OUTPUT_PROTECTION;
1632 0 : break;
1633 0 : default:
1634 0 : RIALTO_CLIENT_LOG_WARN("Received unknown playback error");
1635 0 : break;
1636 : }
1637 :
1638 1 : m_mediaPipelineIpcClient->notifyPlaybackError(event->source_id(), playbackError);
1639 : }
1640 2 : }
1641 :
1642 2 : void MediaPipelineIpc::onSourceFlushed(const std::shared_ptr<firebolt::rialto::SourceFlushedEvent> &event)
1643 : {
1644 : // Ignore event if not for this session
1645 2 : if (event->session_id() == m_sessionId)
1646 : {
1647 1 : m_mediaPipelineIpcClient->notifySourceFlushed(event->source_id());
1648 : }
1649 2 : }
1650 :
1651 1 : void MediaPipelineIpc::onPlaybackInfo(const std::shared_ptr<firebolt::rialto::PlaybackInfoEvent> &event)
1652 : {
1653 1 : if (event->session_id() == m_sessionId)
1654 : {
1655 1 : PlaybackInfo playbackInfo;
1656 1 : playbackInfo.currentPosition = event->current_position();
1657 1 : playbackInfo.volume = event->volume();
1658 1 : m_mediaPipelineIpcClient->notifyPlaybackInfo(playbackInfo);
1659 : }
1660 : }
1661 :
1662 188 : bool MediaPipelineIpc::createSession(const VideoRequirements &videoRequirements)
1663 : {
1664 188 : if (!reattachChannelIfRequired())
1665 : {
1666 0 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1667 0 : return false;
1668 : }
1669 :
1670 188 : firebolt::rialto::CreateSessionRequest request;
1671 :
1672 188 : request.set_max_width(videoRequirements.maxWidth);
1673 188 : request.set_max_height(videoRequirements.maxHeight);
1674 :
1675 188 : firebolt::rialto::CreateSessionResponse response;
1676 188 : auto ipcController = m_ipc.createRpcController();
1677 188 : auto blockingClosure = m_ipc.createBlockingClosure();
1678 188 : m_mediaPipelineStub->createSession(ipcController.get(), &request, &response, blockingClosure.get());
1679 :
1680 : // wait for the call to complete
1681 188 : blockingClosure->wait();
1682 :
1683 : // check the result
1684 188 : if (ipcController->Failed())
1685 : {
1686 1 : RIALTO_CLIENT_LOG_ERROR("failed to create session due to '%s'", ipcController->ErrorText().c_str());
1687 1 : return false;
1688 : }
1689 :
1690 187 : m_sessionId = response.session_id();
1691 :
1692 187 : return true;
1693 188 : }
1694 :
1695 187 : void MediaPipelineIpc::destroySession()
1696 : {
1697 187 : if (!reattachChannelIfRequired())
1698 : {
1699 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1700 1 : return;
1701 : }
1702 :
1703 186 : firebolt::rialto::DestroySessionRequest request;
1704 186 : request.set_session_id(m_sessionId);
1705 :
1706 186 : firebolt::rialto::DestroySessionResponse response;
1707 186 : auto ipcController = m_ipc.createRpcController();
1708 186 : auto blockingClosure = m_ipc.createBlockingClosure();
1709 186 : m_mediaPipelineStub->destroySession(ipcController.get(), &request, &response, blockingClosure.get());
1710 :
1711 : // wait for the call to complete
1712 186 : blockingClosure->wait();
1713 :
1714 : // check the result
1715 186 : if (ipcController->Failed())
1716 : {
1717 1 : RIALTO_CLIENT_LOG_ERROR("failed to destroy session due to '%s'", ipcController->ErrorText().c_str());
1718 : }
1719 186 : }
1720 :
1721 3 : firebolt::rialto::LoadRequest_MediaType MediaPipelineIpc::convertLoadRequestMediaType(MediaType mediaType) const
1722 : {
1723 3 : firebolt::rialto::LoadRequest_MediaType protoMediaType = firebolt::rialto::LoadRequest_MediaType_UNKNOWN;
1724 3 : switch (mediaType)
1725 : {
1726 3 : case MediaType::MSE:
1727 3 : protoMediaType = firebolt::rialto::LoadRequest_MediaType_MSE;
1728 3 : break;
1729 0 : default:
1730 0 : break;
1731 : }
1732 :
1733 3 : return protoMediaType;
1734 : }
1735 :
1736 : firebolt::rialto::HaveDataRequest_MediaSourceStatus
1737 3 : MediaPipelineIpc::convertHaveDataRequestMediaSourceStatus(MediaSourceStatus status) const
1738 : {
1739 3 : firebolt::rialto::HaveDataRequest_MediaSourceStatus protoMediaSourceStatus =
1740 : firebolt::rialto::HaveDataRequest_MediaSourceStatus_UNKNOWN;
1741 3 : switch (status)
1742 : {
1743 3 : case MediaSourceStatus::OK:
1744 3 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_OK;
1745 3 : break;
1746 0 : case MediaSourceStatus::EOS:
1747 0 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_EOS;
1748 0 : break;
1749 0 : case MediaSourceStatus::ERROR:
1750 0 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_ERROR;
1751 0 : break;
1752 0 : case MediaSourceStatus::CODEC_CHANGED:
1753 0 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_CODEC_CHANGED;
1754 0 : break;
1755 0 : case MediaSourceStatus::NO_AVAILABLE_SAMPLES:
1756 0 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_NO_AVAILABLE_SAMPLES;
1757 0 : break;
1758 0 : case MediaSourceStatus::NO_SPACE_FOR_SAMPLES:
1759 0 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_NO_SPACE_FOR_SAMPLES;
1760 0 : break;
1761 0 : default:
1762 0 : break;
1763 : }
1764 :
1765 3 : return protoMediaSourceStatus;
1766 : }
1767 :
1768 : firebolt::rialto::AttachSourceRequest_ConfigType
1769 17 : MediaPipelineIpc::convertConfigType(const firebolt::rialto::SourceConfigType &configType) const
1770 : {
1771 17 : switch (configType)
1772 : {
1773 0 : case firebolt::rialto::SourceConfigType::UNKNOWN:
1774 : {
1775 0 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_UNKNOWN;
1776 : }
1777 9 : case firebolt::rialto::SourceConfigType::AUDIO:
1778 : {
1779 9 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_AUDIO;
1780 : }
1781 3 : case firebolt::rialto::SourceConfigType::VIDEO:
1782 : {
1783 3 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_VIDEO;
1784 : }
1785 3 : case firebolt::rialto::SourceConfigType::VIDEO_DOLBY_VISION:
1786 : {
1787 3 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_VIDEO_DOLBY_VISION;
1788 : }
1789 2 : case firebolt::rialto::SourceConfigType::SUBTITLE:
1790 : {
1791 2 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_SUBTITLE;
1792 : }
1793 : }
1794 0 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_UNKNOWN;
1795 : }
1796 :
1797 3 : firebolt::rialto::SetVolumeRequest_EaseType MediaPipelineIpc::convertEaseType(const firebolt::rialto::EaseType &easeType) const
1798 : {
1799 3 : switch (easeType)
1800 : {
1801 3 : case firebolt::rialto::EaseType::EASE_LINEAR:
1802 : {
1803 3 : return firebolt::rialto::SetVolumeRequest_EaseType_EASE_LINEAR;
1804 : }
1805 0 : case firebolt::rialto::EaseType::EASE_IN_CUBIC:
1806 : {
1807 0 : return firebolt::rialto::SetVolumeRequest_EaseType_EASE_IN_CUBIC;
1808 : }
1809 0 : case firebolt::rialto::EaseType::EASE_OUT_CUBIC:
1810 : {
1811 0 : return firebolt::rialto::SetVolumeRequest_EaseType_EASE_OUT_CUBIC;
1812 : }
1813 : }
1814 0 : return firebolt::rialto::SetVolumeRequest_EaseType_EASE_LINEAR;
1815 : }
1816 :
1817 : firebolt::rialto::AttachSourceRequest_SegmentAlignment
1818 14 : MediaPipelineIpc::convertSegmentAlignment(const firebolt::rialto::SegmentAlignment &alignment) const
1819 : {
1820 14 : switch (alignment)
1821 : {
1822 14 : case firebolt::rialto::SegmentAlignment::UNDEFINED:
1823 : {
1824 14 : return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_UNDEFINED;
1825 : }
1826 0 : case firebolt::rialto::SegmentAlignment::NAL:
1827 : {
1828 0 : return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_NAL;
1829 : }
1830 0 : case firebolt::rialto::SegmentAlignment::AU:
1831 : {
1832 0 : return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_AU;
1833 : }
1834 : }
1835 0 : return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_UNDEFINED;
1836 : }
1837 :
1838 : firebolt::rialto::AttachSourceRequest_StreamFormat
1839 14 : MediaPipelineIpc::convertStreamFormat(const firebolt::rialto::StreamFormat &streamFormat) const
1840 : {
1841 14 : switch (streamFormat)
1842 : {
1843 8 : case firebolt::rialto::StreamFormat::UNDEFINED:
1844 : {
1845 8 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_UNDEFINED;
1846 : }
1847 6 : case firebolt::rialto::StreamFormat::RAW:
1848 : {
1849 6 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_RAW;
1850 : }
1851 0 : case firebolt::rialto::StreamFormat::AVC:
1852 : {
1853 0 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_AVC;
1854 : }
1855 0 : case firebolt::rialto::StreamFormat::BYTE_STREAM:
1856 : {
1857 0 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_BYTE_STREAM;
1858 : }
1859 0 : case firebolt::rialto::StreamFormat::HVC1:
1860 : {
1861 0 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_HVC1;
1862 : }
1863 0 : case firebolt::rialto::StreamFormat::HEV1:
1864 : {
1865 0 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_HEV1;
1866 : }
1867 : }
1868 0 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_UNDEFINED;
1869 : }
1870 :
1871 : firebolt::rialto::AttachSourceRequest_CodecData_Type
1872 3 : MediaPipelineIpc::convertCodecDataType(const firebolt::rialto::CodecDataType &codecDataType) const
1873 : {
1874 3 : if (firebolt::rialto::CodecDataType::STRING == codecDataType)
1875 : {
1876 0 : return firebolt::rialto::AttachSourceRequest_CodecData_Type_STRING;
1877 : }
1878 3 : return firebolt::rialto::AttachSourceRequest_CodecData_Type_BUFFER;
1879 : }
1880 :
1881 : firebolt::rialto::AttachSourceRequest_AudioConfig_Format
1882 0 : MediaPipelineIpc::convertFormat(const firebolt::rialto::Format &format) const
1883 : {
1884 : static const std::unordered_map<firebolt::rialto::Format, firebolt::rialto::AttachSourceRequest_AudioConfig_Format>
1885 : kFormatConversionMap{
1886 : {firebolt::rialto::Format::S8, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S8},
1887 : {firebolt::rialto::Format::U8, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U8},
1888 : {firebolt::rialto::Format::S16LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S16LE},
1889 : {firebolt::rialto::Format::S16BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S16BE},
1890 : {firebolt::rialto::Format::U16LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U16LE},
1891 : {firebolt::rialto::Format::U16BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U16BE},
1892 : {firebolt::rialto::Format::S24_32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24_32LE},
1893 : {firebolt::rialto::Format::S24_32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24_32BE},
1894 : {firebolt::rialto::Format::U24_32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24_32LE},
1895 : {firebolt::rialto::Format::U24_32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24_32BE},
1896 : {firebolt::rialto::Format::S32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S32LE},
1897 : {firebolt::rialto::Format::S32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S32BE},
1898 : {firebolt::rialto::Format::U32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U32LE},
1899 : {firebolt::rialto::Format::U32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U32BE},
1900 : {firebolt::rialto::Format::S24LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24LE},
1901 : {firebolt::rialto::Format::S24BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24BE},
1902 : {firebolt::rialto::Format::U24LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24LE},
1903 : {firebolt::rialto::Format::U24BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24BE},
1904 : {firebolt::rialto::Format::S20LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S20LE},
1905 : {firebolt::rialto::Format::S20BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S20BE},
1906 : {firebolt::rialto::Format::U20LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U20LE},
1907 : {firebolt::rialto::Format::U20BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U20BE},
1908 : {firebolt::rialto::Format::S18LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S18LE},
1909 : {firebolt::rialto::Format::S18BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S18BE},
1910 : {firebolt::rialto::Format::U18LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U18LE},
1911 : {firebolt::rialto::Format::U18BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U18BE},
1912 : {firebolt::rialto::Format::F32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F32LE},
1913 : {firebolt::rialto::Format::F32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F32BE},
1914 : {firebolt::rialto::Format::F64LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F64LE},
1915 0 : {firebolt::rialto::Format::F64BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F64BE}};
1916 0 : const auto kIt = kFormatConversionMap.find(format);
1917 0 : if (kFormatConversionMap.end() != kIt)
1918 : {
1919 0 : return kIt->second;
1920 : }
1921 0 : return firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S8;
1922 : }
1923 :
1924 : firebolt::rialto::AttachSourceRequest_AudioConfig_Layout
1925 0 : MediaPipelineIpc::convertLayout(const firebolt::rialto::Layout &layout) const
1926 : {
1927 : static const std::unordered_map<firebolt::rialto::Layout, firebolt::rialto::AttachSourceRequest_AudioConfig_Layout>
1928 : kLayoutConversionMap{{firebolt::rialto::Layout::INTERLEAVED,
1929 : firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_INTERLEAVED},
1930 : {firebolt::rialto::Layout::NON_INTERLEAVED,
1931 0 : firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_NON_INTERLEAVED}};
1932 0 : const auto kIt = kLayoutConversionMap.find(layout);
1933 0 : if (kLayoutConversionMap.end() != kIt)
1934 : {
1935 0 : return kIt->second;
1936 : }
1937 0 : return firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_INTERLEAVED;
1938 : }
1939 :
1940 17 : bool MediaPipelineIpc::buildAttachSourceRequest(firebolt::rialto::AttachSourceRequest &request,
1941 : const std::unique_ptr<IMediaPipeline::MediaSource> &source) const
1942 : {
1943 17 : SourceConfigType configType = source->getConfigType();
1944 17 : request.set_config_type(convertConfigType(configType));
1945 34 : request.set_mime_type(source->getMimeType());
1946 17 : request.set_has_drm(source->getHasDrm());
1947 :
1948 17 : if (configType == SourceConfigType::VIDEO_DOLBY_VISION || configType == SourceConfigType::VIDEO ||
1949 11 : configType == SourceConfigType::AUDIO)
1950 : {
1951 15 : IMediaPipeline::MediaSourceAV *mediaSourceAV = dynamic_cast<IMediaPipeline::MediaSourceAV *>(source.get());
1952 15 : if (!mediaSourceAV)
1953 : {
1954 1 : RIALTO_CLIENT_LOG_ERROR("Failed to get the audio video source");
1955 1 : return false;
1956 : }
1957 14 : request.set_segment_alignment(convertSegmentAlignment(mediaSourceAV->getSegmentAlignment()));
1958 :
1959 14 : if (mediaSourceAV->getCodecData())
1960 : {
1961 6 : request.mutable_codec_data()->set_data(mediaSourceAV->getCodecData()->data.data(),
1962 3 : mediaSourceAV->getCodecData()->data.size());
1963 3 : request.mutable_codec_data()->set_type(convertCodecDataType(mediaSourceAV->getCodecData()->type));
1964 : }
1965 14 : request.set_stream_format(convertStreamFormat(mediaSourceAV->getStreamFormat()));
1966 :
1967 14 : if (configType == SourceConfigType::VIDEO_DOLBY_VISION)
1968 : {
1969 : IMediaPipeline::MediaSourceVideoDolbyVision *mediaSourceDolby =
1970 2 : dynamic_cast<IMediaPipeline::MediaSourceVideoDolbyVision *>(source.get());
1971 2 : if (!mediaSourceDolby)
1972 : {
1973 1 : RIALTO_CLIENT_LOG_ERROR("Failed to get the video dolby vision media source");
1974 1 : return false;
1975 : }
1976 1 : request.set_width(mediaSourceDolby->getWidth());
1977 1 : request.set_height(mediaSourceDolby->getHeight());
1978 1 : request.set_dolby_vision_profile(mediaSourceDolby->getDolbyVisionProfile());
1979 : }
1980 12 : else if (configType == SourceConfigType::VIDEO)
1981 : {
1982 : IMediaPipeline::MediaSourceVideo *mediaSourceVideo =
1983 3 : dynamic_cast<IMediaPipeline::MediaSourceVideo *>(source.get());
1984 3 : if (!mediaSourceVideo)
1985 : {
1986 1 : RIALTO_CLIENT_LOG_ERROR("Failed to get the video media source");
1987 1 : return false;
1988 : }
1989 2 : request.set_width(mediaSourceVideo->getWidth());
1990 2 : request.set_height(mediaSourceVideo->getHeight());
1991 : }
1992 9 : else if (configType == SourceConfigType::AUDIO)
1993 : {
1994 : IMediaPipeline::MediaSourceAudio *mediaSourceAudio =
1995 9 : dynamic_cast<IMediaPipeline::MediaSourceAudio *>(source.get());
1996 9 : if (!mediaSourceAudio)
1997 : {
1998 2 : RIALTO_CLIENT_LOG_ERROR("Failed to get the audio media source");
1999 2 : return false;
2000 : }
2001 7 : request.mutable_audio_config()->set_number_of_channels(mediaSourceAudio->getAudioConfig().numberOfChannels);
2002 7 : request.mutable_audio_config()->set_sample_rate(mediaSourceAudio->getAudioConfig().sampleRate);
2003 7 : if (!mediaSourceAudio->getAudioConfig().codecSpecificConfig.empty())
2004 : {
2005 : request.mutable_audio_config()
2006 9 : ->set_codec_specific_config(mediaSourceAudio->getAudioConfig().codecSpecificConfig.data(),
2007 3 : mediaSourceAudio->getAudioConfig().codecSpecificConfig.size());
2008 : }
2009 7 : if (mediaSourceAudio->getAudioConfig().format.has_value())
2010 : {
2011 0 : request.mutable_audio_config()->set_format(
2012 0 : convertFormat(mediaSourceAudio->getAudioConfig().format.value()));
2013 : }
2014 7 : if (mediaSourceAudio->getAudioConfig().layout.has_value())
2015 : {
2016 0 : request.mutable_audio_config()->set_layout(
2017 0 : convertLayout(mediaSourceAudio->getAudioConfig().layout.value()));
2018 : }
2019 7 : if (mediaSourceAudio->getAudioConfig().channelMask.has_value())
2020 : {
2021 0 : request.mutable_audio_config()->set_channel_mask(mediaSourceAudio->getAudioConfig().channelMask.value());
2022 : }
2023 7 : for (auto &header : mediaSourceAudio->getAudioConfig().streamHeader)
2024 : {
2025 0 : request.mutable_audio_config()->add_stream_header(header.data(), header.size());
2026 : }
2027 7 : if (mediaSourceAudio->getAudioConfig().framed.has_value())
2028 : {
2029 0 : request.mutable_audio_config()->set_framed(mediaSourceAudio->getAudioConfig().framed.value());
2030 : }
2031 : }
2032 10 : }
2033 2 : else if (configType == SourceConfigType::SUBTITLE)
2034 : {
2035 : IMediaPipeline::MediaSourceSubtitle *mediaSourceSubtitle =
2036 2 : dynamic_cast<IMediaPipeline::MediaSourceSubtitle *>(source.get());
2037 2 : if (!mediaSourceSubtitle)
2038 : {
2039 1 : RIALTO_CLIENT_LOG_ERROR("Failed to get the subtitle source");
2040 1 : return false;
2041 : }
2042 1 : request.set_text_track_identifier(mediaSourceSubtitle->getTextTrackIdentifier());
2043 : }
2044 : else
2045 : {
2046 0 : RIALTO_CLIENT_LOG_ERROR("Unknown source type");
2047 0 : return false;
2048 : }
2049 11 : return true;
2050 : }
2051 : }; // namespace firebolt::rialto::client
|