From 6529b170e67ef4208403da95d38cedb2ca871ad9 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Mon, 30 Jan 2023 00:07:52 +0100 Subject: [PATCH] Cleanup Source Fail reporting All Stream report failure with logs, read in InfoVisitor for Sources. ImGuiVisitor for Sources also detect failure of source and its stream. Cleanup of unused includes and functions. --- src/Connection.h | 4 +- src/ImGuiVisitor.cpp | 362 +++++++++++++++++++---------------- src/InfoVisitor.cpp | 179 ++++++++++------- src/MediaPlayer.cpp | 17 +- src/MediaPlayer.h | 33 +--- src/MultiFileSource.cpp | 22 +-- src/MultiFileSource.h | 1 - src/NetworkSource.cpp | 13 +- src/NetworkSource.h | 2 - src/Stream.cpp | 11 +- src/Stream.h | 6 + src/StreamSource.cpp | 2 - src/Streamer.cpp | 2 - src/UserInterfaceManager.cpp | 2 +- src/defines.h | 1 + 15 files changed, 347 insertions(+), 310 deletions(-) diff --git a/src/Connection.h b/src/Connection.h index e33fce2..06fb74a 100644 --- a/src/Connection.h +++ b/src/Connection.h @@ -2,10 +2,12 @@ #define CONNECTION_H #include +#include #include #include -#include "NetworkToolkit.h" +#include +#include #define MAX_HANDSHAKE 20 #define HANDSHAKE_PORT 71310 diff --git a/src/ImGuiVisitor.cpp b/src/ImGuiVisitor.cpp index e1af4b9..f101dca 100644 --- a/src/ImGuiVisitor.cpp +++ b/src/ImGuiVisitor.cpp @@ -380,13 +380,14 @@ void ImGuiVisitor::visit (Source& s) const float preview_height = 4.5f * ImGui::GetFrameHeightWithSpacing(); const float space = ImGui::GetStyle().ItemSpacing.y; + ImGui::PushID(std::to_string(s.id()).c_str()); + + // blending selection + s.blendingShader()->accept(*this); + + // Draw different info if failed or succeed if ( !s.failed() ) { - ImGui::PushID(std::to_string(s.id()).c_str()); - - // blending selection - s.blendingShader()->accept(*this); - // remember where we were... ImVec2 pos = ImGui::GetCursorPos(); @@ -538,10 +539,6 @@ void ImGuiVisitor::visit (Source& s) s.processingShader()->accept(*this); } - ImGui::Spacing(); - - ImGui::PopID(); - } else { @@ -568,12 +565,15 @@ void ImGuiVisitor::visit (Source& s) // back ImGui::SetCursorPos( ImVec2( pos.x, pos.y + preview_height)); - ImGui::Spacing(); } + ImGui::PopID(); + + ImGui::Spacing(); ImGuiToolkit::Icon(s.icon().x, s.icon().y); ImGui::SameLine(0, IMGUI_SAME_LINE); ImGui::Text("%s", s.info().c_str()); + } void ImGuiVisitor::visit (MediaSource& s) @@ -584,32 +584,28 @@ void ImGuiVisitor::visit (MediaSource& s) ImGui::Text("%s", info.str().c_str()); ImGui::PopTextWrapPos(); - // icon (>) to open player - if ( s.playable() ) { - ImVec2 pos = ImGui::GetCursorPos(); - ImGui::SameLine(0, 0); - ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); - if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) - UserInterface::manager().showSourceEditor(&s); - ImGui::SetCursorPos(pos); + if ( !s.failed() ) { + // icon (>) to open player + if ( s.playable() ) { + ImVec2 pos = ImGui::GetCursorPos(); + ImGui::SameLine(0, 0); + ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); + if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) + UserInterface::manager().showSourceEditor(&s); + ImGui::SetCursorPos(pos); + } } + else + info.reset(); // folder std::string path = SystemToolkit::path_filename(s.path()); std::string label = BaseToolkit::truncated(path, 25); label = BaseToolkit::transliterate(label); ImGuiToolkit::ButtonOpenUrl( label.c_str(), path.c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0) ); - ImGui::SameLine(0, IMGUI_SAME_LINE); ImGui::Text("Folder"); -// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); -// if ( ImGui::Button("Replace") ) { - -// s.setPath("/home/bh/Videos/iss.mov"); -// Mixer::manager().recreateSource( Mixer::manager().findSource( s.id() ) ); - -// } } void ImGuiVisitor::visit (SessionFileSource& s) @@ -623,58 +619,65 @@ void ImGuiVisitor::visit (SessionFileSource& s) ImGui::Text("%s", info.str().c_str()); ImGui::PopTextWrapPos(); - // icon (>) to open player - if ( s.playable() ) { - ImVec2 pos = ImGui::GetCursorPos(); - ImGui::SameLine(0, 0); - ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); - if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) - UserInterface::manager().showSourceEditor(&s); - ImGui::SetCursorPos(pos); - } + if ( !s.failed() ) { - if ( ImGui::Button( ICON_FA_SIGN_OUT_ALT " Import", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) - Mixer::manager().import( &s ); - ImGui::SameLine(0, IMGUI_SAME_LINE); - ImGui::Text("Sources"); - - // versions - SessionSnapshots *versions = s.session()->snapshots(); - if (versions->keys_.size()>0) { - ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - if (ImGui::BeginCombo("Version", ICON_FA_CODE_BRANCH " Select" ) ) - { - for (auto v = versions->keys_.crbegin() ; v != versions->keys_.crend(); ++v){ - std::string label = std::to_string(*v); - const tinyxml2::XMLElement *snap = versions->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(*v).c_str() ); - if (snap) - label = snap->Attribute("label"); - if (ImGui::Selectable( label.c_str() )) { - s.session()->applySnapshot(*v); - } - } - ImGui::EndCombo(); + // icon (>) to open player + if ( s.playable() ) { + ImVec2 pos = ImGui::GetCursorPos(); + ImGui::SameLine(0, 0); + ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); + if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) + UserInterface::manager().showSourceEditor(&s); + ImGui::SetCursorPos(pos); } - } - // fading - if (ImGuiToolkit::IconButton(2, 1)) s.session()->setFadingTarget(0.f); - int f = 100 - int(s.session()->fading() * 100.f); - ImGui::SameLine(0, IMGUI_SAME_LINE); - ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - if (ImGui::SliderInt("Fading", &f, 0, 100, f > 99 ? "None" : "%d %%") ) - s.session()->setFadingTarget( float(100 - f) * 0.01f ); - if (ImGui::IsItemDeactivatedAfterEdit()){ - std::ostringstream oss; - oss << s.name() << ": Fading " << f << " %"; - Action::manager().store(oss.str()); - } + if ( ImGui::Button( ICON_FA_SIGN_OUT_ALT " Import", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) + Mixer::manager().import( &s ); + ImGui::SameLine(0, IMGUI_SAME_LINE); + ImGui::Text("Sources"); + + // versions + SessionSnapshots *versions = s.session()->snapshots(); + if (versions->keys_.size()>0) { + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + if (ImGui::BeginCombo("Version", ICON_FA_CODE_BRANCH " Select" ) ) + { + for (auto v = versions->keys_.crbegin() ; v != versions->keys_.crend(); ++v){ + std::string label = std::to_string(*v); + const tinyxml2::XMLElement *snap = versions->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(*v).c_str() ); + if (snap) + label = snap->Attribute("label"); + if (ImGui::Selectable( label.c_str() )) { + s.session()->applySnapshot(*v); + } + } + ImGui::EndCombo(); + } + } + + // fading + if (ImGuiToolkit::IconButton(2, 1)) s.session()->setFadingTarget(0.f); + int f = 100 - int(s.session()->fading() * 100.f); + ImGui::SameLine(0, IMGUI_SAME_LINE); + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + if (ImGui::SliderInt("Fading", &f, 0, 100, f > 99 ? "None" : "%d %%") ) + s.session()->setFadingTarget( float(100 - f) * 0.01f ); + if (ImGui::IsItemDeactivatedAfterEdit()){ + std::ostringstream oss; + oss << s.name() << ": Fading " << f << " %"; + Action::manager().store(oss.str()); + } + + // file open + if ( ImGui::Button( ICON_FA_FILE_UPLOAD " Open", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) + Mixer::manager().set( s.detach() ); + ImGui::SameLine(0, IMGUI_SAME_LINE); + ImGui::Text("File"); + + } + else + info.reset(); - // file open - if ( ImGui::Button( ICON_FA_FILE_UPLOAD " Open", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) - Mixer::manager().set( s.detach() ); - ImGui::SameLine(0, IMGUI_SAME_LINE); - ImGui::Text("File"); // file path std::string path = SystemToolkit::path_filename(s.path()); std::string label = BaseToolkit::truncated(path, 25); @@ -698,7 +701,7 @@ void ImGuiVisitor::visit (SessionGroupSource& s) ImGui::PopTextWrapPos(); // icon (>) to open player - if ( s.playable() ) { + if ( s.playable() && !s.failed() ) { ImVec2 pos = ImGui::GetCursorPos(); ImGui::SameLine(0, 0); ImGui::SameLine(0, 10.f + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); @@ -1078,21 +1081,27 @@ void ImGuiVisitor::visit (PatternSource& s) ImGui::Text("%s", info.str().c_str()); ImGui::PopTextWrapPos(); - // icon (>) to open player - if ( s.playable() ) { - ImVec2 pos = ImGui::GetCursorPos(); - ImGui::SameLine(0, 0); - ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); - if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) - UserInterface::manager().showSourceEditor(&s); - ImGui::SetCursorPos(pos); + if ( !s.failed() ) { + // icon (>) to open player + if ( s.playable() ) { + ImVec2 pos = ImGui::GetCursorPos(); + ImGui::SameLine(0, 0); + ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); + if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) + UserInterface::manager().showSourceEditor(&s); + ImGui::SetCursorPos(pos); + } } + else + info.reset(); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - if (ImGui::BeginCombo("##Patterns", Pattern::get(s.pattern()->type()).label.c_str()) ) + if (ImGui::BeginCombo("##Patterns", Pattern::get(s.pattern()->type()).label.c_str(), ImGuiComboFlags_HeightLarge) ) { for (uint p = 0; p < Pattern::count(); ++p){ - if (ImGui::Selectable( Pattern::get(p).label.c_str() )) { + pattern_descriptor pattern = Pattern::get(p); + std::string label = pattern.label + (pattern.animated ? " " ICON_FA_CARET_RIGHT : " "); + if (pattern.available && ImGui::Selectable( label.c_str(), p == s.pattern()->type() )) { s.setPattern(p, s.pattern()->resolution()); info.reset(); std::ostringstream oss; @@ -1113,15 +1122,19 @@ void ImGuiVisitor::visit (DeviceSource& s) ImGui::Text("%s", info.str().c_str()); ImGui::PopTextWrapPos(); - // icon (>) to open player - if ( s.playable() ) { - ImVec2 pos = ImGui::GetCursorPos(); - ImGui::SameLine(0, 0); - ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); - if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) - UserInterface::manager().showSourceEditor(&s); - ImGui::SetCursorPos(pos); + if ( !s.failed() ) { + // icon (>) to open player + if ( s.playable() ) { + ImVec2 pos = ImGui::GetCursorPos(); + ImGui::SameLine(0, 0); + ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); + if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) + UserInterface::manager().showSourceEditor(&s); + ImGui::SetCursorPos(pos); + } } + else + info.reset(); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); if (ImGui::BeginCombo("Device", s.device().c_str())) @@ -1152,21 +1165,25 @@ void ImGuiVisitor::visit (NetworkSource& s) ImGui::Text("%s", info.str().c_str()); ImGui::PopTextWrapPos(); - // icon (>) to open player - if ( s.playable() ) { - ImVec2 pos = ImGui::GetCursorPos(); - ImGui::SameLine(0, 0); - ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); - if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) - UserInterface::manager().showSourceEditor(&s); - ImGui::SetCursorPos(pos); + if ( !s.failed() ) { + // icon (>) to open player + if ( s.playable() ) { + ImVec2 pos = ImGui::GetCursorPos(); + ImGui::SameLine(0, 0); + ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); + if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) + UserInterface::manager().showSourceEditor(&s); + ImGui::SetCursorPos(pos); + } } - - if ( ImGui::Button( ICON_FA_REPLY " Reconnect", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) - { - s.setConnection(s.connection()); + else info.reset(); - } + +// if ( ImGui::Button( ICON_FA_REPLY " Reconnect", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) +// { +// s.setConnection(s.connection()); +// info.reset(); +// } } @@ -1180,54 +1197,59 @@ void ImGuiVisitor::visit (MultiFileSource& s) ImGui::Text("%s", info.str().c_str()); ImGui::PopTextWrapPos(); - // icon (>) to open player - if ( s.playable() ) { - ImVec2 pos = ImGui::GetCursorPos(); - ImGui::SameLine(0, 0); - ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); - if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) - UserInterface::manager().showSourceEditor(&s); - ImGui::SetCursorPos(pos); - } + if ( !s.failed() ) { - // Filename pattern - ImGuiTextBuffer info; - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.14f, 0.14f, 0.14f, 0.9f)); - info.appendf("%s", SystemToolkit::base_filename(s.sequence().location).c_str()); - ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - ImGui::InputText("Filenames", (char *)info.c_str(), info.size(), ImGuiInputTextFlags_ReadOnly); - ImGui::PopStyleColor(1); + // icon (>) to open player + if ( s.playable() ) { + ImVec2 pos = ImGui::GetCursorPos(); + ImGui::SameLine(0, 0); + ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); + if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) + UserInterface::manager().showSourceEditor(&s); + ImGui::SetCursorPos(pos); + } - // change range - static int _begin = -1; - if (_begin < 0 || id != s.id()) - _begin = s.begin(); - static int _end = -1; - if (_end < 0 || id != s.id()) - _end = s.end(); - ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - ImGui::DragIntRange2("Range", &_begin, &_end, 1, s.sequence().min, s.sequence().max); - if (ImGui::IsItemDeactivatedAfterEdit()){ - s.setRange( _begin, _end ); - std::ostringstream oss; - oss << s.name() << ": Range " << _begin << "-" << _end; - Action::manager().store(oss.str()); - _begin = _end = -1; - } + // Filename pattern + ImGuiTextBuffer info; + ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.14f, 0.14f, 0.14f, 0.9f)); + info.appendf("%s", SystemToolkit::base_filename(s.sequence().location).c_str()); + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + ImGui::InputText("Filenames", (char *)info.c_str(), info.size(), ImGuiInputTextFlags_ReadOnly); + ImGui::PopStyleColor(1); - // change framerate - static int _fps = -1; - if (_fps < 0 || id != s.id()) - _fps = s.framerate(); - ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); - ImGui::SliderInt("Framerate", &_fps, 1, 30, "%d fps"); - if (ImGui::IsItemDeactivatedAfterEdit()){ - s.setFramerate(_fps); - std::ostringstream oss; - oss << s.name() << ": Framerate " << _fps << " fps"; - Action::manager().store(oss.str()); - _fps = -1; + // change range + static int _begin = -1; + if (_begin < 0 || id != s.id()) + _begin = s.begin(); + static int _end = -1; + if (_end < 0 || id != s.id()) + _end = s.end(); + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + ImGui::DragIntRange2("Range", &_begin, &_end, 1, s.sequence().min, s.sequence().max); + if (ImGui::IsItemDeactivatedAfterEdit()){ + s.setRange( _begin, _end ); + std::ostringstream oss; + oss << s.name() << ": Range " << _begin << "-" << _end; + Action::manager().store(oss.str()); + _begin = _end = -1; + } + + // change framerate + static int _fps = -1; + if (_fps < 0 || id != s.id()) + _fps = s.framerate(); + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + ImGui::SliderInt("Framerate", &_fps, 1, 30, "%d fps"); + if (ImGui::IsItemDeactivatedAfterEdit()){ + s.setFramerate(_fps); + std::ostringstream oss; + oss << s.name() << ": Framerate " << _fps << " fps"; + Action::manager().store(oss.str()); + _fps = -1; + } } + else + info.reset(); // offer to open file browser at location std::string path = SystemToolkit::path_filename(s.sequence().location); @@ -1251,15 +1273,19 @@ void ImGuiVisitor::visit (GenericStreamSource& s) ImGui::Text("%s", info.str().c_str()); ImGui::PopTextWrapPos(); - // icon (>) to open player - if ( s.playable() ) { - ImVec2 pos = ImGui::GetCursorPos(); - ImGui::SameLine(0, 0); - ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); - if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) - UserInterface::manager().showSourceEditor(&s); - ImGui::SetCursorPos(pos); + if ( !s.failed() ) { + // icon (>) to open player + if ( s.playable() ) { + ImVec2 pos = ImGui::GetCursorPos(); + ImGui::SameLine(0, 0); + ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); + if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) + UserInterface::manager().showSourceEditor(&s); + ImGui::SetCursorPos(pos); + } } + else + info.reset(); // Prepare display pipeline text static int numlines = 0; @@ -1284,15 +1310,19 @@ void ImGuiVisitor::visit (SrtReceiverSource& s) ImGui::Text("%s", info.str().c_str()); ImGui::PopTextWrapPos(); - // icon (>) to open player - if ( s.playable() ) { - ImVec2 pos = ImGui::GetCursorPos(); - ImGui::SameLine(0, 0); - ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); - if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) - UserInterface::manager().showSourceEditor(&s); - ImGui::SetCursorPos(pos); + if ( !s.failed() ) { + // icon (>) to open player + if ( s.playable() ) { + ImVec2 pos = ImGui::GetCursorPos(); + ImGui::SameLine(0, 0); + ImGui::SameLine(0, IMGUI_SAME_LINE + ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN); + if (ImGuiToolkit::IconButton(ICON_FA_PLAY_CIRCLE, "Open in Player")) + UserInterface::manager().showSourceEditor(&s); + ImGui::SetCursorPos(pos); + } } + else + info.reset(); // if ( ImGui::Button( ICON_FA_REPLY " Reconnect", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) // { diff --git a/src/InfoVisitor.cpp b/src/InfoVisitor.cpp index de40043..1aa86dd 100644 --- a/src/InfoVisitor.cpp +++ b/src/InfoVisitor.cpp @@ -27,15 +27,8 @@ #include #include -#include -#include "tinyxml2Toolkit.h" -#include "defines.h" -#include "Log.h" #include "Scene.h" -#include "Primitives.h" -#include "ImageShader.h" -#include "ImageProcessingShader.h" #include "MediaPlayer.h" #include "MediaSource.h" #include "CloneSource.h" @@ -46,13 +39,8 @@ #include "NetworkSource.h" #include "SrtReceiverSource.h" #include "MultiFileSource.h" -#include "SessionCreator.h" -#include "SessionVisitor.h" -#include "Settings.h" -#include "Mixer.h" -#include "ActionManager.h" +#include "Session.h" #include "BaseToolkit.h" -#include "UserInterfaceManager.h" #include "SystemToolkit.h" #include "InfoVisitor.h" @@ -102,19 +90,24 @@ void InfoVisitor::visit(MediaPlayer &mp) return; std::ostringstream oss; - if (brief_) { - oss << SystemToolkit::filename(mp.filename()) << std::endl; - oss << mp.media().codec_name.substr(0, mp.media().codec_name.find_first_of(" (,")) << ", "; - oss << mp.width() << " x " << mp.height(); - if (!mp.isImage()) - oss << ", " << std::fixed << std::setprecision(0) << mp.frameRate() << "fps"; + if (mp.failed()) { + oss << mp.filename() << std::endl << mp.log(); } else { - oss << mp.filename() << std::endl; - oss << mp.media().codec_name << std::endl; - oss << mp.width() << " x " << mp.height() ; - if (!mp.isImage()) - oss << ", " << std::fixed << std::setprecision(1) << mp.frameRate() << " fps"; + if (brief_) { + oss << SystemToolkit::filename(mp.filename()) << std::endl; + oss << mp.media().codec_name.substr(0, mp.media().codec_name.find_first_of(" (,")) << ", "; + oss << mp.width() << " x " << mp.height(); + if (!mp.isImage() && mp.frameRate() > 0.) + oss << ", " << std::fixed << std::setprecision(0) << mp.frameRate() << " fps"; + } + else { + oss << mp.filename() << std::endl; + oss << mp.media().codec_name << std::endl; + oss << mp.width() << " x " << mp.height() ; + if (!mp.isImage() && mp.frameRate() > 0.) + oss << ", " << std::fixed << std::setprecision(1) << mp.frameRate() << " fps"; + } } information_ = oss.str(); @@ -139,7 +132,12 @@ void InfoVisitor::visit(Stream &n) void InfoVisitor::visit (MediaSource& s) { + if (current_id_ == s.id()) + return; + s.mediaplayer()->accept(*this); + + current_id_ = s.id(); } void InfoVisitor::visit (SessionFileSource& s) @@ -254,16 +252,24 @@ void InfoVisitor::visit (PatternSource& s) return; std::ostringstream oss; - if (s.pattern()) { - if (brief_) { - oss << "RGBA, " << s.pattern()->width() << " x " << s.pattern()->height(); - } + + Pattern *ptn = s.pattern(); + if (ptn) { + if (ptn->failed()) + oss << ptn->description() << std::endl << ptn->log(); else { - oss << Pattern::get(s.pattern()->type()).label << " pattern" << std::endl; - oss << "RGBA" << std::endl; - oss << s.pattern()->width() << " x " << s.pattern()->height(); + if (brief_) { + oss << "RGBA, " << ptn->width() << " x " << ptn->height(); + } + else { + oss << Pattern::get(ptn->type()).label << " pattern" << std::endl; + oss << "RGBA" << std::endl; + oss << ptn->width() << " x " << ptn->height(); + } } } + else + oss << "Undefined"; information_ = oss.str(); current_id_ = s.id(); @@ -294,6 +300,9 @@ void InfoVisitor::visit (DeviceSource& s) oss << std::fixed << std::setprecision(1) << fps << " fps"; } } + else { + oss << s.device() << " not available."; + } information_ = oss.str(); current_id_ = s.id(); @@ -304,20 +313,29 @@ void InfoVisitor::visit (NetworkSource& s) if (current_id_ == s.id()) return; - NetworkStream *ns = s.networkStream(); + std::ostringstream oss; - std::ostringstream oss; - if (brief_) { - oss << NetworkToolkit::stream_protocol_label[ns->protocol()] << std::endl; - oss << "IP " << ns->serverAddress() << std::endl; - oss << ns->resolution().x << " x " << ns->resolution().y; - } - else { - oss << s.connection() << std::endl; - oss << NetworkToolkit::stream_protocol_label[ns->protocol()]; - oss << " shared from IP " << ns->serverAddress() << std::endl; - oss << ns->resolution().x << " x " << ns->resolution().y; + NetworkStream *ns = s.networkStream(); + if (ns) { + if (ns->failed()) { + oss << s.stream()->log(); + } + else { + if (brief_) { + oss << NetworkToolkit::stream_protocol_label[ns->protocol()] << std::endl; + oss << "IP " << ns->serverAddress() << std::endl; + oss << ns->resolution().x << " x " << ns->resolution().y; + } + else { + oss << s.connection() << std::endl; + oss << NetworkToolkit::stream_protocol_label[ns->protocol()]; + oss << " shared from IP " << ns->serverAddress() << std::endl; + oss << ns->resolution().x << " x " << ns->resolution().y; + } + } } + else + oss << "Undefined"; information_ = oss.str(); current_id_ = s.id(); @@ -330,18 +348,26 @@ void InfoVisitor::visit (MultiFileSource& s) return; std::ostringstream oss; - if (brief_) { - oss << s.sequence().max - s.sequence().min + 1 << " images ["; - oss << s.sequence().min << " - " << s.sequence().max << "]" << std::endl; - oss << s.sequence().codec << ", "; - oss << s.sequence().width << " x " << s.sequence().height; - } - else { - oss << s.sequence().location << " ["; - oss << s.sequence().min << " - " << s.sequence().max << "]" << std::endl; - oss << s.sequence().max - s.sequence().min + 1 << " "; - oss << s.sequence().codec << " images" << std::endl; - oss << s.sequence().width << " x " << s.sequence().height << ", " << s.framerate() << " fps"; + + if (s.stream()) { + if (s.stream()->failed()) { + oss << s.sequence().location << std::endl << s.stream()->log(); + } + else { + if (brief_) { + oss << s.sequence().max - s.sequence().min + 1 << " images ["; + oss << s.sequence().min << " - " << s.sequence().max << "]" << std::endl; + oss << s.sequence().codec << ", "; + oss << s.sequence().width << " x " << s.sequence().height; + } + else { + oss << s.sequence().location << " ["; + oss << s.sequence().min << " - " << s.sequence().max << "]" << std::endl; + oss << s.sequence().max - s.sequence().min + 1 << " "; + oss << s.sequence().codec << " images" << std::endl; + oss << s.sequence().width << " x " << s.sequence().height << ", " << s.framerate() << " fps"; + } + } } information_ = oss.str(); @@ -354,18 +380,25 @@ void InfoVisitor::visit (GenericStreamSource& s) return; std::ostringstream oss; - if (s.stream()) { - std::string src_element = s.gstElements().front(); - if (brief_) { - src_element = src_element.substr(0, src_element.find(" ")); - oss << "gstreamer '" << src_element << "'" << std::endl; - oss << "RGBA, " << s.stream()->width() << " x " << s.stream()->height(); + Stream *stm = s.stream(); + if (stm) { + if (stm->failed()) { + oss << stm->log(); } else { - oss << "gstreamer '" << src_element << "'" << std::endl; - oss << "RGBA" << std::endl; - oss << s.stream()->width() << " x " << s.stream()->height(); + std::string src_element = s.gstElements().front(); + + if (brief_) { + src_element = src_element.substr(0, src_element.find(" ")); + oss << "gstreamer '" << src_element << "'" << std::endl; + oss << "RGBA, " << stm->width() << " x " << stm->height(); + } + else { + oss << "gstreamer '" << src_element << "'" << std::endl; + oss << "RGBA" << std::endl; + oss << stm->width() << " x " << stm->height(); + } } } else @@ -382,13 +415,19 @@ void InfoVisitor::visit (SrtReceiverSource& s) std::ostringstream oss; - if (s.stream()) { - if (brief_) - oss << s.uri() << std::endl; + Stream *stm = s.stream(); + if (stm) { + if (stm->failed()) { + oss << s.uri() << std::endl << stm->log(); + } else { - oss << "SRT Receiver " << s.uri() << std::endl; - oss << "H264 (" << s.stream()->decoderName() << ")" << std::endl; - oss << s.stream()->width() << " x " << s.stream()->height(); + if (brief_) + oss << s.uri() << std::endl; + else { + oss << "SRT Receiver " << s.uri() << std::endl; + oss << "H264 (" << stm->decoderName() << ")" << std::endl; + oss << stm->width() << " x " << stm->height(); + } } } else diff --git a/src/MediaPlayer.cpp b/src/MediaPlayer.cpp index 96a418f..820ab3e 100644 --- a/src/MediaPlayer.cpp +++ b/src/MediaPlayer.cpp @@ -137,22 +137,22 @@ MediaInfo MediaPlayer::UriDiscoverer(const std::string &uri) GstDiscovererResult result = gst_discoverer_info_get_result (info); switch (result) { case GST_DISCOVERER_URI_INVALID: - Log::Warning("'%s': Invalid URI", uri.c_str()); + video_stream_info.log = "Invalid URI"; break; case GST_DISCOVERER_ERROR: - Log::Warning("'%s': %s", uri.c_str(), err->message); + video_stream_info.log = err->message; break; case GST_DISCOVERER_TIMEOUT: - Log::Warning("'%s': Timeout loading", uri.c_str()); + video_stream_info.log = "Timeout loading"; break; case GST_DISCOVERER_BUSY: - Log::Warning("'%s': Busy", uri.c_str()); + video_stream_info.log = "Busy"; break; case GST_DISCOVERER_MISSING_PLUGINS: { const GstStructure *s = gst_discoverer_info_get_misc (info); gchar *str = gst_structure_to_string (s); - Log::Info("'%s': Unknown file format (%s)", uri.c_str(), str); + video_stream_info.log = "Unknown format " + std::string(str); g_free (str); } break; @@ -218,10 +218,10 @@ MediaInfo MediaPlayer::UriDiscoverer(const std::string &uri) } if (!video_stream_info.valid) - Log::Warning("'%s': Invalid video stream", uri.c_str()); + video_stream_info.log = "Invalid video stream"; } else - Log::Warning("'%s': No video stream", uri.c_str()); + video_stream_info.log = "No video stream"; gst_discoverer_stream_info_list_free(streams); } @@ -929,7 +929,8 @@ void MediaPlayer::update() execute_open(); } else { - Log::Warning("MediaPlayer %s Loading cancelled", std::to_string(id_).c_str()); + Log::Warning("'%s' : %s", uri().c_str(), media_.log.c_str()); + Log::Warning("MediaPlayer %s Loading failed.", std::to_string(id_).c_str()); failed_ = true; } } diff --git a/src/MediaPlayer.h b/src/MediaPlayer.h index 0299c64..ba1a389 100644 --- a/src/MediaPlayer.h +++ b/src/MediaPlayer.h @@ -36,40 +36,22 @@ struct MediaInfo { bool valid; GstClockTime dt; GstClockTime end; + std::string log; MediaInfo() { - width = par_width = 640; - height = 480; + width = par_width = 1; + height = 1; bitrate = 0; - framerate_n = 1; - framerate_d = 25; - codec_name = ""; + framerate_n = 0; + framerate_d = 1; + codec_name = "Undefined"; isimage = false; interlaced = false; seekable = false; valid = false; dt = GST_CLOCK_TIME_NONE; end = GST_CLOCK_TIME_NONE; - } - - inline MediaInfo& operator = (const MediaInfo& b) - { - if (this != &b) { - this->dt = b.dt; - this->end = b.end; - this->width = b.width; - this->par_width = b.par_width; - this->height = b.height; - this->bitrate = b.bitrate; - this->framerate_n = b.framerate_n; - this->framerate_d = b.framerate_d; - this->codec_name = b.codec_name; - this->valid = b.valid; - this->isimage = b.isimage; - this->interlaced = b.interlaced; - this->seekable = b.seekable; - } - return *this; + log = ""; } }; @@ -283,6 +265,7 @@ public: static std::list::const_iterator end() { return registered_.cend(); } static MediaInfo UriDiscoverer(const std::string &uri); + std::string log() const { return media_.log; } private: diff --git a/src/MultiFileSource.cpp b/src/MultiFileSource.cpp index f7c0583..d3a928d 100644 --- a/src/MultiFileSource.cpp +++ b/src/MultiFileSource.cpp @@ -20,9 +20,6 @@ #include #include -#include "defines.h" -#include "ImageShader.h" -#include "Resource.h" #include "Decorations.h" #include "Stream.h" #include "Visitor.h" @@ -77,20 +74,6 @@ bool MultiFileSequence::valid() const return !( location.empty() || codec.empty() || width < 1 || height < 1 || max == min); } -MultiFileSequence& MultiFileSequence::operator = (const MultiFileSequence& b) -{ - if (this != &b) { - this->width = b.width; - this->height = b.height; - this->min = b.min; - this->max = b.max; - this->location = b.location; - this->codec = b.codec; - } - return *this; -} - - bool MultiFileSequence::operator != (const MultiFileSequence& b) { return ( location != b.location || codec != b.codec || width != b.width || @@ -104,8 +87,11 @@ MultiFile::MultiFile() : Stream(), src_(nullptr) void MultiFile::open (const MultiFileSequence &sequence, uint framerate ) { - if (sequence.location.empty()) + std::string path = SystemToolkit::path_filename( sequence.location ); + if (!SystemToolkit::file_exists(path) ) { + fail("Invalid path."); return; + } std::ostringstream gstreamer_pipeline; gstreamer_pipeline << "multifilesrc name=src location=\""; diff --git a/src/MultiFileSource.h b/src/MultiFileSource.h index 7aa63e0..777d735 100644 --- a/src/MultiFileSource.h +++ b/src/MultiFileSource.h @@ -17,7 +17,6 @@ struct MultiFileSequence { MultiFileSequence (); MultiFileSequence (const std::list &list_files); bool valid () const; - MultiFileSequence& operator = (const MultiFileSequence& b); bool operator != (const MultiFileSequence& b); }; diff --git a/src/NetworkSource.cpp b/src/NetworkSource.cpp index e0300ab..be4d57a 100644 --- a/src/NetworkSource.cpp +++ b/src/NetworkSource.cpp @@ -123,8 +123,7 @@ void NetworkStream::connect(const std::string &nameconnection) // refuse self referencing if (nameconnection.compare(Connection::manager().info().name) == 0) { - Log::Warning("Cannot create self-referencing Network Source '%s'", nameconnection.c_str()); - failed_ = true; + fail("Cannot create self-referencing Network Source " + nameconnection); return; } @@ -133,8 +132,7 @@ void NetworkStream::connect(const std::string &nameconnection) // Nope, cannot connect to unknown connection if (streamer_index < 0) { - Log::Warning("Cannot connect to %s: please make sure %s is active on this machine.", nameconnection.c_str(), APP_NAME); - failed_ = true; + fail("Cannot connect to " + nameconnection + ". Please make sure vimix is active on this machine"); return; } @@ -159,8 +157,7 @@ void NetworkStream::connect(const std::string &nameconnection) } } if (receiver_ == nullptr) { - Log::Notify("Cannot establish connection with %s. Please check your network.", streamer_.name.c_str()); - failed_ = true; + fail("Cannot establish connection with " + streamer_.name + ". Please check your network."); return; } @@ -191,6 +188,7 @@ void NetworkStream::disconnect() { // receiver should not be active anyway, make sure it is deleted if (receiver_) { + receiver_->AsynchronousBreak(); delete receiver_; receiver_ = nullptr; } @@ -297,8 +295,7 @@ void NetworkStream::update() } } else { - Log::Warning("Connection was rejected by %s.\nMake sure Sharing on local network is enabled and try again.", streamer_.name.c_str()); - failed_=true; + fail("Connection was rejected by " + streamer_.name + ".\nMake sure Sharing on local network is enabled and try again."); } } } diff --git a/src/NetworkSource.h b/src/NetworkSource.h index 8da318b..0ece9d5 100644 --- a/src/NetworkSource.h +++ b/src/NetworkSource.h @@ -5,11 +5,9 @@ #include "Connection.h" #include "StreamSource.h" - class NetworkStream : public Stream { public: - NetworkStream(); void connect(const std::string &nameconnection); diff --git a/src/Stream.cpp b/src/Stream.cpp index 2d0dbcb..2f64994 100644 --- a/src/Stream.cpp +++ b/src/Stream.cpp @@ -23,11 +23,9 @@ // Desktop OpenGL function loader #include -#include "defines.h" #include "Log.h" #include "Resource.h" #include "Visitor.h" -#include "SystemToolkit.h" #include "BaseToolkit.h" #include "GstToolkit.h" @@ -192,8 +190,10 @@ StreamInfo StreamDiscoverer(const std::string &description, guint w, guint h) gst_object_unref (_pipeline); } - else + else { info.message = error->message; + g_clear_error (&error); + } } // at this point, the info should be filled return info; @@ -312,7 +312,8 @@ void Stream::execute_open() void Stream::fail(const std::string &message) { - Log::Warning("Stream %s %s.", std::to_string(id_).c_str(), message.c_str() ); + log_ = message; + Log::Warning("Stream %s %s.", std::to_string(id_).c_str(), log_.c_str() ); failed_ = true; } @@ -878,8 +879,6 @@ GstFlowReturn Stream::callback_new_sample (GstAppSink *sink, gpointer p) return ret; } - - Stream::TimeCounter::TimeCounter(): fps(1.f) { timer = g_timer_new (); diff --git a/src/Stream.h b/src/Stream.h index c416c77..591ad22 100644 --- a/src/Stream.h +++ b/src/Stream.h @@ -143,12 +143,17 @@ public: * NB: perform request on pipeline on first call * */ std::string decoderName(); + /** + * Get logs + * */ + std::string log() const { return log_; } /** * Accept visitors * Used for saving session file * */ void accept(Visitor& v); + protected: // video player description @@ -220,6 +225,7 @@ protected: // gst pipeline control virtual void execute_open(); virtual void fail(const std::string &message); + std::string log_; // gst frame filling bool textureinitialized_; diff --git a/src/StreamSource.cpp b/src/StreamSource.cpp index c48c03f..aca0d35 100644 --- a/src/StreamSource.cpp +++ b/src/StreamSource.cpp @@ -21,8 +21,6 @@ #include #include -#include "defines.h" -#include "ImageShader.h" #include "Resource.h" #include "Decorations.h" #include "Stream.h" diff --git a/src/Streamer.cpp b/src/Streamer.cpp index 65c3424..fb30e17 100644 --- a/src/Streamer.cpp +++ b/src/Streamer.cpp @@ -36,10 +36,8 @@ #include "Settings.h" #include "GstToolkit.h" -#include "defines.h" #include "SystemToolkit.h" #include "Session.h" -#include "FrameBuffer.h" #include "Log.h" #include "Connection.h" #include "NetworkToolkit.h" diff --git a/src/UserInterfaceManager.cpp b/src/UserInterfaceManager.cpp index 12382f4..3b8f83d 100644 --- a/src/UserInterfaceManager.cpp +++ b/src/UserInterfaceManager.cpp @@ -6311,7 +6311,7 @@ void Navigator::Render() // ignore source if failed (managed in stash below) if (s->failed()){ - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.f, 0.3f, 0.2f, 1.f)); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_FAILED, 1.)); ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetColorU32(ImGuiCol_Button)); ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImGui::GetColorU32(ImGuiCol_ButtonActive)); ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImGui::GetColorU32(ImGuiCol_ButtonHovered)); diff --git a/src/defines.h b/src/defines.h index 579af55..27deead 100644 --- a/src/defines.h +++ b/src/defines.h @@ -89,6 +89,7 @@ #define IMGUI_COLOR_BROADCAST 1.0, 0.9, 0.3 #define IMGUI_NOTIFICATION_DURATION 2.5f #define IMGUI_TOOLTIP_TIMEOUT 80 +#define IMGUI_COLOR_FAILED 1.0, 0.3, 0.2 #define COLOR_BGROUND 0.2f, 0.2f, 0.2f #define COLOR_NAVIGATOR 0.1f, 0.1f, 0.1f