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