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