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 2026 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 <stdexcept>
21 :
22 : #include "IGstCapabilities.h"
23 : #include "MediaCapabilitiesServerInternal.h"
24 : #include "RialtoServerLogging.h"
25 : #include <mutex>
26 :
27 : namespace firebolt::rialto::server
28 : {
29 : std::shared_ptr<IMediaCapabilitiesServerInternal>
30 0 : MediaCapabilitiesServerInternalFactory::createMediaCapabilitiesServerInternal() const
31 : {
32 0 : std::shared_ptr<IMediaCapabilitiesServerInternal> mediaCapabilities;
33 :
34 : try
35 : {
36 : // Create GstCapabilities for runtime GStreamer queries (fallback path)
37 0 : std::shared_ptr<IGstCapabilitiesFactory> gstCapabilitiesFactory = IGstCapabilitiesFactory::getFactory();
38 0 : if (!gstCapabilitiesFactory)
39 : {
40 0 : throw std::runtime_error("Failed to get the gstreamer capabilities factory");
41 : }
42 :
43 0 : auto gstCapabilitiesUnique = gstCapabilitiesFactory->createGstCapabilities();
44 0 : if (!gstCapabilitiesUnique)
45 : {
46 0 : throw std::runtime_error("Failed to create GstCapabilities");
47 : }
48 :
49 : // Create MediaCapabilitiesServerInternal orchestrator for GStreamer queries (fallback path)
50 : // Pass ownership of gstCapabilities to MediaCapabilitiesServerInternal (unique_ptr)
51 : // Preloaded capabilities are applied later by the caller via setPreloadedCapabilities()
52 0 : mediaCapabilities = std::make_shared<MediaCapabilitiesServerInternal>(std::move(gstCapabilitiesUnique));
53 :
54 0 : RIALTO_SERVER_LOG_DEBUG("Created server-side MediaCapabilitiesServerInternal with GStreamer orchestration");
55 : }
56 0 : catch (const std::exception &e)
57 : {
58 0 : RIALTO_SERVER_LOG_ERROR("Failed to create server-side media capabilities, reason: %s", e.what());
59 : }
60 :
61 0 : return mediaCapabilities;
62 : }
63 :
64 0 : std::shared_ptr<IMediaCapabilitiesServerInternalFactory> IMediaCapabilitiesServerInternalFactory::createFactory()
65 : {
66 0 : std::shared_ptr<IMediaCapabilitiesServerInternalFactory> factory;
67 :
68 : try
69 : {
70 0 : factory = std::make_shared<MediaCapabilitiesServerInternalFactory>();
71 : }
72 0 : catch (const std::exception &e)
73 : {
74 0 : RIALTO_SERVER_LOG_ERROR("Failed to create the server-internal media capabilities factory, reason: %s", e.what());
75 : }
76 :
77 0 : return factory;
78 : }
79 :
80 18 : MediaCapabilitiesServerInternal::MediaCapabilitiesServerInternal(std::unique_ptr<IGstCapabilities> gstCapabilities)
81 18 : : m_gstCapabilities{std::move(gstCapabilities)}
82 : {
83 18 : RIALTO_SERVER_LOG_DEBUG("MediaCapabilitiesServerInternal: constructor - uses GStreamer for fallback queries");
84 18 : if (!m_gstCapabilities)
85 : {
86 1 : throw std::runtime_error("GstCapabilities is required");
87 : }
88 21 : }
89 :
90 5 : firebolt::rialto::common::AudioDecoderCapabilities MediaCapabilitiesServerInternal::getSupportedAudioCapabilities()
91 : {
92 : // Path 0: Check preloaded capabilities first (highest priority)
93 : {
94 5 : std::lock_guard<std::mutex> lock{m_preloadedCapabilitiesMutex};
95 5 : if (m_preloadedAudioCapabilities.has_value())
96 : {
97 2 : RIALTO_SERVER_LOG_DEBUG("Returning preloaded audio capabilities (Path 0)");
98 2 : return *m_preloadedAudioCapabilities;
99 : }
100 5 : }
101 :
102 : // Path B: Fall back to GStreamer queries
103 3 : RIALTO_SERVER_LOG_DEBUG("Returning GStreamer audio capabilities (Path B fallback)");
104 3 : return m_gstCapabilities->getSupportedAudioCapabilities();
105 : }
106 :
107 4 : firebolt::rialto::common::VideoDecoderCapabilities MediaCapabilitiesServerInternal::getSupportedVideoCapabilities()
108 : {
109 : // Path 0: Check preloaded capabilities first (highest priority)
110 : {
111 4 : std::lock_guard<std::mutex> lock{m_preloadedCapabilitiesMutex};
112 4 : if (m_preloadedVideoCapabilities.has_value())
113 : {
114 2 : RIALTO_SERVER_LOG_DEBUG("Returning preloaded video capabilities (Path 0)");
115 2 : return *m_preloadedVideoCapabilities;
116 : }
117 4 : }
118 :
119 : // Path B: Fall back to GStreamer queries
120 2 : RIALTO_SERVER_LOG_DEBUG("Returning GStreamer video capabilities (Path B fallback)");
121 2 : return m_gstCapabilities->getSupportedVideoCapabilities();
122 : }
123 :
124 4 : void MediaCapabilitiesServerInternal::setPreloadedCapabilities(
125 : const std::optional<firebolt::rialto::common::AudioDecoderCapabilities> &audioCapabilities,
126 : const std::optional<firebolt::rialto::common::VideoDecoderCapabilities> &videoCapabilities)
127 : {
128 4 : std::lock_guard<std::mutex> lock{m_preloadedCapabilitiesMutex};
129 4 : m_preloadedAudioCapabilities = audioCapabilities;
130 4 : m_preloadedVideoCapabilities = videoCapabilities;
131 4 : RIALTO_SERVER_LOG_DEBUG("Preloaded capabilities set (audio: %s, video: %s)",
132 : audioCapabilities.has_value() ? "yes" : "no", videoCapabilities.has_value() ? "yes" : "no");
133 : }
134 :
135 : } // namespace firebolt::rialto::server
|