diff --git a/GstToolkit.cpp b/GstToolkit.cpp index 3c8000b..c55574e 100644 --- a/GstToolkit.cpp +++ b/GstToolkit.cpp @@ -134,22 +134,13 @@ 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(bool enable) -{ - list plugins_list_; - - 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; + const char *plugins[10] = { "omxmpeg4videodec", "omxmpeg2dec", "omxh264dec", "vdpaumpegdec", + "nvh264dec", "nvh265dec", "nvmpeg2videodec", + "nvmpeg4videodec", "nvvp8dec", "nvvp9dec" + }; + const int N = 10; #elif GST_GL_HAVE_PLATFORM_CGL const char *plugins[1] = { "vtdec_hw" }; const int N = 1; @@ -158,6 +149,16 @@ std::list GstToolkit::enable_gpu_decoding_plugins(bool enable) const int N = 0; #endif + +// see https://developer.ridgerun.com/wiki/index.php?title=GStreamer_modify_the_elements_rank +std::list GstToolkit::enable_gpu_decoding_plugins(bool enable) +{ + list plugins_list_; + + static GstRegistry* plugins_register = nullptr; + if ( plugins_register == nullptr ) + plugins_register = gst_registry_get(); + static bool enabled_ = false; if (enabled_ != enable) { enabled_ = enable; @@ -173,3 +174,29 @@ std::list GstToolkit::enable_gpu_decoding_plugins(bool enable) return plugins_list_; } + +std::string GstToolkit::used_gpu_decoding_plugins(GstElement *gstbin) +{ + std::string found = ""; + + auto it = gst_bin_iterate_recurse(GST_BIN(gstbin)); + GValue value = G_VALUE_INIT; + for(GstIteratorResult r = gst_iterator_next(it, &value); r != GST_ITERATOR_DONE; r = gst_iterator_next(it, &value)) + { + if ( r == GST_ITERATOR_OK ) + { + GstElement *e = static_cast(g_value_peek_pointer(&value)); + if (e) { + std::string e_name = gst_element_get_name(e); + for (int i = 0; i < N; i++) { + if (e_name.find(plugins[i]) != std::string::npos) { + found = plugins[i]; + break; + } + } + } + } + } + + return found; +} diff --git a/GstToolkit.h b/GstToolkit.h index c7a3f1c..646b7c9 100644 --- a/GstToolkit.h +++ b/GstToolkit.h @@ -22,6 +22,7 @@ std::string gst_version(); std::list all_plugins(); std::list enable_gpu_decoding_plugins(bool enable = true); +std::string used_gpu_decoding_plugins(GstElement *gstbin); std::list all_plugin_features(std::string pluginname); bool enable_feature (std::string name, bool enable); diff --git a/MediaPlayer.cpp b/MediaPlayer.cpp index 39be1af..8ce792a 100644 --- a/MediaPlayer.cpp +++ b/MediaPlayer.cpp @@ -36,6 +36,7 @@ MediaPlayer::MediaPlayer() seeking_ = false; enabled_ = true; force_software_decoding_ = false; + hardware_decoder_ = ""; rate_ = 1.0; position_ = GST_CLOCK_TIME_NONE; desired_state_ = GST_STATE_PAUSED; @@ -473,6 +474,10 @@ bool MediaPlayer::isImage() const return media_.isimage; } +std::string MediaPlayer::hardwareDecoderName() +{ + return hardware_decoder_; +} bool MediaPlayer::softwareDecodingForced() { @@ -708,6 +713,11 @@ void MediaPlayer::fill_texture(guint index) // initialize texture init_texture(index); + // now that a frame is ready, and once only, browse into the decoder of the pipeline + // for possible hadrware decoding plugins used. Empty string means none. + GstElement *dec = GST_ELEMENT(gst_bin_get_by_name (GST_BIN (pipeline_), "decoder") ); + hardware_decoder_ = GstToolkit::used_gpu_decoding_plugins(dec); + } else { glBindTexture(GL_TEXTURE_2D, textureindex_); diff --git a/MediaPlayer.h b/MediaPlayer.h index 0d178f4..bab2fad 100644 --- a/MediaPlayer.h +++ b/MediaPlayer.h @@ -169,10 +169,6 @@ public: * Set the loop mode * */ void setLoop(LoopMode mode); - - bool softwareDecodingForced(); - void setSoftwareDecodingForced(bool on); - /** * Seek to next frame when paused * (aka next frame) @@ -242,6 +238,17 @@ public: * Must be called in OpenGL context * */ guint texture() const; + /** + * Get the name of the hardware decoder used + * Empty string if none (i.e. software decoding) + * */ + std::string hardwareDecoderName(); + /** + * Forces open using software decoding + * (i.e. without hadrware decoding) + * */ + void setSoftwareDecodingForced(bool on); + bool softwareDecodingForced(); /** * Accept visitors * Used for saving session file @@ -279,6 +286,7 @@ private: bool seeking_; bool enabled_; bool force_software_decoding_; + std::string hardware_decoder_; // fps counter struct TimeCounter { diff --git a/RenderingManager.cpp b/RenderingManager.cpp index 6f25dfb..65000ec 100644 --- a/RenderingManager.cpp +++ b/RenderingManager.cpp @@ -161,10 +161,13 @@ bool Rendering::init() std::list gpuplugins = GstToolkit::enable_gpu_decoding_plugins(Settings::application.render.gpu_decoding); if (Settings::application.render.gpu_decoding) { if (gpuplugins.size() > 0) { - Log::Info("Video decoding favoring the following GPU decoding plugin(s):"); + Log::Info("Fond the following GPU decoding plugin(s):"); for(auto it = gpuplugins.begin(); it != gpuplugins.end(); it++) Log::Info(" - %s", (*it).c_str()); } + else { + Log::Info("No GPU decoding plugin found."); + } } //#if GST_GL_HAVE_PLATFORM_WGL diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 7c04a3c..4af328b 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -1639,8 +1639,14 @@ void MediaController::Render() ImVec2(tooltip_pos.x + width + 10.f, tooltip_pos.y + tooltip_height), IMGUI_COLOR_OVERLAY); ImGui::SetCursorScreenPos(tooltip_pos); + // filename ImGui::Text(" %s", mp_->filename().c_str()); - ImGui::Text(" %s", mp_->media().codec_name.c_str()); + // decoding info + if (Settings::application.render.gpu_decoding) + ImGui::Text(" %s (%s hardware decoder)", mp_->media().codec_name.c_str(), mp_->hardwareDecoderName().c_str()); + else + ImGui::Text(" %s", mp_->media().codec_name.c_str()); + // framerate if ( mp_->frameRate() > 1.f ) ImGui::Text(" %d x %d px, %.2f / %.2f fps", mp_->width(), mp_->height(), mp_->updateFrameRate() , mp_->frameRate() ); else @@ -1710,19 +1716,6 @@ void MediaController::Render() //#endif } -// // if global GPU decoding is enabled -// if (Settings::application.render.gpu_decoding) { - -// // icon GPU disabled? -// bool gpudisabled = mp_->gpuDisabled(); - -// ImGui::SameLine(0, spacing); -// const char *tooltip[2] = {"Hardware decoding enabled", "Hardware decoding disabled"}; -// if (ImGuiToolkit::IconToggle(13,2,14,2, &gpudisabled, tooltip)) { -// mp_->setGpuDisabled(gpudisabled); -// } -// } - // speed slider ImGui::SameLine(0, MAX(spacing * 2.f, width - 500.f) ); float speed = static_cast(mp_->playSpeed()); @@ -1738,6 +1731,21 @@ void MediaController::Render() if (ImGuiToolkit::ButtonIcon(5, 8)) ImGui::OpenPopup( "MenuTimeline" ); if (ImGui::BeginPopup( "MenuTimeline" )) { + // if global GPU decoding is enabled + if (Settings::application.render.gpu_decoding) { +// std::string hwdec = mp_->hardwareDecoderName(); +// if (!hwdec.empty()) { +// if (ImGui::Selectable( "Disable hardware decoder" )){ + +// } +// } +// else { +// if (ImGui::Selectable( "Try to find hardware decoder" )){ + +// } +// } + } + if (ImGui::Selectable( "Reset Speed" )){ speed = 1.f; mp_->setPlaySpeed( static_cast(speed) ); @@ -1749,13 +1757,13 @@ void MediaController::Render() Action::manager().store("Timeline Reset"); } ImGui::Separator(); - ImGui::SetNextItemWidth(150); + ImGui::SetNextItemWidth(180); int smoothcurve = 0; if (ImGui::Combo("##SmoothCurve", &smoothcurve, "Smooth curve\0Just a little\0A bit more\0Quite a lot\0") ){ mp_->timeline()->smoothFading( 10 * (int) pow(4, smoothcurve-1) ); Action::manager().store("Timeline Smooth curve"); } - ImGui::SetNextItemWidth(150); + ImGui::SetNextItemWidth(180); int autofade = 0; if (ImGui::Combo("##Autofade", &autofade, "Auto fading\0 250 ms\0 500 ms\0 1 second\0 2 seconds\0") ){ mp_->timeline()->autoFading( 250 * (int ) pow(2, autofade-1) );