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