4#include <gst/rtsp/gstrtspurl.h>
5#include <QtCore/QLatin1String>
6#include <QtCore/QString>
20 GstRTSPUrl *url = NULL;
23 if (!gst_uri_is_valid(uri_str)) {
27 res = gst_rtsp_url_parse(uri_str, &url);
28 if ((res != GST_RTSP_OK) || (url == NULL)) {
30 gst_rtsp_url_free(url);
35 const gboolean hasHost = (url->host && url->host[0] !=
'\0');
36 gst_rtsp_url_free(url);
46 const gchar *factoryName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
51 const QString nameLower = QString::fromUtf8(factoryName).toLower();
54 if (nameLower.startsWith(
"amcviddec-omxgoogle") || nameLower.startsWith(
"amcviddec-c2android")) {
57 if (nameLower.startsWith(
"amcviddec-")) {
61 const auto containsHardware = [](
const gchar *value) {
62 if (!value)
return false;
63 gchar *lower = g_ascii_strdown(value, -1);
64 bool found = (g_strrstr(lower,
"hardware") !=
nullptr);
69 if (containsHardware(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS))) {
73 if (containsHardware(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_DESCRIPTION))) {
77 static constexpr QLatin1String kHardwareTags[] = {
81 QLatin1String(
"msdk"),
82 QLatin1String(
"vulkan"),
84 QLatin1String(
"dxva"),
85 QLatin1String(
"vtdec"),
86 QLatin1String(
"metal"),
89 for (
const auto &tag : kHardwareTags) {
90 if (nameLower.contains(tag)) {
100void changeFeatureRank(GstRegistry *registry,
const char *featureName, uint16_t rank)
102 if (!registry || !featureName) {
106 GstPluginFeature *feature = gst_registry_lookup_feature(registry, featureName);
108 qCDebug(GStreamerHelpersLog) <<
"Failed to change ranking of feature. Feature does not exist:" << featureName;
112 qCDebug(GStreamerHelpersLog) <<
" Changing feature (" << featureName <<
") to use rank:" << rank;
113 gst_plugin_feature_set_rank(feature, rank);
114 gst_clear_object(&feature);
117void lowerDecoderRanksByClass(GstRegistry *registry,
bool lowerHardware)
119 static constexpr uint16_t NewRank = GST_RANK_NONE;
121 qCCritical(GStreamerHelpersLog) <<
"Invalid registry!";
125 GList *decoderFactories = gst_element_factory_list_get_elements(
126 static_cast<GstElementFactoryListType
>(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO),
129 for (GList *node = decoderFactories; node !=
nullptr; node = node->next) {
130 GstElementFactory *factory = GST_ELEMENT_FACTORY(node->data);
139 const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
144 qCDebug(GStreamerHelpersLog) <<
"Lowering" << (lowerHardware ?
"hardware" :
"software") <<
"decoder rank:" << name;
145 gst_plugin_feature_set_rank(GST_PLUGIN_FEATURE(factory), NewRank);
148 gst_plugin_feature_list_free(decoderFactories);
151void prioritizeByHardwareClass(GstRegistry *registry, uint16_t prioritizedRank,
bool requireHardware)
154 qCCritical(GStreamerHelpersLog) <<
"Failed to get gstreamer registry.";
158 GList *decoderFactories = gst_element_factory_list_get_elements(
159 static_cast<GstElementFactoryListType
>(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO),
162 if (!decoderFactories) {
163 qCDebug(GStreamerHelpersLog) <<
"No decoder factories available while prioritizing"
164 << (requireHardware ?
"hardware" :
"software") <<
"decoders";
168 qCDebug(GStreamerHelpersLog) <<
"Prioritizing" << (requireHardware ?
"hardware" :
"software")
169 <<
"video decoders with rank:" << prioritizedRank;
170 int matchedFactories = 0;
171 for (GList *node = decoderFactories; node !=
nullptr; node = node->next) {
172 GstElementFactory *factory = GST_ELEMENT_FACTORY(node->data);
181 const gchar *featureName = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
186 changeFeatureRank(registry, featureName, prioritizedRank);
190 if (matchedFactories == 0) {
191 qCWarning(GStreamerHelpersLog) <<
"No" << (requireHardware ?
"hardware" :
"software")
192 <<
"video decoder factories found to reprioritize.";
195 qCDebug(GStreamerHelpersLog) <<
"Lowering" << (requireHardware ?
"software" :
"hardware") <<
"decoder ranks.";
196 lowerDecoderRanksByClass(registry, !requireHardware);
198 gst_plugin_feature_list_free(decoderFactories);
205 GstRegistry *registry = gst_registry_get();
208 qCCritical(GStreamerHelpersLog) <<
"Failed to get gstreamer registry.";
212 static constexpr uint16_t PrioritizedRank = GST_RANK_PRIMARY + 1;
219 prioritizeByHardwareClass(registry, PrioritizedRank,
false);
222 prioritizeByHardwareClass(registry, PrioritizedRank,
true);
225 for (
const char *name : {
"vaav1dec",
"vah264dec",
"vah265dec",
"vajpegdec",
"vampeg2dec",
"vavp8dec",
"vavp9dec"}) {
226 changeFeatureRank(registry, name, PrioritizedRank);
230 for (
const char *name : {
"nvav1dec",
"nvh264dec",
"nvh265dec",
"nvjpegdec",
"nvmpeg2videodec",
"nvmpeg4videodec",
"nvmpegvideodec",
"nvvp8dec",
"nvvp9dec"}) {
231 changeFeatureRank(registry, name, PrioritizedRank);
235 for (
const char *name : {
"d3d11av1dec",
"d3d11h264dec",
"d3d11h265dec",
"d3d11mpeg2dec",
"d3d11vp8dec",
"d3d11vp9dec",
236 "d3d12av1dec",
"d3d12h264dec",
"d3d12h265dec",
"d3d12mpeg2dec",
"d3d12vp8dec",
"d3d12vp9dec",
237 "dxvaav1decoder",
"dxvah264decoder",
"dxvah265decoder",
"dxvampeg2decoder",
"dxvavp8decoder",
"dxvavp9decoder"}) {
238 changeFeatureRank(registry, name, PrioritizedRank);
242 for (
const char *name : {
"vtdec_hw",
"vtdec"}) {
243 changeFeatureRank(registry, name, PrioritizedRank);
247 for (
const char *name : {
"qsvh264dec",
"qsvh265dec",
"qsvjpegdec",
"qsvvp9dec",
"msdkav1dec",
"msdkh264dec",
"msdkh265dec",
"msdkmjpegdec",
"msdkmpeg2dec",
"msdkvc1dec",
"msdkvp8dec",
"msdkvp9dec"}) {
248 changeFeatureRank(registry, name, PrioritizedRank);
252 for (
const char *name : {
"vulkanh264dec",
"vulkanh265dec"}) {
253 changeFeatureRank(registry, name, PrioritizedRank);
257 qCWarning(GStreamerHelpersLog) <<
"Can't handle decode option:" << option;
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void setCodecPriorities(VideoDecoderOptions option)
@ ForceVideoDecoderDefault
@ ForceVideoDecoderVulkan
@ ForceVideoDecoderSoftware
@ ForceVideoDecoderNVIDIA
@ ForceVideoDecoderVideoToolbox
@ ForceVideoDecoderHardware
@ ForceVideoDecoderDirectX3D
bool isHardwareDecoderFactory(GstElementFactory *factory)
gboolean isValidRtspUri(const gchar *uri_str)