diff --git a/GstToolkit.cpp b/GstToolkit.cpp index d35656c..afb4b43 100644 --- a/GstToolkit.cpp +++ b/GstToolkit.cpp @@ -2,6 +2,8 @@ #include using namespace std; +#include + #include "GstToolkit.h" string GstToolkit::time_to_string(guint64 t, time_string_mode m) @@ -121,3 +123,37 @@ string GstToolkit::gst_version() return oss.str(); } + + +// see https://developer.ridgerun.com/wiki/index.php?title=GStreamer_modify_the_elements_rank + +std::list GstToolkit::enable_gpu_decoding_plugins() +{ + static list pluginslist; + static GstRegistry* plugins_register = nullptr; + + if ( plugins_register == nullptr ) { + plugins_register = gst_registry_get(); + +#if GST_GL_HAVE_PLATFORM_GLX + // https://gstreamer.freedesktop.org/documentation/nvcodec/index.html?gi-language=c#plugin-nvcodec + const char *plugins[6] = { "nvh264dec", "nvh265dec", "nvmpeg2videodec", + "nvmpeg4videodec", "nvvp8dec", "nvvp9dec" }; + const int N = 6; +#elif GST_GL_HAVE_PLATFORM_WGL + const char *plugins[1] = { "avdec_h264"}; + const int N = 1; +#endif + + for (int i = 0; i < N; i++) { + GstPluginFeature* feature = gst_registry_lookup_feature(plugins_register, plugins[i]); + if(feature != NULL) { + pluginslist.push_front( string( plugins[i] ) ); + gst_plugin_feature_set_rank(feature, GST_RANK_PRIMARY + 1); + gst_object_unref(feature); + } + } + } + + return pluginslist; +} diff --git a/GstToolkit.h b/GstToolkit.h index d60cc6e..3857501 100644 --- a/GstToolkit.h +++ b/GstToolkit.h @@ -18,9 +18,11 @@ typedef enum { std::string time_to_string(guint64 t, time_string_mode m = TIME_STRING_ADJUSTED); std::string gst_version(); -std::list all_plugins(); -std::list all_plugin_features(std::string pluginname); +std::list all_plugins(); +std::list enable_gpu_decoding_plugins(); + +std::list all_plugin_features(std::string pluginname); bool enable_feature (std::string name, bool enable); } diff --git a/RenderingManager.cpp b/RenderingManager.cpp index a85a8b3..fb4316f 100644 --- a/RenderingManager.cpp +++ b/RenderingManager.cpp @@ -157,6 +157,15 @@ bool Rendering::init() g_setenv ("GST_GL_API", "opengl3", TRUE); gst_init (NULL, NULL); + // increase selection rank for GPU decoding plugins + if (Settings::application.render.gpu_decoding) { + std::list gpuplugins = GstToolkit::enable_gpu_decoding_plugins(); + if (gpuplugins.size() > 0) { + Log::Info("Video decoding favoring the following GPU decoding plugin(s):"); + for(auto it = gpuplugins.begin(); it != gpuplugins.end(); it++) + Log::Info(" - %s", (*it).c_str()); + } + } //#if GST_GL_HAVE_PLATFORM_WGL // global_gl_context = gst_gl_context_new_wrapped (display, (guintptr) wglGetCurrentContext (), diff --git a/Settings.cpp b/Settings.cpp index 1f9edb9..07a0c7d 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -82,6 +82,7 @@ void Settings::Save() RenderNode->SetAttribute("vsync", application.render.vsync); RenderNode->SetAttribute("multisampling", application.render.multisampling); RenderNode->SetAttribute("blit", application.render.blit); + RenderNode->SetAttribute("gpu_decoding", application.render.gpu_decoding); RenderNode->SetAttribute("ratio", application.render.ratio); RenderNode->SetAttribute("res", application.render.res); pRoot->InsertEndChild(RenderNode); @@ -264,6 +265,7 @@ void Settings::Load() rendernode->QueryIntAttribute("vsync", &application.render.vsync); rendernode->QueryIntAttribute("multisampling", &application.render.multisampling); rendernode->QueryBoolAttribute("blit", &application.render.blit); + rendernode->QueryBoolAttribute("gpu_decoding", &application.render.gpu_decoding); rendernode->QueryIntAttribute("ratio", &application.render.ratio); rendernode->QueryIntAttribute("res", &application.render.res); } diff --git a/Settings.h b/Settings.h index ee6b85f..8d8560d 100644 --- a/Settings.h +++ b/Settings.h @@ -136,14 +136,16 @@ struct RenderConfig int ratio; int res; float fading; + bool gpu_decoding; RenderConfig() { blit = false; - vsync = 1; // todo GUI selection - multisampling = 2; // todo GUI selection + vsync = 1; + multisampling = 2; ratio = 3; res = 1; fading = 0.0; + gpu_decoding = true; } }; diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 4d020bb..d0c9add 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -2886,7 +2886,11 @@ void ShowConfig(bool* p_open) bool vsync = (Settings::application.render.vsync < 2); ImGui::Checkbox("Sync refresh with monitor (v-sync 60Hz)", &vsync); Settings::application.render.vsync = vsync ? 1 : 2; + ImGui::Checkbox("Use GPU video decoding when possible", &Settings::application.render.gpu_decoding); + ImGui::Spacing(); ImGui::Text( ICON_FA_EXCLAMATION " Restart the application for change to take effect."); + if (ImGui::Button( ICON_FA_POWER_OFF " Quit ", ImVec2(250,0))) + Rendering::manager().close(); } ImGui::End();