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