mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Added mechanisms to detect when a source failed, and to remove it if its
the case.
This commit is contained in:
@@ -36,6 +36,7 @@ MediaPlayer::MediaPlayer(string name) : id_(name)
|
|||||||
discoverer_ = nullptr;
|
discoverer_ = nullptr;
|
||||||
|
|
||||||
ready_ = false;
|
ready_ = false;
|
||||||
|
failed_ = false;
|
||||||
seekable_ = false;
|
seekable_ = false;
|
||||||
isimage_ = false;
|
isimage_ = false;
|
||||||
interlaced_ = false;
|
interlaced_ = false;
|
||||||
@@ -90,6 +91,7 @@ void MediaPlayer::open(string path)
|
|||||||
if (!discoverer_) {
|
if (!discoverer_) {
|
||||||
Log::Warning("MediaPlayer Error creating discoverer instance: %s\n", err->message);
|
Log::Warning("MediaPlayer Error creating discoverer instance: %s\n", err->message);
|
||||||
g_clear_error (&err);
|
g_clear_error (&err);
|
||||||
|
failed_ = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +107,7 @@ void MediaPlayer::open(string path)
|
|||||||
Log::Warning("MediaPlayer %s Failed to start discovering URI '%s'\n", id_.c_str(), uri_.c_str());
|
Log::Warning("MediaPlayer %s Failed to start discovering URI '%s'\n", id_.c_str(), uri_.c_str());
|
||||||
g_object_unref (discoverer_);
|
g_object_unref (discoverer_);
|
||||||
discoverer_ = nullptr;
|
discoverer_ = nullptr;
|
||||||
|
failed_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and wait for discoverer to finish...
|
// and wait for discoverer to finish...
|
||||||
@@ -125,6 +128,7 @@ void MediaPlayer::execute_open()
|
|||||||
if (error != NULL) {
|
if (error != NULL) {
|
||||||
Log::Warning("MediaPlayer %s Could not construct pipeline %s:\n%s", id_.c_str(), description.c_str(), error->message);
|
Log::Warning("MediaPlayer %s Could not construct pipeline %s:\n%s", id_.c_str(), description.c_str(), error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
|
failed_ = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g_object_set(G_OBJECT(pipeline_), "name", id_.c_str(), NULL);
|
g_object_set(G_OBJECT(pipeline_), "name", id_.c_str(), NULL);
|
||||||
@@ -134,6 +138,7 @@ void MediaPlayer::execute_open()
|
|||||||
GstCaps *caps = gst_caps_from_string(capstring.c_str());
|
GstCaps *caps = gst_caps_from_string(capstring.c_str());
|
||||||
if (!gst_video_info_from_caps (&v_frame_video_info_, caps)) {
|
if (!gst_video_info_from_caps (&v_frame_video_info_, caps)) {
|
||||||
Log::Warning("MediaPlayer %s Could not configure video frame info", id_.c_str());
|
Log::Warning("MediaPlayer %s Could not configure video frame info", id_.c_str());
|
||||||
|
failed_ = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,6 +164,7 @@ void MediaPlayer::execute_open()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log::Warning("MediaPlayer %s Could not configure sink", id_.c_str());
|
Log::Warning("MediaPlayer %s Could not configure sink", id_.c_str());
|
||||||
|
failed_ = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
@@ -170,6 +176,7 @@ void MediaPlayer::execute_open()
|
|||||||
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
|
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
|
||||||
if (ret == GST_STATE_CHANGE_FAILURE) {
|
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||||
Log::Warning("MediaPlayer %s Could not open %s", id_.c_str(), uri_.c_str());
|
Log::Warning("MediaPlayer %s Could not open %s", id_.c_str(), uri_.c_str());
|
||||||
|
failed_ = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,6 +190,11 @@ bool MediaPlayer::isOpen() const
|
|||||||
return ready_;
|
return ready_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaPlayer::failed() const
|
||||||
|
{
|
||||||
|
return failed_;
|
||||||
|
}
|
||||||
|
|
||||||
void MediaPlayer::close()
|
void MediaPlayer::close()
|
||||||
{
|
{
|
||||||
// stop discovering stream
|
// stop discovering stream
|
||||||
@@ -284,6 +296,7 @@ void MediaPlayer::play(bool on)
|
|||||||
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
|
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
|
||||||
if (ret == GST_STATE_CHANGE_FAILURE) {
|
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||||
Log::Warning("MediaPlayer %s Failed to start", gst_element_get_name(pipeline_));
|
Log::Warning("MediaPlayer %s Failed to start", gst_element_get_name(pipeline_));
|
||||||
|
failed_ = true;
|
||||||
}
|
}
|
||||||
#ifdef MEDIA_PLAYER_DEBUG
|
#ifdef MEDIA_PLAYER_DEBUG
|
||||||
else if (on)
|
else if (on)
|
||||||
@@ -775,6 +788,7 @@ void MediaPlayer::callback_discoverer_finished(GstDiscoverer *discoverer, MediaP
|
|||||||
else {
|
else {
|
||||||
Log::Warning("MediaPlayer %s Failed to open %s\n%s", m->id_.c_str(), m->uri_.c_str(), m->discoverer_message_.str().c_str());
|
Log::Warning("MediaPlayer %s Failed to open %s\n%s", m->id_.c_str(), m->uri_.c_str(), m->discoverer_message_.str().c_str());
|
||||||
m->discoverer_message_.clear();
|
m->discoverer_message_.clear();
|
||||||
|
m->failed_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,10 @@ public:
|
|||||||
* True if a media was oppenned
|
* True if a media was oppenned
|
||||||
* */
|
* */
|
||||||
bool isOpen() const;
|
bool isOpen() const;
|
||||||
|
/**
|
||||||
|
* True if problem occured
|
||||||
|
* */
|
||||||
|
bool failed() const;
|
||||||
/**
|
/**
|
||||||
* Close the Media
|
* Close the Media
|
||||||
* */
|
* */
|
||||||
@@ -243,6 +247,7 @@ private:
|
|||||||
MediaSegmentSet::iterator current_segment_;
|
MediaSegmentSet::iterator current_segment_;
|
||||||
|
|
||||||
bool ready_;
|
bool ready_;
|
||||||
|
bool failed_;
|
||||||
bool seekable_;
|
bool seekable_;
|
||||||
bool isimage_;
|
bool isimage_;
|
||||||
bool interlaced_;
|
bool interlaced_;
|
||||||
|
|||||||
@@ -142,6 +142,11 @@ MediaPlayer *MediaSource::mediaplayer() const
|
|||||||
return mediaplayer_;
|
return mediaplayer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaSource::failed() const
|
||||||
|
{
|
||||||
|
return mediaplayer_->failed();
|
||||||
|
}
|
||||||
|
|
||||||
void MediaSource::init()
|
void MediaSource::init()
|
||||||
{
|
{
|
||||||
if ( mediaplayer_->isOpen() ) {
|
if ( mediaplayer_->isOpen() ) {
|
||||||
|
|||||||
16
Source.h
16
Source.h
@@ -28,6 +28,9 @@ public:
|
|||||||
inline std::string name () const { return name_; }
|
inline std::string name () const { return name_; }
|
||||||
inline const char *initials() const { return initials_; }
|
inline const char *initials() const { return initials_; }
|
||||||
|
|
||||||
|
// an overlay can be displayed on top of the source
|
||||||
|
virtual void setOverlayVisible(bool on);
|
||||||
|
|
||||||
// get handle on the node used to manipulate the source in a view
|
// get handle on the node used to manipulate the source in a view
|
||||||
inline Group *group(View::Mode m) const { return groups_.at(m); }
|
inline Group *group(View::Mode m) const { return groups_.at(m); }
|
||||||
inline Node *node(View::Mode m) const { return static_cast<Node*>(groups_.at(m)); }
|
inline Node *node(View::Mode m) const { return static_cast<Node*>(groups_.at(m)); }
|
||||||
@@ -44,12 +47,12 @@ public:
|
|||||||
// every Source shall be rendered before draw
|
// every Source shall be rendered before draw
|
||||||
virtual void render() = 0;
|
virtual void render() = 0;
|
||||||
|
|
||||||
// an overlay can be displayed on top of the source
|
|
||||||
virtual void setOverlayVisible(bool on);
|
|
||||||
|
|
||||||
// accept all kind of visitors
|
// accept all kind of visitors
|
||||||
virtual void accept (Visitor& v);
|
virtual void accept (Visitor& v);
|
||||||
|
|
||||||
|
// informs if the source failed (and might have to be deleted)
|
||||||
|
virtual bool failed() const { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// name
|
// name
|
||||||
std::string name_;
|
std::string name_;
|
||||||
@@ -112,9 +115,10 @@ public:
|
|||||||
~MediaSource();
|
~MediaSource();
|
||||||
|
|
||||||
// implementation of source API
|
// implementation of source API
|
||||||
FrameBuffer *frame() const;
|
FrameBuffer *frame() const override;
|
||||||
void render();
|
void render() override;
|
||||||
void accept (Visitor& v);
|
void accept (Visitor& v) override;
|
||||||
|
bool failed() const override;
|
||||||
|
|
||||||
// Media specific interface
|
// Media specific interface
|
||||||
void setPath(const std::string &p);
|
void setPath(const std::string &p);
|
||||||
|
|||||||
@@ -891,6 +891,7 @@ void Navigator::Render()
|
|||||||
// the list of INITIALS for sources
|
// the list of INITIALS for sources
|
||||||
int index = 0;
|
int index = 0;
|
||||||
SourceList::iterator iter;
|
SourceList::iterator iter;
|
||||||
|
Source *source_to_delete = nullptr;
|
||||||
for (iter = Mixer::manager().session()->begin(); iter != Mixer::manager().session()->end(); iter++, index++)
|
for (iter = Mixer::manager().session()->begin(); iter != Mixer::manager().session()->end(); iter++, index++)
|
||||||
{
|
{
|
||||||
// draw an indicator for current source
|
// draw an indicator for current source
|
||||||
@@ -909,7 +910,14 @@ void Navigator::Render()
|
|||||||
if (selected_button[index])
|
if (selected_button[index])
|
||||||
Mixer::manager().setCurrentSource(selected_source_index);
|
Mixer::manager().setCurrentSource(selected_source_index);
|
||||||
}
|
}
|
||||||
|
// delete sources which failed
|
||||||
|
if ( (*iter)->failed() )
|
||||||
|
source_to_delete = *iter;
|
||||||
}
|
}
|
||||||
|
// TODO : general (mixer?) paradigm to delete failed sources (here it looks like a hack)
|
||||||
|
if (source_to_delete != nullptr)
|
||||||
|
Mixer::manager().deleteSource(source_to_delete);
|
||||||
|
|
||||||
// the "+" icon for action of creating new source
|
// the "+" icon for action of creating new source
|
||||||
if (ImGui::Selectable( ICON_FA_PLUS, &selected_button[NAV_NEW], 0, iconsize))
|
if (ImGui::Selectable( ICON_FA_PLUS, &selected_button[NAV_NEW], 0, iconsize))
|
||||||
{
|
{
|
||||||
@@ -1158,15 +1166,15 @@ void Navigator::RenderMainPannel()
|
|||||||
// Bottom aligned
|
// Bottom aligned
|
||||||
ImGui::SetCursorPosY(height - 4.f * ImGui::GetTextLineHeightWithSpacing());
|
ImGui::SetCursorPosY(height - 4.f * ImGui::GetTextLineHeightWithSpacing());
|
||||||
ImGui::Text("About");
|
ImGui::Text("About");
|
||||||
if ( ImGui::Button( " About vimix", ImVec2(pannel_width - padding_width, 0)) )
|
if ( ImGui::Button( ICON_FA_CROW " About vimix", ImVec2(ImGui::GetContentRegionAvail().x, 0)) )
|
||||||
UserInterface::manager().show_about = true;
|
UserInterface::manager().show_about = true;
|
||||||
if ( ImGui::Button("About ImGui"))
|
if ( ImGui::Button("ImGui"))
|
||||||
UserInterface::manager().show_imgui_about = true;
|
UserInterface::manager().show_imgui_about = true;
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if ( ImGui::Button("About GStreamer"))
|
if ( ImGui::Button("GStreamer"))
|
||||||
UserInterface::manager().show_gst_about = true;
|
UserInterface::manager().show_gst_about = true;
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if ( ImGui::Button("About OpenGL"))
|
if ( ImGui::Button("OpenGL", ImVec2(ImGui::GetContentRegionAvail().x, 0)))
|
||||||
UserInterface::manager().show_opengl_about = true;
|
UserInterface::manager().show_opengl_about = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user