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