Implemented a detection of hardware decoding used in pipeline

Simple check for names of decoder inside uridecodebin and cross check
with the list of known hardware Decoder Names
This commit is contained in:
brunoherbelin
2021-04-01 00:11:05 +02:00
parent 649d2b7ef7
commit c59994b7e5
6 changed files with 92 additions and 35 deletions

View File

@@ -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<std::string> GstToolkit::enable_gpu_decoding_plugins(bool enable)
{
list<string> 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<std::string> 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<std::string> GstToolkit::enable_gpu_decoding_plugins(bool enable)
{
list<string> 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<std::string> 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<GstElement*>(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;
}

View File

@@ -22,6 +22,7 @@ std::string gst_version();
std::list<std::string> all_plugins();
std::list<std::string> enable_gpu_decoding_plugins(bool enable = true);
std::string used_gpu_decoding_plugins(GstElement *gstbin);
std::list<std::string> all_plugin_features(std::string pluginname);
bool enable_feature (std::string name, bool enable);

View File

@@ -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_);

View File

@@ -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 {

View File

@@ -161,10 +161,13 @@ bool Rendering::init()
std::list<std::string> 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

View File

@@ -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<float>(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<double>(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) );