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 :
20 : #include "MediaPipelineService.h"
21 : #include "IGstCapabilities.h"
22 : #include "IMediaCapabilitiesServerInternal.h"
23 : #include "IMediaPipelineServerInternal.h"
24 : #include "MediaPipelineMetricsClient.h"
25 : #include "RialtoServerLogging.h"
26 : #include <exception>
27 : #include <future>
28 : #include <string>
29 : #include <utility>
30 : #include <vector>
31 :
32 : namespace firebolt::rialto::server::service
33 : {
34 139 : MediaPipelineService::MediaPipelineService(
35 : IPlaybackService &playbackService, std::shared_ptr<IMediaPipelineServerInternalFactory> &&mediaPipelineFactory,
36 : std::shared_ptr<IMediaPipelineCapabilitiesFactory> &&mediaPipelineCapabilitiesFactory,
37 : IDecryptionService &decryptionService, IPrivateMetricsService &metricsService,
38 139 : std::shared_ptr<firebolt::rialto::server::IMediaCapabilitiesServerInternalFactory> &&mediaCapabilitiesFactory)
39 139 : : m_playbackService{playbackService}, m_mediaPipelineFactory{std::move(mediaPipelineFactory)},
40 139 : m_mediaPipelineCapabilities{mediaPipelineCapabilitiesFactory->createMediaPipelineCapabilities()},
41 139 : m_mediaCapabilities{mediaCapabilitiesFactory ? mediaCapabilitiesFactory->createMediaCapabilitiesServerInternal()
42 : : nullptr},
43 278 : m_decryptionService{decryptionService}, m_metricsService{metricsService}
44 : {
45 139 : if (!m_mediaPipelineCapabilities)
46 : {
47 1 : throw std::runtime_error("Could not create Media Pipeline Capabilities");
48 : }
49 :
50 138 : RIALTO_SERVER_LOG_DEBUG("MediaPipelineService is constructed");
51 143 : }
52 :
53 276 : MediaPipelineService::~MediaPipelineService()
54 : {
55 138 : RIALTO_SERVER_LOG_DEBUG("MediaPipelineService is destructed");
56 276 : }
57 :
58 1 : void MediaPipelineService::clearMediaPipelines()
59 : {
60 1 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
61 1 : m_mediaPipelines.clear();
62 : }
63 :
64 89 : bool MediaPipelineService::createSession(int sessionId, const std::shared_ptr<IMediaPipelineClient> &mediaPipelineClient,
65 : std::uint32_t maxWidth, std::uint32_t maxHeight)
66 : {
67 89 : RIALTO_SERVER_LOG_DEBUG("MediaPipelineService requested to create new session with id: %d", sessionId);
68 89 : if (!m_playbackService.isActive())
69 : {
70 1 : RIALTO_SERVER_LOG_ERROR("Skip to create session with id: %d - Session Server in Inactive state", sessionId);
71 1 : return false;
72 : }
73 :
74 : {
75 88 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
76 88 : if (m_mediaPipelines.size() == static_cast<size_t>(m_playbackService.getMaxPlaybacks()))
77 : {
78 1 : RIALTO_SERVER_LOG_ERROR("Unable to create a session with id: %d. Max session number reached.", sessionId);
79 1 : return false;
80 : }
81 87 : if (m_mediaPipelines.find(sessionId) != m_mediaPipelines.end())
82 : {
83 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d already exists", sessionId);
84 1 : return false;
85 : }
86 86 : auto shmBuffer = m_playbackService.getShmBuffer();
87 86 : m_mediaPipelines.emplace(
88 172 : std::make_pair(sessionId,
89 86 : m_mediaPipelineFactory
90 258 : ->createMediaPipelineServerInternal(std::make_shared<
91 86 : MediaPipelineMetricsClient>(sessionId,
92 : mediaPipelineClient,
93 : m_metricsService),
94 86 : VideoRequirements{maxWidth, maxHeight}, sessionId,
95 : shmBuffer, m_decryptionService)));
96 86 : if (!m_mediaPipelines.at(sessionId))
97 : {
98 1 : RIALTO_SERVER_LOG_ERROR("Could not create MediaPipeline for session with id: %d", sessionId);
99 1 : m_mediaPipelines.erase(sessionId);
100 1 : return false;
101 : }
102 89 : }
103 :
104 85 : RIALTO_SERVER_LOG_INFO("New session with id: %d created", sessionId);
105 85 : return true;
106 : }
107 :
108 3 : bool MediaPipelineService::destroySession(int sessionId)
109 : {
110 3 : RIALTO_SERVER_LOG_DEBUG("MediaPipelineService requested to destroy session with id: %d", sessionId);
111 : {
112 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
113 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
114 3 : if (mediaPipelineIter == m_mediaPipelines.end())
115 : {
116 2 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
117 2 : return false;
118 : }
119 1 : m_mediaPipelines.erase(mediaPipelineIter);
120 3 : }
121 1 : RIALTO_SERVER_LOG_INFO("Session with id: %d destroyed", sessionId);
122 1 : return true;
123 : }
124 :
125 3 : bool MediaPipelineService::load(int sessionId, MediaType type, const std::string &mimeType, const std::string &url,
126 : bool isLive)
127 : {
128 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to load session with id: %d", sessionId);
129 :
130 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
131 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
132 3 : if (mediaPipelineIter == m_mediaPipelines.end())
133 : {
134 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
135 1 : return false;
136 : }
137 2 : return mediaPipelineIter->second->load(type, mimeType, url, isLive);
138 3 : }
139 :
140 3 : bool MediaPipelineService::attachSource(int sessionId, const std::unique_ptr<IMediaPipeline::MediaSource> &source)
141 : {
142 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to attach source, session id: %d", sessionId);
143 :
144 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
145 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
146 3 : if (mediaPipelineIter == m_mediaPipelines.end())
147 : {
148 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
149 1 : return false;
150 : }
151 2 : return mediaPipelineIter->second->attachSource(source);
152 3 : }
153 :
154 3 : bool MediaPipelineService::removeSource(int sessionId, std::int32_t sourceId)
155 : {
156 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to remove source, session id: %d", sessionId);
157 :
158 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
159 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
160 3 : if (mediaPipelineIter == m_mediaPipelines.end())
161 : {
162 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
163 1 : return false;
164 : }
165 2 : return mediaPipelineIter->second->removeSource(sourceId);
166 3 : }
167 :
168 3 : bool MediaPipelineService::allSourcesAttached(int sessionId)
169 : {
170 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService notified that all sources were attached, session id: %d", sessionId);
171 :
172 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
173 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
174 3 : if (mediaPipelineIter == m_mediaPipelines.end())
175 : {
176 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
177 1 : return false;
178 : }
179 2 : return mediaPipelineIter->second->allSourcesAttached();
180 3 : }
181 :
182 3 : bool MediaPipelineService::play(int sessionId, bool &async)
183 : {
184 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to play, session id: %d", sessionId);
185 :
186 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
187 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
188 3 : if (mediaPipelineIter == m_mediaPipelines.end())
189 : {
190 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
191 1 : return false;
192 : }
193 2 : return mediaPipelineIter->second->play(async);
194 3 : }
195 :
196 3 : bool MediaPipelineService::pause(int sessionId)
197 : {
198 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to pause, session id: %d", sessionId);
199 :
200 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
201 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
202 3 : if (mediaPipelineIter == m_mediaPipelines.end())
203 : {
204 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
205 1 : return false;
206 : }
207 2 : return mediaPipelineIter->second->pause();
208 3 : }
209 :
210 3 : bool MediaPipelineService::stop(int sessionId)
211 : {
212 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to stop, session id: %d", sessionId);
213 :
214 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
215 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
216 3 : if (mediaPipelineIter == m_mediaPipelines.end())
217 : {
218 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
219 1 : return false;
220 : }
221 2 : return mediaPipelineIter->second->stop();
222 3 : }
223 :
224 3 : bool MediaPipelineService::setPlaybackRate(int sessionId, double rate)
225 : {
226 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to set playback rate, session id: %d", sessionId);
227 :
228 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
229 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
230 3 : if (mediaPipelineIter == m_mediaPipelines.end())
231 : {
232 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
233 1 : return false;
234 : }
235 2 : return mediaPipelineIter->second->setPlaybackRate(rate);
236 3 : }
237 :
238 3 : bool MediaPipelineService::setPosition(int sessionId, std::int64_t position)
239 : {
240 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to set position, session id: %d", sessionId);
241 :
242 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
243 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
244 3 : if (mediaPipelineIter == m_mediaPipelines.end())
245 : {
246 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
247 1 : return false;
248 : }
249 2 : return mediaPipelineIter->second->setPosition(position);
250 3 : }
251 :
252 3 : bool MediaPipelineService::getPosition(int sessionId, std::int64_t &position)
253 : {
254 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to get position, session id: %d", sessionId);
255 :
256 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
257 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
258 3 : if (mediaPipelineIter == m_mediaPipelines.end())
259 : {
260 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
261 1 : return false;
262 : }
263 2 : return mediaPipelineIter->second->getPosition(position);
264 3 : }
265 :
266 3 : bool MediaPipelineService::getDuration(int sessionId, std::int64_t &duration)
267 : {
268 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to get duration, session id: %d", sessionId);
269 :
270 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
271 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
272 3 : if (mediaPipelineIter == m_mediaPipelines.end())
273 : {
274 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
275 1 : return false;
276 : }
277 2 : return mediaPipelineIter->second->getDuration(duration);
278 3 : }
279 :
280 3 : bool MediaPipelineService::setImmediateOutput(int sessionId, int32_t sourceId, bool immediateOutput)
281 : {
282 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to setImmediateOutput, session id: %d", sessionId);
283 :
284 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
285 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
286 3 : if (mediaPipelineIter == m_mediaPipelines.end())
287 : {
288 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
289 1 : return false;
290 : }
291 2 : return mediaPipelineIter->second->setImmediateOutput(sourceId, immediateOutput);
292 3 : }
293 :
294 3 : bool MediaPipelineService::setReportDecodeErrors(int sessionId, int32_t sourceId, bool reportDecodeErrors)
295 : {
296 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to setReportDecodeErrors, session id: %d", sessionId);
297 :
298 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
299 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
300 3 : if (mediaPipelineIter == m_mediaPipelines.end())
301 : {
302 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
303 1 : return false;
304 : }
305 2 : return mediaPipelineIter->second->setReportDecodeErrors(sourceId, reportDecodeErrors);
306 3 : }
307 :
308 3 : bool MediaPipelineService::getQueuedFrames(int sessionId, int32_t sourceId, uint32_t &queuedFrames)
309 : {
310 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to getQueuedFrames, session id: %d", sessionId);
311 :
312 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
313 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
314 3 : if (mediaPipelineIter == m_mediaPipelines.end())
315 : {
316 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
317 1 : return false;
318 : }
319 2 : return mediaPipelineIter->second->getQueuedFrames(sourceId, queuedFrames);
320 3 : }
321 :
322 3 : bool MediaPipelineService::getImmediateOutput(int sessionId, int32_t sourceId, bool &immediateOutput)
323 : {
324 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to getImmediateOutput, session id: %d", sessionId);
325 :
326 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
327 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
328 3 : if (mediaPipelineIter == m_mediaPipelines.end())
329 : {
330 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
331 1 : return false;
332 : }
333 2 : return mediaPipelineIter->second->getImmediateOutput(sourceId, immediateOutput);
334 3 : }
335 :
336 3 : bool MediaPipelineService::getStats(int sessionId, int32_t sourceId, uint64_t &renderedFrames, uint64_t &droppedFrames)
337 : {
338 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to get stats, session id: %d", sessionId);
339 :
340 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
341 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
342 3 : if (mediaPipelineIter == m_mediaPipelines.end())
343 : {
344 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
345 1 : return false;
346 : }
347 2 : return mediaPipelineIter->second->getStats(sourceId, renderedFrames, droppedFrames);
348 3 : }
349 :
350 3 : bool MediaPipelineService::setVideoWindow(int sessionId, std::uint32_t x, std::uint32_t y, std::uint32_t width,
351 : std::uint32_t height)
352 : {
353 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to set video window, session id: %d", sessionId);
354 :
355 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
356 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
357 3 : if (mediaPipelineIter == m_mediaPipelines.end())
358 : {
359 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
360 1 : return false;
361 : }
362 2 : return mediaPipelineIter->second->setVideoWindow(x, y, width, height);
363 3 : }
364 :
365 3 : bool MediaPipelineService::haveData(int sessionId, MediaSourceStatus status, std::uint32_t numFrames,
366 : std::uint32_t needDataRequestId)
367 : {
368 3 : RIALTO_SERVER_LOG_DEBUG("New data available, session id: %d", sessionId);
369 :
370 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
371 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
372 3 : if (mediaPipelineIter == m_mediaPipelines.end())
373 : {
374 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
375 1 : return false;
376 : }
377 2 : return mediaPipelineIter->second->haveData(status, numFrames, needDataRequestId);
378 3 : }
379 :
380 3 : bool MediaPipelineService::renderFrame(int sessionId)
381 : {
382 3 : RIALTO_SERVER_LOG_DEBUG("Render frame requested, session id: %d", sessionId);
383 :
384 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
385 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
386 3 : if (mediaPipelineIter == m_mediaPipelines.end())
387 : {
388 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
389 1 : return false;
390 : }
391 2 : return mediaPipelineIter->second->renderFrame();
392 3 : }
393 3 : bool MediaPipelineService::setVolume(int sessionId, double targetVolume, uint32_t volumeDuration, EaseType easeType)
394 : {
395 3 : RIALTO_SERVER_LOG_DEBUG("Set volume requested, session id: %d", sessionId);
396 :
397 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
398 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
399 3 : if (mediaPipelineIter == m_mediaPipelines.end())
400 : {
401 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
402 1 : return false;
403 : }
404 2 : return mediaPipelineIter->second->setVolume(targetVolume, volumeDuration, easeType);
405 3 : }
406 :
407 3 : bool MediaPipelineService::getVolume(int sessionId, double &volume)
408 : {
409 3 : RIALTO_SERVER_LOG_DEBUG("Get volume requested, session id: %d", sessionId);
410 :
411 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
412 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
413 3 : if (mediaPipelineIter == m_mediaPipelines.end())
414 : {
415 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
416 1 : return false;
417 : }
418 2 : return mediaPipelineIter->second->getVolume(volume);
419 3 : }
420 :
421 3 : bool MediaPipelineService::setMute(int sessionId, std::int32_t sourceId, bool mute)
422 : {
423 3 : RIALTO_SERVER_LOG_DEBUG("Set mute requested, session id: %d", sessionId);
424 :
425 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
426 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
427 3 : if (mediaPipelineIter == m_mediaPipelines.end())
428 : {
429 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
430 1 : return false;
431 : }
432 2 : return mediaPipelineIter->second->setMute(sourceId, mute);
433 3 : }
434 :
435 3 : bool MediaPipelineService::getMute(int sessionId, std::int32_t sourceId, bool &mute)
436 : {
437 3 : RIALTO_SERVER_LOG_DEBUG("Get mute requested, session id: %d", sessionId);
438 :
439 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
440 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
441 3 : if (mediaPipelineIter == m_mediaPipelines.end())
442 : {
443 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
444 1 : return false;
445 : }
446 2 : return mediaPipelineIter->second->getMute(sourceId, mute);
447 3 : }
448 :
449 3 : bool MediaPipelineService::setTextTrackIdentifier(int sessionId, const std::string &textTrackIdentifier)
450 : {
451 3 : RIALTO_SERVER_LOG_DEBUG("Set text track identifier requested, session id: %d", sessionId);
452 :
453 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
454 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
455 3 : if (mediaPipelineIter == m_mediaPipelines.end())
456 : {
457 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
458 1 : return false;
459 : }
460 2 : return mediaPipelineIter->second->setTextTrackIdentifier(textTrackIdentifier);
461 3 : }
462 :
463 3 : bool MediaPipelineService::getTextTrackIdentifier(int sessionId, std::string &textTrackIdentifier)
464 : {
465 3 : RIALTO_SERVER_LOG_DEBUG("Get text track identifier requested, session id: %d", sessionId);
466 :
467 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
468 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
469 3 : if (mediaPipelineIter == m_mediaPipelines.end())
470 : {
471 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
472 1 : return false;
473 : }
474 2 : return mediaPipelineIter->second->getTextTrackIdentifier(textTrackIdentifier);
475 3 : }
476 :
477 3 : bool MediaPipelineService::setLowLatency(int sessionId, bool lowLatency)
478 : {
479 3 : RIALTO_SERVER_LOG_DEBUG("Set low latency requested, session id: %d", sessionId);
480 :
481 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
482 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
483 3 : if (mediaPipelineIter == m_mediaPipelines.end())
484 : {
485 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
486 1 : return false;
487 : }
488 2 : return mediaPipelineIter->second->setLowLatency(lowLatency);
489 3 : }
490 :
491 3 : bool MediaPipelineService::setSync(int sessionId, bool sync)
492 : {
493 3 : RIALTO_SERVER_LOG_DEBUG("Set sync requested, session id: %d", sessionId);
494 :
495 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
496 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
497 3 : if (mediaPipelineIter == m_mediaPipelines.end())
498 : {
499 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
500 1 : return false;
501 : }
502 2 : return mediaPipelineIter->second->setSync(sync);
503 3 : }
504 :
505 3 : bool MediaPipelineService::getSync(int sessionId, bool &sync)
506 : {
507 3 : RIALTO_SERVER_LOG_DEBUG("Get sync requested, session id: %d", sessionId);
508 :
509 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
510 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
511 3 : if (mediaPipelineIter == m_mediaPipelines.end())
512 : {
513 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
514 1 : return false;
515 : }
516 2 : return mediaPipelineIter->second->getSync(sync);
517 3 : }
518 :
519 3 : bool MediaPipelineService::setSyncOff(int sessionId, bool syncOff)
520 : {
521 3 : RIALTO_SERVER_LOG_DEBUG("Set sync off requested, session id: %d", sessionId);
522 :
523 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
524 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
525 3 : if (mediaPipelineIter == m_mediaPipelines.end())
526 : {
527 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
528 1 : return false;
529 : }
530 2 : return mediaPipelineIter->second->setSyncOff(syncOff);
531 3 : }
532 :
533 3 : bool MediaPipelineService::setStreamSyncMode(int sessionId, int32_t sourceId, int32_t streamSyncMode)
534 : {
535 3 : RIALTO_SERVER_LOG_DEBUG("Set stream sync mode requested, session id: %d", sessionId);
536 :
537 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
538 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
539 3 : if (mediaPipelineIter == m_mediaPipelines.end())
540 : {
541 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
542 1 : return false;
543 : }
544 2 : return mediaPipelineIter->second->setStreamSyncMode(sourceId, streamSyncMode);
545 3 : }
546 :
547 3 : bool MediaPipelineService::getStreamSyncMode(int sessionId, int32_t &streamSyncMode)
548 : {
549 3 : RIALTO_SERVER_LOG_DEBUG("Get stream sync mode requested, session id: %d", sessionId);
550 :
551 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
552 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
553 3 : if (mediaPipelineIter == m_mediaPipelines.end())
554 : {
555 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
556 1 : return false;
557 : }
558 2 : return mediaPipelineIter->second->getStreamSyncMode(streamSyncMode);
559 3 : }
560 :
561 3 : bool MediaPipelineService::flush(int sessionId, std::int32_t sourceId, bool resetTime, bool &isAsync)
562 : {
563 3 : RIALTO_SERVER_LOG_DEBUG("Flush requested, session id: %d", sessionId);
564 :
565 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
566 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
567 3 : if (mediaPipelineIter == m_mediaPipelines.end())
568 : {
569 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
570 1 : return false;
571 : }
572 2 : return mediaPipelineIter->second->flush(sourceId, resetTime, isAsync);
573 3 : }
574 :
575 3 : bool MediaPipelineService::setSourcePosition(int sessionId, int32_t sourceId, int64_t position, bool resetTime,
576 : double appliedRate, uint64_t stopPosition)
577 : {
578 3 : RIALTO_SERVER_LOG_DEBUG("Set Source Position requested, session id: %d", sessionId);
579 :
580 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
581 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
582 3 : if (mediaPipelineIter == m_mediaPipelines.end())
583 : {
584 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
585 1 : return false;
586 : }
587 2 : return mediaPipelineIter->second->setSourcePosition(sourceId, position, resetTime, appliedRate, stopPosition);
588 3 : }
589 :
590 0 : bool MediaPipelineService::setSubtitleOffset(int sessionId, int32_t sourceId, int64_t position)
591 : {
592 0 : RIALTO_SERVER_LOG_DEBUG("Set Subtitle Offset requested, session id: %d", sessionId);
593 :
594 0 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
595 0 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
596 0 : if (mediaPipelineIter == m_mediaPipelines.end())
597 : {
598 0 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
599 0 : return false;
600 : }
601 0 : return mediaPipelineIter->second->setSubtitleOffset(sourceId, position);
602 : }
603 :
604 3 : bool MediaPipelineService::processAudioGap(int sessionId, int64_t position, uint32_t duration, int64_t discontinuityGap,
605 : bool audioAac)
606 : {
607 3 : RIALTO_SERVER_LOG_DEBUG("Process Audio Gap requested, session id: %d", sessionId);
608 :
609 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
610 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
611 3 : if (mediaPipelineIter == m_mediaPipelines.end())
612 : {
613 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
614 1 : return false;
615 : }
616 2 : return mediaPipelineIter->second->processAudioGap(position, duration, discontinuityGap, audioAac);
617 3 : }
618 :
619 3 : bool MediaPipelineService::setBufferingLimit(int sessionId, uint32_t limitBufferingMs)
620 : {
621 3 : RIALTO_SERVER_LOG_DEBUG("Set buffering limit requested, session id: %d", sessionId);
622 :
623 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
624 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
625 3 : if (mediaPipelineIter == m_mediaPipelines.end())
626 : {
627 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
628 1 : return false;
629 : }
630 2 : return mediaPipelineIter->second->setBufferingLimit(limitBufferingMs);
631 3 : }
632 :
633 3 : bool MediaPipelineService::getBufferingLimit(int sessionId, uint32_t &limitBufferingMs)
634 : {
635 3 : RIALTO_SERVER_LOG_DEBUG("Get buffering limit requested, session id: %d", sessionId);
636 :
637 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
638 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
639 3 : if (mediaPipelineIter == m_mediaPipelines.end())
640 : {
641 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
642 1 : return false;
643 : }
644 2 : return mediaPipelineIter->second->getBufferingLimit(limitBufferingMs);
645 3 : }
646 :
647 3 : bool MediaPipelineService::setUseBuffering(int sessionId, bool useBuffering)
648 : {
649 3 : RIALTO_SERVER_LOG_DEBUG("Set use buffering requested, session id: %d", sessionId);
650 :
651 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
652 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
653 3 : if (mediaPipelineIter == m_mediaPipelines.end())
654 : {
655 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
656 1 : return false;
657 : }
658 2 : return mediaPipelineIter->second->setUseBuffering(useBuffering);
659 3 : }
660 :
661 3 : bool MediaPipelineService::getUseBuffering(int sessionId, bool &useBuffering)
662 : {
663 3 : RIALTO_SERVER_LOG_DEBUG("Get use buffering requested, session id: %d", sessionId);
664 :
665 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
666 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
667 3 : if (mediaPipelineIter == m_mediaPipelines.end())
668 : {
669 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exist", sessionId);
670 1 : return false;
671 : }
672 2 : return mediaPipelineIter->second->getUseBuffering(useBuffering);
673 3 : }
674 :
675 3 : bool MediaPipelineService::switchSource(int sessionId, const std::unique_ptr<IMediaPipeline::MediaSource> &source)
676 : {
677 3 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested to switch source, session id: %d", sessionId);
678 :
679 3 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
680 3 : auto mediaPipelineIter = m_mediaPipelines.find(sessionId);
681 3 : if (mediaPipelineIter == m_mediaPipelines.end())
682 : {
683 1 : RIALTO_SERVER_LOG_ERROR("Session with id: %d does not exists", sessionId);
684 1 : return false;
685 : }
686 2 : return mediaPipelineIter->second->switchSource(source);
687 3 : }
688 :
689 2 : bool MediaPipelineService::isVideoMaster(bool &isVideoMaster)
690 : {
691 2 : RIALTO_SERVER_LOG_INFO("MediaPipelineService requested check if video is master");
692 :
693 2 : return m_mediaPipelineCapabilities->isVideoMaster(isVideoMaster);
694 : }
695 :
696 1 : std::vector<std::string> MediaPipelineService::getSupportedMimeTypes(MediaSourceType type)
697 : {
698 1 : return m_mediaPipelineCapabilities->getSupportedMimeTypes(type);
699 : }
700 :
701 1 : bool MediaPipelineService::isMimeTypeSupported(const std::string &mimeType)
702 : {
703 1 : return m_mediaPipelineCapabilities->isMimeTypeSupported(mimeType);
704 : }
705 :
706 1 : std::vector<std::string> MediaPipelineService::getSupportedProperties(MediaSourceType mediaType,
707 : const std::vector<std::string> &propertyNames)
708 : {
709 1 : return m_mediaPipelineCapabilities->getSupportedProperties(mediaType, propertyNames);
710 : }
711 :
712 2 : void MediaPipelineService::ping(const std::shared_ptr<IHeartbeatProcedure> &heartbeatProcedure)
713 : {
714 2 : RIALTO_SERVER_LOG_DEBUG("Ping requested");
715 2 : std::lock_guard<std::mutex> lock{m_mediaPipelineMutex};
716 3 : for (const auto &mediaPipelinePair : m_mediaPipelines)
717 : {
718 1 : auto &mediaPipeline = mediaPipelinePair.second;
719 1 : mediaPipeline->ping(heartbeatProcedure->createHandler());
720 : }
721 2 : }
722 :
723 0 : common::AudioDecoderCapabilities MediaPipelineService::getSupportedAudioCapabilities()
724 : {
725 0 : RIALTO_SERVER_LOG_DEBUG("GetSupportedAudioCapabilities requested");
726 :
727 0 : if (m_mediaCapabilities)
728 : {
729 0 : return m_mediaCapabilities->getSupportedAudioCapabilities();
730 : }
731 :
732 0 : return common::AudioDecoderCapabilities();
733 : }
734 :
735 0 : common::VideoDecoderCapabilities MediaPipelineService::getSupportedVideoCapabilities()
736 : {
737 0 : RIALTO_SERVER_LOG_DEBUG("GetSupportedVideoCapabilities requested");
738 :
739 0 : if (m_mediaCapabilities)
740 : {
741 0 : return m_mediaCapabilities->getSupportedVideoCapabilities();
742 : }
743 :
744 0 : return common::VideoDecoderCapabilities();
745 : }
746 :
747 0 : void MediaPipelineService::setPreloadedCapabilities(const std::optional<common::AudioDecoderCapabilities> &audioCaps,
748 : const std::optional<common::VideoDecoderCapabilities> &videoCaps)
749 : {
750 0 : RIALTO_SERVER_LOG_DEBUG("setPreloadedCapabilities called with audio: %s, video: %s",
751 : audioCaps.has_value() ? "yes" : "no", videoCaps.has_value() ? "yes" : "no");
752 :
753 : // Delegate to MediaCapabilitiesServerInternal to store preloaded state
754 0 : if (m_mediaCapabilities)
755 : {
756 0 : m_mediaCapabilities->setPreloadedCapabilities(audioCaps, videoCaps);
757 : }
758 : }
759 :
760 : } // namespace firebolt::rialto::server::service
|