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