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;
|
||||
|
||||
ready_ = false;
|
||||
failed_ = false;
|
||||
seekable_ = false;
|
||||
isimage_ = false;
|
||||
interlaced_ = false;
|
||||
@@ -90,6 +91,7 @@ void MediaPlayer::open(string path)
|
||||
if (!discoverer_) {
|
||||
Log::Warning("MediaPlayer Error creating discoverer instance: %s\n", err->message);
|
||||
g_clear_error (&err);
|
||||
failed_ = true;
|
||||
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());
|
||||
g_object_unref (discoverer_);
|
||||
discoverer_ = nullptr;
|
||||
failed_ = true;
|
||||
}
|
||||
|
||||
// and wait for discoverer to finish...
|
||||
@@ -125,6 +128,7 @@ void MediaPlayer::execute_open()
|
||||
if (error != NULL) {
|
||||
Log::Warning("MediaPlayer %s Could not construct pipeline %s:\n%s", id_.c_str(), description.c_str(), error->message);
|
||||
g_clear_error (&error);
|
||||
failed_ = true;
|
||||
return;
|
||||
}
|
||||
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());
|
||||
if (!gst_video_info_from_caps (&v_frame_video_info_, caps)) {
|
||||
Log::Warning("MediaPlayer %s Could not configure video frame info", id_.c_str());
|
||||
failed_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -159,6 +164,7 @@ void MediaPlayer::execute_open()
|
||||
}
|
||||
else {
|
||||
Log::Warning("MediaPlayer %s Could not configure sink", id_.c_str());
|
||||
failed_ = true;
|
||||
return;
|
||||
}
|
||||
gst_caps_unref (caps);
|
||||
@@ -170,6 +176,7 @@ void MediaPlayer::execute_open()
|
||||
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
|
||||
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||
Log::Warning("MediaPlayer %s Could not open %s", id_.c_str(), uri_.c_str());
|
||||
failed_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -183,6 +190,11 @@ bool MediaPlayer::isOpen() const
|
||||
return ready_;
|
||||
}
|
||||
|
||||
bool MediaPlayer::failed() const
|
||||
{
|
||||
return failed_;
|
||||
}
|
||||
|
||||
void MediaPlayer::close()
|
||||
{
|
||||
// stop discovering stream
|
||||
@@ -284,6 +296,7 @@ void MediaPlayer::play(bool on)
|
||||
GstStateChangeReturn ret = gst_element_set_state (pipeline_, desired_state_);
|
||||
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||
Log::Warning("MediaPlayer %s Failed to start", gst_element_get_name(pipeline_));
|
||||
failed_ = true;
|
||||
}
|
||||
#ifdef MEDIA_PLAYER_DEBUG
|
||||
else if (on)
|
||||
@@ -775,6 +788,7 @@ void MediaPlayer::callback_discoverer_finished(GstDiscoverer *discoverer, MediaP
|
||||
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());
|
||||
m->discoverer_message_.clear();
|
||||
m->failed_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,10 @@ public:
|
||||
* True if a media was oppenned
|
||||
* */
|
||||
bool isOpen() const;
|
||||
/**
|
||||
* True if problem occured
|
||||
* */
|
||||
bool failed() const;
|
||||
/**
|
||||
* Close the Media
|
||||
* */
|
||||
@@ -243,6 +247,7 @@ private:
|
||||
MediaSegmentSet::iterator current_segment_;
|
||||
|
||||
bool ready_;
|
||||
bool failed_;
|
||||
bool seekable_;
|
||||
bool isimage_;
|
||||
bool interlaced_;
|
||||
|
||||
@@ -142,6 +142,11 @@ MediaPlayer *MediaSource::mediaplayer() const
|
||||
return mediaplayer_;
|
||||
}
|
||||
|
||||
bool MediaSource::failed() const
|
||||
{
|
||||
return mediaplayer_->failed();
|
||||
}
|
||||
|
||||
void MediaSource::init()
|
||||
{
|
||||
if ( mediaplayer_->isOpen() ) {
|
||||
|
||||
16
Source.h
16
Source.h
@@ -28,6 +28,9 @@ public:
|
||||
inline std::string name () const { return name_; }
|
||||
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
|
||||
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)); }
|
||||
@@ -44,12 +47,12 @@ public:
|
||||
// every Source shall be rendered before draw
|
||||
virtual void render() = 0;
|
||||
|
||||
// an overlay can be displayed on top of the source
|
||||
virtual void setOverlayVisible(bool on);
|
||||
|
||||
// accept all kind of visitors
|
||||
virtual void accept (Visitor& v);
|
||||
|
||||
// informs if the source failed (and might have to be deleted)
|
||||
virtual bool failed() const { return false; }
|
||||
|
||||
protected:
|
||||
// name
|
||||
std::string name_;
|
||||
@@ -112,9 +115,10 @@ public:
|
||||
~MediaSource();
|
||||
|
||||
// implementation of source API
|
||||
FrameBuffer *frame() const;
|
||||
void render();
|
||||
void accept (Visitor& v);
|
||||
FrameBuffer *frame() const override;
|
||||
void render() override;
|
||||
void accept (Visitor& v) override;
|
||||
bool failed() const override;
|
||||
|
||||
// Media specific interface
|
||||
void setPath(const std::string &p);
|
||||
|
||||
@@ -891,6 +891,7 @@ void Navigator::Render()
|
||||
// the list of INITIALS for sources
|
||||
int index = 0;
|
||||
SourceList::iterator iter;
|
||||
Source *source_to_delete = nullptr;
|
||||
for (iter = Mixer::manager().session()->begin(); iter != Mixer::manager().session()->end(); iter++, index++)
|
||||
{
|
||||
// draw an indicator for current source
|
||||
@@ -909,7 +910,14 @@ void Navigator::Render()
|
||||
if (selected_button[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
|
||||
if (ImGui::Selectable( ICON_FA_PLUS, &selected_button[NAV_NEW], 0, iconsize))
|
||||
{
|
||||
@@ -1158,15 +1166,15 @@ void Navigator::RenderMainPannel()
|
||||
// Bottom aligned
|
||||
ImGui::SetCursorPosY(height - 4.f * ImGui::GetTextLineHeightWithSpacing());
|
||||
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;
|
||||
if ( ImGui::Button("About ImGui"))
|
||||
if ( ImGui::Button("ImGui"))
|
||||
UserInterface::manager().show_imgui_about = true;
|
||||
ImGui::SameLine();
|
||||
if ( ImGui::Button("About GStreamer"))
|
||||
if ( ImGui::Button("GStreamer"))
|
||||
UserInterface::manager().show_gst_about = true;
|
||||
ImGui::SameLine();
|
||||
if ( ImGui::Button("About OpenGL"))
|
||||
if ( ImGui::Button("OpenGL", ImVec2(ImGui::GetContentRegionAvail().x, 0)))
|
||||
UserInterface::manager().show_opengl_about = true;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user