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 "Utils.h"
21 : #include "CapsBuilder.h"
22 : #include "GstMimeMapping.h"
23 : #include "IGlibWrapper.h"
24 : #include "IGstWrapper.h"
25 : #include "RialtoServerLogging.h"
26 : #include <algorithm>
27 : #include <string.h>
28 :
29 : namespace
30 : {
31 : const char *underflowSignals[]{"buffer-underflow-callback", "vidsink-underflow-callback", "underrun-callback"};
32 :
33 190 : bool isType(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element, GstElementFactoryListType type)
34 : {
35 190 : if (!element)
36 : {
37 0 : return false;
38 : }
39 :
40 190 : GstElementFactory *factory{gstWrapper.gstElementGetFactory(element)};
41 190 : if (!factory)
42 : {
43 0 : return false;
44 : }
45 190 : return gstWrapper.gstElementFactoryListIsType(factory, type);
46 : }
47 : } // namespace
48 :
49 : namespace firebolt::rialto::server
50 : {
51 :
52 3 : bool isVideoDecoder(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element)
53 : {
54 3 : return isType(gstWrapper, element, GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO);
55 : }
56 :
57 25 : bool isAudioDecoder(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element)
58 : {
59 25 : return isType(gstWrapper, element, GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO);
60 : }
61 :
62 7 : bool isVideoParser(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element)
63 : {
64 7 : return isType(gstWrapper, element, GST_ELEMENT_FACTORY_TYPE_PARSER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO);
65 : }
66 :
67 3 : bool isAudioParser(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element)
68 : {
69 3 : return isType(gstWrapper, element, GST_ELEMENT_FACTORY_TYPE_PARSER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO);
70 : }
71 :
72 33 : bool isVideoSink(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element)
73 : {
74 33 : return isType(gstWrapper, element, GST_ELEMENT_FACTORY_TYPE_SINK | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO);
75 : }
76 :
77 21 : bool isAudioSink(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element)
78 : {
79 21 : return isType(gstWrapper, element, GST_ELEMENT_FACTORY_TYPE_SINK | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO);
80 : }
81 :
82 27 : bool isSink(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element)
83 : {
84 27 : return isType(gstWrapper, element, GST_ELEMENT_FACTORY_TYPE_SINK);
85 : }
86 :
87 33 : bool isDecoder(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element)
88 : {
89 33 : return isType(gstWrapper, element, GST_ELEMENT_FACTORY_TYPE_DECODER);
90 : }
91 :
92 27 : bool isAudio(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element)
93 : {
94 27 : return isType(gstWrapper, element, GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO);
95 : }
96 :
97 11 : bool isVideo(const firebolt::rialto::wrappers::IGstWrapper &gstWrapper, GstElement *element)
98 : {
99 11 : return isType(gstWrapper, element, GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO);
100 : }
101 :
102 27 : std::optional<std::string> getUnderflowSignalName(const firebolt::rialto::wrappers::IGlibWrapper &glibWrapper,
103 : GstElement *element)
104 : {
105 27 : GType type = glibWrapper.gObjectType(element);
106 27 : guint nsignals{0};
107 27 : guint *signals = glibWrapper.gSignalListIds(type, &nsignals);
108 :
109 27 : for (guint i = 0; i < nsignals; i++)
110 : {
111 : GSignalQuery query;
112 27 : glibWrapper.gSignalQuery(signals[i], &query);
113 81 : const auto signalNameIt = std::find_if(std::begin(underflowSignals), std::end(underflowSignals),
114 27 : [&](const auto *signalName)
115 27 : { return strcmp(signalName, query.signal_name) == 0; });
116 :
117 27 : if (std::end(underflowSignals) != signalNameIt)
118 : {
119 27 : glibWrapper.gFree(signals);
120 54 : return std::string(*signalNameIt);
121 : }
122 : }
123 0 : glibWrapper.gFree(signals);
124 :
125 0 : return std::nullopt;
126 : }
127 :
128 24 : GstCaps *createCapsFromMediaSource(const std::shared_ptr<firebolt::rialto::wrappers::IGstWrapper> &gstWrapper,
129 : const std::shared_ptr<firebolt::rialto::wrappers::IGlibWrapper> &glibWrapper,
130 : const std::unique_ptr<IMediaPipeline::MediaSource> &source)
131 : {
132 24 : std::unique_ptr<MediaSourceCapsBuilder> capsBuilder;
133 :
134 24 : firebolt::rialto::SourceConfigType configType = source->getConfigType();
135 24 : if (configType == firebolt::rialto::SourceConfigType::AUDIO)
136 : {
137 14 : const IMediaPipeline::MediaSourceAudio *kSource = dynamic_cast<IMediaPipeline::MediaSourceAudio *>(source.get());
138 14 : if (kSource)
139 : {
140 13 : capsBuilder = std::make_unique<MediaSourceAudioCapsBuilder>(gstWrapper, glibWrapper, *kSource);
141 : }
142 : else
143 : {
144 1 : RIALTO_SERVER_LOG_ERROR("Failed to cast to audio source");
145 1 : return nullptr;
146 : }
147 : }
148 10 : else if (configType == firebolt::rialto::SourceConfigType::VIDEO)
149 : {
150 7 : const IMediaPipeline::MediaSourceVideo *kSource = dynamic_cast<IMediaPipeline::MediaSourceVideo *>(source.get());
151 7 : if (kSource)
152 : {
153 6 : capsBuilder = std::make_unique<MediaSourceVideoCapsBuilder>(gstWrapper, glibWrapper, *kSource);
154 : }
155 : else
156 : {
157 1 : RIALTO_SERVER_LOG_ERROR("Failed to cast to video source");
158 1 : return nullptr;
159 : }
160 : }
161 3 : else if (configType == firebolt::rialto::SourceConfigType::VIDEO_DOLBY_VISION)
162 : {
163 : const IMediaPipeline::MediaSourceVideoDolbyVision *kSource =
164 2 : dynamic_cast<IMediaPipeline::MediaSourceVideoDolbyVision *>(source.get());
165 2 : if (kSource)
166 : {
167 1 : capsBuilder = std::make_unique<MediaSourceVideoDolbyVisionCapsBuilder>(gstWrapper, glibWrapper, *kSource);
168 : }
169 : else
170 : {
171 1 : RIALTO_SERVER_LOG_ERROR("Failed to cast to dolby vision source!");
172 1 : return nullptr;
173 : }
174 : }
175 1 : else if (configType == firebolt::rialto::SourceConfigType::SUBTITLE)
176 : {
177 : // subtitle caps is just a simple type, without any extra parameters
178 1 : return firebolt::rialto::server::createSimpleCapsFromMimeType(gstWrapper, *source.get());
179 : }
180 : else
181 : {
182 0 : RIALTO_SERVER_LOG_ERROR("Invalid config type %u", static_cast<uint32_t>(configType));
183 0 : return nullptr;
184 : }
185 :
186 20 : return capsBuilder->buildCaps();
187 24 : }
188 : } // namespace firebolt::rialto::server
|