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 177 : MediaPipelineIpc::MediaPipelineIpc(IMediaPipelineIpcClient *client, const VideoRequirements &videoRequirements,
72 : IIpcClient &ipcClient,
73 177 : const std::shared_ptr<common::IEventThreadFactory> &eventThreadFactory)
74 177 : : IpcModule(ipcClient), m_mediaPipelineIpcClient(client),
75 354 : m_eventThread(eventThreadFactory->createEventThread("rialto-media-player-events"))
76 : {
77 177 : if (!attachChannel())
78 : {
79 4 : throw std::runtime_error("Failed attach to the ipc channel");
80 : }
81 :
82 : // create media player session
83 173 : if (!createSession(videoRequirements))
84 : {
85 1 : detachChannel();
86 1 : throw std::runtime_error("Could not create the media player session");
87 : }
88 192 : }
89 :
90 344 : MediaPipelineIpc::~MediaPipelineIpc()
91 : {
92 : // destroy media player session
93 172 : destroySession();
94 :
95 : // detach the Ipc channel
96 172 : detachChannel();
97 :
98 : // destroy the thread processing async notifications
99 172 : m_eventThread.reset();
100 344 : }
101 :
102 245 : bool MediaPipelineIpc::createRpcStubs(const std::shared_ptr<ipc::IChannel> &ipcChannel)
103 : {
104 245 : m_mediaPipelineStub = std::make_unique<::firebolt::rialto::MediaPipelineModule_Stub>(ipcChannel.get());
105 245 : if (!m_mediaPipelineStub)
106 : {
107 0 : return false;
108 : }
109 245 : return true;
110 : }
111 :
112 245 : bool MediaPipelineIpc::subscribeToEvents(const std::shared_ptr<ipc::IChannel> &ipcChannel)
113 : {
114 245 : if (!ipcChannel)
115 : {
116 0 : return false;
117 : }
118 :
119 490 : int eventTag = ipcChannel->subscribe<firebolt::rialto::PlaybackStateChangeEvent>(
120 245 : [this](const std::shared_ptr<firebolt::rialto::PlaybackStateChangeEvent> &event)
121 247 : { m_eventThread->add(&MediaPipelineIpc::onPlaybackStateUpdated, this, event); });
122 245 : if (eventTag < 0)
123 0 : return false;
124 245 : m_eventTags.push_back(eventTag);
125 :
126 490 : eventTag = ipcChannel->subscribe<firebolt::rialto::PositionChangeEvent>(
127 245 : [this](const std::shared_ptr<firebolt::rialto::PositionChangeEvent> &event)
128 0 : { m_eventThread->add(&MediaPipelineIpc::onPositionUpdated, this, event); });
129 245 : if (eventTag < 0)
130 1 : return false;
131 244 : m_eventTags.push_back(eventTag);
132 :
133 488 : eventTag = ipcChannel->subscribe<firebolt::rialto::NetworkStateChangeEvent>(
134 244 : [this](const std::shared_ptr<firebolt::rialto::NetworkStateChangeEvent> &event)
135 2 : { m_eventThread->add(&MediaPipelineIpc::onNetworkStateUpdated, this, event); });
136 244 : if (eventTag < 0)
137 0 : return false;
138 244 : m_eventTags.push_back(eventTag);
139 :
140 488 : eventTag = ipcChannel->subscribe<firebolt::rialto::NeedMediaDataEvent>(
141 244 : [this](const std::shared_ptr<firebolt::rialto::NeedMediaDataEvent> &event)
142 3 : { m_eventThread->add(&MediaPipelineIpc::onNeedMediaData, this, event); });
143 244 : if (eventTag < 0)
144 0 : return false;
145 244 : m_eventTags.push_back(eventTag);
146 :
147 488 : eventTag = ipcChannel->subscribe<firebolt::rialto::QosEvent>(
148 244 : [this](const std::shared_ptr<firebolt::rialto::QosEvent> &event)
149 2 : { m_eventThread->add(&MediaPipelineIpc::onQos, this, event); });
150 244 : if (eventTag < 0)
151 0 : return false;
152 244 : m_eventTags.push_back(eventTag);
153 :
154 488 : eventTag = ipcChannel->subscribe<firebolt::rialto::BufferUnderflowEvent>(
155 244 : [this](const std::shared_ptr<firebolt::rialto::BufferUnderflowEvent> &event)
156 0 : { m_eventThread->add(&MediaPipelineIpc::onBufferUnderflow, this, event); });
157 244 : if (eventTag < 0)
158 0 : return false;
159 244 : m_eventTags.push_back(eventTag);
160 :
161 488 : eventTag = ipcChannel->subscribe<firebolt::rialto::PlaybackErrorEvent>(
162 244 : [this](const std::shared_ptr<firebolt::rialto::PlaybackErrorEvent> &event)
163 2 : { m_eventThread->add(&MediaPipelineIpc::onPlaybackError, this, event); });
164 244 : if (eventTag < 0)
165 0 : return false;
166 244 : m_eventTags.push_back(eventTag);
167 :
168 488 : eventTag = ipcChannel->subscribe<firebolt::rialto::SourceFlushedEvent>(
169 244 : [this](const std::shared_ptr<firebolt::rialto::SourceFlushedEvent> &event)
170 2 : { m_eventThread->add(&MediaPipelineIpc::onSourceFlushed, this, event); });
171 244 : if (eventTag < 0)
172 0 : return false;
173 244 : m_eventTags.push_back(eventTag);
174 :
175 244 : 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 3 : bool MediaPipelineIpc::setSubtitleOffset(int32_t sourceId, int64_t position)
1141 : {
1142 3 : if (!reattachChannelIfRequired())
1143 : {
1144 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1145 1 : return false;
1146 : }
1147 :
1148 2 : firebolt::rialto::SetSubtitleOffsetRequest request;
1149 :
1150 2 : request.set_session_id(m_sessionId);
1151 2 : request.set_source_id(sourceId);
1152 2 : request.set_position(position);
1153 :
1154 2 : firebolt::rialto::SetSubtitleOffsetResponse response;
1155 2 : auto ipcController = m_ipc.createRpcController();
1156 2 : auto blockingClosure = m_ipc.createBlockingClosure();
1157 2 : m_mediaPipelineStub->setSubtitleOffset(ipcController.get(), &request, &response, blockingClosure.get());
1158 :
1159 : // wait for the call to complete
1160 2 : blockingClosure->wait();
1161 :
1162 : // check the result
1163 2 : if (ipcController->Failed())
1164 : {
1165 1 : RIALTO_CLIENT_LOG_ERROR("failed to set subtitle offset due to '%s'", ipcController->ErrorText().c_str());
1166 1 : return false;
1167 : }
1168 :
1169 1 : return true;
1170 2 : }
1171 :
1172 4 : bool MediaPipelineIpc::processAudioGap(int64_t position, uint32_t duration, int64_t discontinuityGap, bool audioAac)
1173 : {
1174 4 : if (!reattachChannelIfRequired())
1175 : {
1176 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1177 1 : return false;
1178 : }
1179 :
1180 3 : firebolt::rialto::ProcessAudioGapRequest request;
1181 :
1182 3 : request.set_session_id(m_sessionId);
1183 3 : request.set_position(position);
1184 3 : request.set_duration(duration);
1185 3 : request.set_discontinuity_gap(discontinuityGap);
1186 3 : request.set_audio_aac(audioAac);
1187 :
1188 3 : firebolt::rialto::ProcessAudioGapResponse response;
1189 3 : auto ipcController = m_ipc.createRpcController();
1190 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1191 3 : m_mediaPipelineStub->processAudioGap(ipcController.get(), &request, &response, blockingClosure.get());
1192 :
1193 : // wait for the call to complete
1194 3 : blockingClosure->wait();
1195 :
1196 : // check the result
1197 3 : if (ipcController->Failed())
1198 : {
1199 1 : RIALTO_CLIENT_LOG_ERROR("failed to process audio gap due to '%s'", ipcController->ErrorText().c_str());
1200 1 : return false;
1201 : }
1202 :
1203 2 : return true;
1204 3 : }
1205 :
1206 4 : bool MediaPipelineIpc::setBufferingLimit(uint32_t limitBufferingMs)
1207 : {
1208 4 : if (!reattachChannelIfRequired())
1209 : {
1210 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1211 1 : return false;
1212 : }
1213 :
1214 3 : firebolt::rialto::SetBufferingLimitRequest request;
1215 :
1216 3 : request.set_session_id(m_sessionId);
1217 3 : request.set_limit_buffering_ms(limitBufferingMs);
1218 :
1219 3 : firebolt::rialto::SetBufferingLimitResponse response;
1220 3 : auto ipcController = m_ipc.createRpcController();
1221 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1222 3 : m_mediaPipelineStub->setBufferingLimit(ipcController.get(), &request, &response, blockingClosure.get());
1223 :
1224 : // wait for the call to complete
1225 3 : blockingClosure->wait();
1226 :
1227 : // check the result
1228 3 : if (ipcController->Failed())
1229 : {
1230 1 : RIALTO_CLIENT_LOG_ERROR("failed to set buffering limit due to '%s'", ipcController->ErrorText().c_str());
1231 1 : return false;
1232 : }
1233 :
1234 2 : return true;
1235 3 : }
1236 :
1237 4 : bool MediaPipelineIpc::getBufferingLimit(uint32_t &limitBufferingMs)
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::GetBufferingLimitRequest request;
1246 :
1247 3 : request.set_session_id(m_sessionId);
1248 :
1249 3 : firebolt::rialto::GetBufferingLimitResponse response;
1250 3 : auto ipcController = m_ipc.createRpcController();
1251 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1252 3 : m_mediaPipelineStub->getBufferingLimit(ipcController.get(), &request, &response, blockingClosure.get());
1253 :
1254 : // wait for the call to complete
1255 3 : blockingClosure->wait();
1256 :
1257 : // check the result
1258 3 : if (ipcController->Failed())
1259 : {
1260 1 : RIALTO_CLIENT_LOG_ERROR("failed to get buffering limit due to '%s'", ipcController->ErrorText().c_str());
1261 1 : return false;
1262 : }
1263 :
1264 2 : limitBufferingMs = response.limit_buffering_ms();
1265 :
1266 2 : return true;
1267 3 : }
1268 :
1269 4 : bool MediaPipelineIpc::setUseBuffering(bool useBuffering)
1270 : {
1271 4 : if (!reattachChannelIfRequired())
1272 : {
1273 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1274 1 : return false;
1275 : }
1276 :
1277 3 : firebolt::rialto::SetUseBufferingRequest request;
1278 :
1279 3 : request.set_session_id(m_sessionId);
1280 3 : request.set_use_buffering(useBuffering);
1281 :
1282 3 : firebolt::rialto::SetUseBufferingResponse response;
1283 3 : auto ipcController = m_ipc.createRpcController();
1284 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1285 3 : m_mediaPipelineStub->setUseBuffering(ipcController.get(), &request, &response, blockingClosure.get());
1286 :
1287 : // wait for the call to complete
1288 3 : blockingClosure->wait();
1289 :
1290 : // check the result
1291 3 : if (ipcController->Failed())
1292 : {
1293 1 : RIALTO_CLIENT_LOG_ERROR("failed to set use buffering due to '%s'", ipcController->ErrorText().c_str());
1294 1 : return false;
1295 : }
1296 :
1297 2 : return true;
1298 3 : }
1299 :
1300 4 : bool MediaPipelineIpc::getUseBuffering(bool &useBuffering)
1301 : {
1302 4 : if (!reattachChannelIfRequired())
1303 : {
1304 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1305 1 : return false;
1306 : }
1307 :
1308 3 : firebolt::rialto::GetUseBufferingRequest request;
1309 :
1310 3 : request.set_session_id(m_sessionId);
1311 :
1312 3 : firebolt::rialto::GetUseBufferingResponse response;
1313 3 : auto ipcController = m_ipc.createRpcController();
1314 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1315 3 : m_mediaPipelineStub->getUseBuffering(ipcController.get(), &request, &response, blockingClosure.get());
1316 :
1317 : // wait for the call to complete
1318 3 : blockingClosure->wait();
1319 :
1320 : // check the result
1321 3 : if (ipcController->Failed())
1322 : {
1323 1 : RIALTO_CLIENT_LOG_ERROR("failed to get use buffering due to '%s'", ipcController->ErrorText().c_str());
1324 1 : return false;
1325 : }
1326 :
1327 2 : useBuffering = response.use_buffering();
1328 :
1329 2 : return true;
1330 3 : }
1331 :
1332 5 : bool MediaPipelineIpc::switchSource(const std::unique_ptr<IMediaPipeline::MediaSource> &source)
1333 : {
1334 5 : if (!reattachChannelIfRequired())
1335 : {
1336 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1337 1 : return false;
1338 : }
1339 :
1340 4 : firebolt::rialto::AttachSourceRequest request;
1341 :
1342 4 : request.set_session_id(m_sessionId);
1343 4 : request.set_switch_source(true);
1344 4 : if (!buildAttachSourceRequest(request, source))
1345 : {
1346 1 : RIALTO_CLIENT_LOG_ERROR("Failed to parse source");
1347 1 : return false;
1348 : }
1349 :
1350 3 : firebolt::rialto::AttachSourceResponse response;
1351 3 : auto ipcController = m_ipc.createRpcController();
1352 3 : auto blockingClosure = m_ipc.createBlockingClosure();
1353 3 : m_mediaPipelineStub->attachSource(ipcController.get(), &request, &response, blockingClosure.get());
1354 :
1355 : // wait for the call to complete
1356 3 : blockingClosure->wait();
1357 :
1358 : // check the result
1359 3 : if (ipcController->Failed())
1360 : {
1361 1 : RIALTO_CLIENT_LOG_ERROR("failed to attach source due to '%s'", ipcController->ErrorText().c_str());
1362 1 : return false;
1363 : }
1364 :
1365 2 : return true;
1366 4 : }
1367 :
1368 2 : void MediaPipelineIpc::onPlaybackStateUpdated(const std::shared_ptr<firebolt::rialto::PlaybackStateChangeEvent> &event)
1369 : {
1370 : /* Ignore event if not for this session */
1371 2 : if (event->session_id() == m_sessionId)
1372 : {
1373 1 : PlaybackState playbackState = PlaybackState::UNKNOWN;
1374 1 : switch (event->state())
1375 : {
1376 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_IDLE:
1377 0 : playbackState = PlaybackState::IDLE;
1378 0 : break;
1379 1 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_PLAYING:
1380 1 : playbackState = PlaybackState::PLAYING;
1381 1 : break;
1382 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_PAUSED:
1383 0 : playbackState = PlaybackState::PAUSED;
1384 0 : break;
1385 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_SEEKING:
1386 0 : playbackState = PlaybackState::SEEKING;
1387 0 : break;
1388 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_SEEK_DONE:
1389 0 : playbackState = PlaybackState::SEEK_DONE;
1390 0 : break;
1391 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_STOPPED:
1392 0 : playbackState = PlaybackState::STOPPED;
1393 0 : break;
1394 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_END_OF_STREAM:
1395 0 : playbackState = PlaybackState::END_OF_STREAM;
1396 0 : break;
1397 0 : case firebolt::rialto::PlaybackStateChangeEvent_PlaybackState_FAILURE:
1398 0 : playbackState = PlaybackState::FAILURE;
1399 0 : break;
1400 0 : default:
1401 0 : RIALTO_CLIENT_LOG_WARN("Received unknown playback state");
1402 0 : break;
1403 : }
1404 :
1405 1 : m_mediaPipelineIpcClient->notifyPlaybackState(playbackState);
1406 : }
1407 2 : }
1408 :
1409 0 : void MediaPipelineIpc::onPositionUpdated(const std::shared_ptr<firebolt::rialto::PositionChangeEvent> &event)
1410 : {
1411 : // Ignore event if not for this session
1412 0 : if (event->session_id() == m_sessionId)
1413 : {
1414 0 : int64_t position = event->position();
1415 0 : m_mediaPipelineIpcClient->notifyPosition(position);
1416 : }
1417 : }
1418 :
1419 2 : void MediaPipelineIpc::onNetworkStateUpdated(const std::shared_ptr<firebolt::rialto::NetworkStateChangeEvent> &event)
1420 : {
1421 : // Ignore event if not for this session
1422 2 : if (event->session_id() == m_sessionId)
1423 : {
1424 1 : NetworkState networkState = NetworkState::UNKNOWN;
1425 1 : switch (event->state())
1426 : {
1427 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_IDLE:
1428 0 : networkState = NetworkState::IDLE;
1429 0 : break;
1430 1 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERING:
1431 1 : networkState = NetworkState::BUFFERING;
1432 1 : break;
1433 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERING_PROGRESS:
1434 0 : networkState = NetworkState::BUFFERING_PROGRESS;
1435 0 : break;
1436 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_BUFFERED:
1437 0 : networkState = NetworkState::BUFFERED;
1438 0 : break;
1439 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_STALLED:
1440 0 : networkState = NetworkState::STALLED;
1441 0 : break;
1442 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_FORMAT_ERROR:
1443 0 : networkState = NetworkState::FORMAT_ERROR;
1444 0 : break;
1445 0 : case firebolt::rialto::NetworkStateChangeEvent_NetworkState_NETWORK_ERROR:
1446 0 : networkState = NetworkState::NETWORK_ERROR;
1447 0 : break;
1448 0 : default:
1449 0 : RIALTO_CLIENT_LOG_WARN("Received unknown network state");
1450 0 : break;
1451 : }
1452 :
1453 1 : m_mediaPipelineIpcClient->notifyNetworkState(networkState);
1454 : }
1455 2 : }
1456 :
1457 3 : void MediaPipelineIpc::onNeedMediaData(const std::shared_ptr<firebolt::rialto::NeedMediaDataEvent> &event)
1458 : {
1459 : // Ignore event if not for this session
1460 3 : if (event->session_id() == m_sessionId)
1461 : {
1462 2 : std::shared_ptr<MediaPlayerShmInfo> shmInfo;
1463 2 : if (event->has_shm_info())
1464 : {
1465 1 : shmInfo = std::make_shared<MediaPlayerShmInfo>();
1466 1 : shmInfo->maxMetadataBytes = event->shm_info().max_metadata_bytes();
1467 1 : shmInfo->metadataOffset = event->shm_info().metadata_offset();
1468 1 : shmInfo->mediaDataOffset = event->shm_info().media_data_offset();
1469 1 : shmInfo->maxMediaBytes = event->shm_info().max_media_bytes();
1470 : }
1471 2 : m_mediaPipelineIpcClient->notifyNeedMediaData(event->source_id(), event->frame_count(), event->request_id(),
1472 : shmInfo);
1473 : }
1474 3 : }
1475 :
1476 2 : void MediaPipelineIpc::onQos(const std::shared_ptr<firebolt::rialto::QosEvent> &event)
1477 : {
1478 : // Ignore event if not for this session
1479 2 : if (event->session_id() == m_sessionId)
1480 : {
1481 1 : QosInfo qosInfo = {event->qos_info().processed(), event->qos_info().dropped()};
1482 1 : m_mediaPipelineIpcClient->notifyQos(event->source_id(), qosInfo);
1483 : }
1484 2 : }
1485 :
1486 0 : void MediaPipelineIpc::onBufferUnderflow(const std::shared_ptr<firebolt::rialto::BufferUnderflowEvent> &event)
1487 : {
1488 : // Ignore event if not for this session
1489 0 : if (event->session_id() == m_sessionId)
1490 : {
1491 0 : m_mediaPipelineIpcClient->notifyBufferUnderflow(event->source_id());
1492 : }
1493 : }
1494 :
1495 2 : void MediaPipelineIpc::onPlaybackError(const std::shared_ptr<firebolt::rialto::PlaybackErrorEvent> &event)
1496 : {
1497 : // Ignore event if not for this session
1498 2 : if (event->session_id() == m_sessionId)
1499 : {
1500 1 : PlaybackError playbackError = PlaybackError::UNKNOWN;
1501 1 : switch (event->error())
1502 : {
1503 1 : case firebolt::rialto::PlaybackErrorEvent_PlaybackError_DECRYPTION:
1504 1 : playbackError = PlaybackError::DECRYPTION;
1505 1 : break;
1506 0 : default:
1507 0 : RIALTO_CLIENT_LOG_WARN("Received unknown playback error");
1508 0 : break;
1509 : }
1510 :
1511 1 : m_mediaPipelineIpcClient->notifyPlaybackError(event->source_id(), playbackError);
1512 : }
1513 2 : }
1514 :
1515 2 : void MediaPipelineIpc::onSourceFlushed(const std::shared_ptr<firebolt::rialto::SourceFlushedEvent> &event)
1516 : {
1517 : // Ignore event if not for this session
1518 2 : if (event->session_id() == m_sessionId)
1519 : {
1520 1 : m_mediaPipelineIpcClient->notifySourceFlushed(event->source_id());
1521 : }
1522 2 : }
1523 :
1524 173 : bool MediaPipelineIpc::createSession(const VideoRequirements &videoRequirements)
1525 : {
1526 173 : if (!reattachChannelIfRequired())
1527 : {
1528 0 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1529 0 : return false;
1530 : }
1531 :
1532 173 : firebolt::rialto::CreateSessionRequest request;
1533 :
1534 173 : request.set_max_width(videoRequirements.maxWidth);
1535 173 : request.set_max_height(videoRequirements.maxHeight);
1536 :
1537 173 : firebolt::rialto::CreateSessionResponse response;
1538 173 : auto ipcController = m_ipc.createRpcController();
1539 173 : auto blockingClosure = m_ipc.createBlockingClosure();
1540 173 : m_mediaPipelineStub->createSession(ipcController.get(), &request, &response, blockingClosure.get());
1541 :
1542 : // wait for the call to complete
1543 173 : blockingClosure->wait();
1544 :
1545 : // check the result
1546 173 : if (ipcController->Failed())
1547 : {
1548 1 : RIALTO_CLIENT_LOG_ERROR("failed to create session due to '%s'", ipcController->ErrorText().c_str());
1549 1 : return false;
1550 : }
1551 :
1552 172 : m_sessionId = response.session_id();
1553 :
1554 172 : return true;
1555 173 : }
1556 :
1557 172 : void MediaPipelineIpc::destroySession()
1558 : {
1559 172 : if (!reattachChannelIfRequired())
1560 : {
1561 1 : RIALTO_CLIENT_LOG_ERROR("Reattachment of the ipc channel failed, ipc disconnected");
1562 1 : return;
1563 : }
1564 :
1565 171 : firebolt::rialto::DestroySessionRequest request;
1566 171 : request.set_session_id(m_sessionId);
1567 :
1568 171 : firebolt::rialto::DestroySessionResponse response;
1569 171 : auto ipcController = m_ipc.createRpcController();
1570 171 : auto blockingClosure = m_ipc.createBlockingClosure();
1571 171 : m_mediaPipelineStub->destroySession(ipcController.get(), &request, &response, blockingClosure.get());
1572 :
1573 : // wait for the call to complete
1574 171 : blockingClosure->wait();
1575 :
1576 : // check the result
1577 171 : if (ipcController->Failed())
1578 : {
1579 1 : RIALTO_CLIENT_LOG_ERROR("failed to destroy session due to '%s'", ipcController->ErrorText().c_str());
1580 : }
1581 171 : }
1582 :
1583 3 : firebolt::rialto::LoadRequest_MediaType MediaPipelineIpc::convertLoadRequestMediaType(MediaType mediaType) const
1584 : {
1585 3 : firebolt::rialto::LoadRequest_MediaType protoMediaType = firebolt::rialto::LoadRequest_MediaType_UNKNOWN;
1586 3 : switch (mediaType)
1587 : {
1588 3 : case MediaType::MSE:
1589 3 : protoMediaType = firebolt::rialto::LoadRequest_MediaType_MSE;
1590 3 : break;
1591 0 : default:
1592 0 : break;
1593 : }
1594 :
1595 3 : return protoMediaType;
1596 : }
1597 :
1598 : firebolt::rialto::HaveDataRequest_MediaSourceStatus
1599 3 : MediaPipelineIpc::convertHaveDataRequestMediaSourceStatus(MediaSourceStatus status) const
1600 : {
1601 3 : firebolt::rialto::HaveDataRequest_MediaSourceStatus protoMediaSourceStatus =
1602 : firebolt::rialto::HaveDataRequest_MediaSourceStatus_UNKNOWN;
1603 3 : switch (status)
1604 : {
1605 3 : case MediaSourceStatus::OK:
1606 3 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_OK;
1607 3 : break;
1608 0 : case MediaSourceStatus::EOS:
1609 0 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_EOS;
1610 0 : break;
1611 0 : case MediaSourceStatus::ERROR:
1612 0 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_ERROR;
1613 0 : break;
1614 0 : case MediaSourceStatus::CODEC_CHANGED:
1615 0 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_CODEC_CHANGED;
1616 0 : break;
1617 0 : case MediaSourceStatus::NO_AVAILABLE_SAMPLES:
1618 0 : protoMediaSourceStatus = firebolt::rialto::HaveDataRequest_MediaSourceStatus_NO_AVAILABLE_SAMPLES;
1619 0 : break;
1620 0 : default:
1621 0 : break;
1622 : }
1623 :
1624 3 : return protoMediaSourceStatus;
1625 : }
1626 :
1627 : firebolt::rialto::AttachSourceRequest_ConfigType
1628 17 : MediaPipelineIpc::convertConfigType(const firebolt::rialto::SourceConfigType &configType) const
1629 : {
1630 17 : switch (configType)
1631 : {
1632 0 : case firebolt::rialto::SourceConfigType::UNKNOWN:
1633 : {
1634 0 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_UNKNOWN;
1635 : }
1636 9 : case firebolt::rialto::SourceConfigType::AUDIO:
1637 : {
1638 9 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_AUDIO;
1639 : }
1640 3 : case firebolt::rialto::SourceConfigType::VIDEO:
1641 : {
1642 3 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_VIDEO;
1643 : }
1644 3 : case firebolt::rialto::SourceConfigType::VIDEO_DOLBY_VISION:
1645 : {
1646 3 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_VIDEO_DOLBY_VISION;
1647 : }
1648 2 : case firebolt::rialto::SourceConfigType::SUBTITLE:
1649 : {
1650 2 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_SUBTITLE;
1651 : }
1652 : }
1653 0 : return firebolt::rialto::AttachSourceRequest_ConfigType_CONFIG_TYPE_UNKNOWN;
1654 : }
1655 :
1656 3 : firebolt::rialto::SetVolumeRequest_EaseType MediaPipelineIpc::convertEaseType(const firebolt::rialto::EaseType &easeType) const
1657 : {
1658 3 : switch (easeType)
1659 : {
1660 3 : case firebolt::rialto::EaseType::EASE_LINEAR:
1661 : {
1662 3 : return firebolt::rialto::SetVolumeRequest_EaseType_EASE_LINEAR;
1663 : }
1664 0 : case firebolt::rialto::EaseType::EASE_IN_CUBIC:
1665 : {
1666 0 : return firebolt::rialto::SetVolumeRequest_EaseType_EASE_IN_CUBIC;
1667 : }
1668 0 : case firebolt::rialto::EaseType::EASE_OUT_CUBIC:
1669 : {
1670 0 : return firebolt::rialto::SetVolumeRequest_EaseType_EASE_OUT_CUBIC;
1671 : }
1672 : }
1673 0 : return firebolt::rialto::SetVolumeRequest_EaseType_EASE_LINEAR;
1674 : }
1675 :
1676 : firebolt::rialto::AttachSourceRequest_SegmentAlignment
1677 14 : MediaPipelineIpc::convertSegmentAlignment(const firebolt::rialto::SegmentAlignment &alignment) const
1678 : {
1679 14 : switch (alignment)
1680 : {
1681 14 : case firebolt::rialto::SegmentAlignment::UNDEFINED:
1682 : {
1683 14 : return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_UNDEFINED;
1684 : }
1685 0 : case firebolt::rialto::SegmentAlignment::NAL:
1686 : {
1687 0 : return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_NAL;
1688 : }
1689 0 : case firebolt::rialto::SegmentAlignment::AU:
1690 : {
1691 0 : return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_AU;
1692 : }
1693 : }
1694 0 : return firebolt::rialto::AttachSourceRequest_SegmentAlignment_ALIGNMENT_UNDEFINED;
1695 : }
1696 :
1697 : firebolt::rialto::AttachSourceRequest_StreamFormat
1698 14 : MediaPipelineIpc::convertStreamFormat(const firebolt::rialto::StreamFormat &streamFormat) const
1699 : {
1700 14 : switch (streamFormat)
1701 : {
1702 8 : case firebolt::rialto::StreamFormat::UNDEFINED:
1703 : {
1704 8 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_UNDEFINED;
1705 : }
1706 6 : case firebolt::rialto::StreamFormat::RAW:
1707 : {
1708 6 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_RAW;
1709 : }
1710 0 : case firebolt::rialto::StreamFormat::AVC:
1711 : {
1712 0 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_AVC;
1713 : }
1714 0 : case firebolt::rialto::StreamFormat::BYTE_STREAM:
1715 : {
1716 0 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_BYTE_STREAM;
1717 : }
1718 0 : case firebolt::rialto::StreamFormat::HVC1:
1719 : {
1720 0 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_HVC1;
1721 : }
1722 0 : case firebolt::rialto::StreamFormat::HEV1:
1723 : {
1724 0 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_HEV1;
1725 : }
1726 : }
1727 0 : return firebolt::rialto::AttachSourceRequest_StreamFormat_STREAM_FORMAT_UNDEFINED;
1728 : }
1729 :
1730 : firebolt::rialto::AttachSourceRequest_CodecData_Type
1731 3 : MediaPipelineIpc::convertCodecDataType(const firebolt::rialto::CodecDataType &codecDataType) const
1732 : {
1733 3 : if (firebolt::rialto::CodecDataType::STRING == codecDataType)
1734 : {
1735 0 : return firebolt::rialto::AttachSourceRequest_CodecData_Type_STRING;
1736 : }
1737 3 : return firebolt::rialto::AttachSourceRequest_CodecData_Type_BUFFER;
1738 : }
1739 :
1740 : firebolt::rialto::AttachSourceRequest_AudioConfig_Format
1741 0 : MediaPipelineIpc::convertFormat(const firebolt::rialto::Format &format) const
1742 : {
1743 : static const std::unordered_map<firebolt::rialto::Format, firebolt::rialto::AttachSourceRequest_AudioConfig_Format>
1744 : kFormatConversionMap{
1745 : {firebolt::rialto::Format::S8, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S8},
1746 : {firebolt::rialto::Format::U8, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U8},
1747 : {firebolt::rialto::Format::S16LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S16LE},
1748 : {firebolt::rialto::Format::S16BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S16BE},
1749 : {firebolt::rialto::Format::U16LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U16LE},
1750 : {firebolt::rialto::Format::U16BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U16BE},
1751 : {firebolt::rialto::Format::S24_32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24_32LE},
1752 : {firebolt::rialto::Format::S24_32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24_32BE},
1753 : {firebolt::rialto::Format::U24_32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24_32LE},
1754 : {firebolt::rialto::Format::U24_32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24_32BE},
1755 : {firebolt::rialto::Format::S32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S32LE},
1756 : {firebolt::rialto::Format::S32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S32BE},
1757 : {firebolt::rialto::Format::U32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U32LE},
1758 : {firebolt::rialto::Format::U32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U32BE},
1759 : {firebolt::rialto::Format::S24LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24LE},
1760 : {firebolt::rialto::Format::S24BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S24BE},
1761 : {firebolt::rialto::Format::U24LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24LE},
1762 : {firebolt::rialto::Format::U24BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U24BE},
1763 : {firebolt::rialto::Format::S20LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S20LE},
1764 : {firebolt::rialto::Format::S20BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S20BE},
1765 : {firebolt::rialto::Format::U20LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U20LE},
1766 : {firebolt::rialto::Format::U20BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U20BE},
1767 : {firebolt::rialto::Format::S18LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S18LE},
1768 : {firebolt::rialto::Format::S18BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S18BE},
1769 : {firebolt::rialto::Format::U18LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U18LE},
1770 : {firebolt::rialto::Format::U18BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_U18BE},
1771 : {firebolt::rialto::Format::F32LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F32LE},
1772 : {firebolt::rialto::Format::F32BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F32BE},
1773 : {firebolt::rialto::Format::F64LE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F64LE},
1774 0 : {firebolt::rialto::Format::F64BE, firebolt::rialto::AttachSourceRequest_AudioConfig_Format_F64BE}};
1775 0 : const auto kIt = kFormatConversionMap.find(format);
1776 0 : if (kFormatConversionMap.end() != kIt)
1777 : {
1778 0 : return kIt->second;
1779 : }
1780 0 : return firebolt::rialto::AttachSourceRequest_AudioConfig_Format_S8;
1781 : }
1782 :
1783 : firebolt::rialto::AttachSourceRequest_AudioConfig_Layout
1784 0 : MediaPipelineIpc::convertLayout(const firebolt::rialto::Layout &layout) const
1785 : {
1786 : static const std::unordered_map<firebolt::rialto::Layout, firebolt::rialto::AttachSourceRequest_AudioConfig_Layout>
1787 : kLayoutConversionMap{{firebolt::rialto::Layout::INTERLEAVED,
1788 : firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_INTERLEAVED},
1789 : {firebolt::rialto::Layout::NON_INTERLEAVED,
1790 0 : firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_NON_INTERLEAVED}};
1791 0 : const auto kIt = kLayoutConversionMap.find(layout);
1792 0 : if (kLayoutConversionMap.end() != kIt)
1793 : {
1794 0 : return kIt->second;
1795 : }
1796 0 : return firebolt::rialto::AttachSourceRequest_AudioConfig_Layout_INTERLEAVED;
1797 : }
1798 :
1799 17 : bool MediaPipelineIpc::buildAttachSourceRequest(firebolt::rialto::AttachSourceRequest &request,
1800 : const std::unique_ptr<IMediaPipeline::MediaSource> &source) const
1801 : {
1802 17 : SourceConfigType configType = source->getConfigType();
1803 17 : request.set_config_type(convertConfigType(configType));
1804 34 : request.set_mime_type(source->getMimeType());
1805 17 : request.set_has_drm(source->getHasDrm());
1806 :
1807 17 : if (configType == SourceConfigType::VIDEO_DOLBY_VISION || configType == SourceConfigType::VIDEO ||
1808 11 : configType == SourceConfigType::AUDIO)
1809 : {
1810 15 : IMediaPipeline::MediaSourceAV *mediaSourceAV = dynamic_cast<IMediaPipeline::MediaSourceAV *>(source.get());
1811 15 : if (!mediaSourceAV)
1812 : {
1813 1 : RIALTO_CLIENT_LOG_ERROR("Failed to get the audio video source");
1814 1 : return false;
1815 : }
1816 14 : request.set_segment_alignment(convertSegmentAlignment(mediaSourceAV->getSegmentAlignment()));
1817 :
1818 14 : if (mediaSourceAV->getCodecData())
1819 : {
1820 6 : request.mutable_codec_data()->set_data(mediaSourceAV->getCodecData()->data.data(),
1821 3 : mediaSourceAV->getCodecData()->data.size());
1822 3 : request.mutable_codec_data()->set_type(convertCodecDataType(mediaSourceAV->getCodecData()->type));
1823 : }
1824 14 : request.set_stream_format(convertStreamFormat(mediaSourceAV->getStreamFormat()));
1825 :
1826 14 : if (configType == SourceConfigType::VIDEO_DOLBY_VISION)
1827 : {
1828 : IMediaPipeline::MediaSourceVideoDolbyVision *mediaSourceDolby =
1829 2 : dynamic_cast<IMediaPipeline::MediaSourceVideoDolbyVision *>(source.get());
1830 2 : if (!mediaSourceDolby)
1831 : {
1832 1 : RIALTO_CLIENT_LOG_ERROR("Failed to get the video dolby vision media source");
1833 1 : return false;
1834 : }
1835 1 : request.set_width(mediaSourceDolby->getWidth());
1836 1 : request.set_height(mediaSourceDolby->getHeight());
1837 1 : request.set_dolby_vision_profile(mediaSourceDolby->getDolbyVisionProfile());
1838 : }
1839 12 : else if (configType == SourceConfigType::VIDEO)
1840 : {
1841 : IMediaPipeline::MediaSourceVideo *mediaSourceVideo =
1842 3 : dynamic_cast<IMediaPipeline::MediaSourceVideo *>(source.get());
1843 3 : if (!mediaSourceVideo)
1844 : {
1845 1 : RIALTO_CLIENT_LOG_ERROR("Failed to get the video media source");
1846 1 : return false;
1847 : }
1848 2 : request.set_width(mediaSourceVideo->getWidth());
1849 2 : request.set_height(mediaSourceVideo->getHeight());
1850 : }
1851 9 : else if (configType == SourceConfigType::AUDIO)
1852 : {
1853 : IMediaPipeline::MediaSourceAudio *mediaSourceAudio =
1854 9 : dynamic_cast<IMediaPipeline::MediaSourceAudio *>(source.get());
1855 9 : if (!mediaSourceAudio)
1856 : {
1857 2 : RIALTO_CLIENT_LOG_ERROR("Failed to get the audio media source");
1858 2 : return false;
1859 : }
1860 7 : request.mutable_audio_config()->set_number_of_channels(mediaSourceAudio->getAudioConfig().numberOfChannels);
1861 7 : request.mutable_audio_config()->set_sample_rate(mediaSourceAudio->getAudioConfig().sampleRate);
1862 7 : if (!mediaSourceAudio->getAudioConfig().codecSpecificConfig.empty())
1863 : {
1864 : request.mutable_audio_config()
1865 9 : ->set_codec_specific_config(mediaSourceAudio->getAudioConfig().codecSpecificConfig.data(),
1866 3 : mediaSourceAudio->getAudioConfig().codecSpecificConfig.size());
1867 : }
1868 7 : if (mediaSourceAudio->getAudioConfig().format.has_value())
1869 : {
1870 0 : request.mutable_audio_config()->set_format(
1871 0 : convertFormat(mediaSourceAudio->getAudioConfig().format.value()));
1872 : }
1873 7 : if (mediaSourceAudio->getAudioConfig().layout.has_value())
1874 : {
1875 0 : request.mutable_audio_config()->set_layout(
1876 0 : convertLayout(mediaSourceAudio->getAudioConfig().layout.value()));
1877 : }
1878 7 : if (mediaSourceAudio->getAudioConfig().channelMask.has_value())
1879 : {
1880 0 : request.mutable_audio_config()->set_channel_mask(mediaSourceAudio->getAudioConfig().channelMask.value());
1881 : }
1882 7 : for (auto &header : mediaSourceAudio->getAudioConfig().streamHeader)
1883 : {
1884 0 : request.mutable_audio_config()->add_stream_header(header.data(), header.size());
1885 : }
1886 7 : if (mediaSourceAudio->getAudioConfig().framed.has_value())
1887 : {
1888 0 : request.mutable_audio_config()->set_framed(mediaSourceAudio->getAudioConfig().framed.value());
1889 : }
1890 : }
1891 10 : }
1892 2 : else if (configType == SourceConfigType::SUBTITLE)
1893 : {
1894 : IMediaPipeline::MediaSourceSubtitle *mediaSourceSubtitle =
1895 2 : dynamic_cast<IMediaPipeline::MediaSourceSubtitle *>(source.get());
1896 2 : if (!mediaSourceSubtitle)
1897 : {
1898 1 : RIALTO_CLIENT_LOG_ERROR("Failed to get the subtitle source");
1899 1 : return false;
1900 : }
1901 1 : request.set_text_track_identifier(mediaSourceSubtitle->getTextTrackIdentifier());
1902 : }
1903 : else
1904 : {
1905 0 : RIALTO_CLIENT_LOG_ERROR("Unknown source type");
1906 0 : return false;
1907 : }
1908 11 : return true;
1909 : }
1910 : }; // namespace firebolt::rialto::client
|