From 0051533ac8273f73147979ae4ec1e7119b08f428 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Sun, 29 Jan 2023 10:50:00 +0100 Subject: [PATCH] Improved management of failed sources Clone is failed if its origin is failed, handle MediaPlayer visitor and error message when fail, get SourceList of non-failed sources of a list. --- src/CloneSource.h | 2 +- src/MediaPlayer.cpp | 118 +++++++++++++++++++++-------------------- src/SessionVisitor.cpp | 3 +- src/Source.h | 1 + src/SourceList.cpp | 12 +++++ src/SourceList.h | 1 + src/TextureView.cpp | 4 ++ 7 files changed, 81 insertions(+), 60 deletions(-) diff --git a/src/CloneSource.h b/src/CloneSource.h index 82d3b90..6585cd2 100644 --- a/src/CloneSource.h +++ b/src/CloneSource.h @@ -22,7 +22,7 @@ public: void replay () override; guint64 playtime () const override; uint texture() const override; - bool failed() const override { return origin_ == nullptr; } + bool failed() const override { return origin_ == nullptr || origin_->failed(); } void accept (Visitor& v) override; void render() override; glm::ivec2 icon() const override; diff --git a/src/MediaPlayer.cpp b/src/MediaPlayer.cpp index df9fcf0..96a418f 100644 --- a/src/MediaPlayer.cpp +++ b/src/MediaPlayer.cpp @@ -157,72 +157,74 @@ MediaInfo MediaPlayer::UriDiscoverer(const std::string &uri) } break; default: - case GST_DISCOVERER_OK: break; } - // get videos in information found - GList *streams = gst_discoverer_info_get_video_streams(info); - if ( g_list_length(streams) > 0) { - GList *tmp; - for (tmp = streams; tmp && !video_stream_info.valid; tmp = tmp->next ) { - GstDiscovererStreamInfo *tmpinf = (GstDiscovererStreamInfo *) tmp->data; - if ( GST_IS_DISCOVERER_VIDEO_INFO(tmpinf) ) - { - // found a video / image stream : fill-in information - GstDiscovererVideoInfo* vinfo = GST_DISCOVERER_VIDEO_INFO(tmpinf); - video_stream_info.width = gst_discoverer_video_info_get_width(vinfo); - video_stream_info.height = gst_discoverer_video_info_get_height(vinfo); - guint parn = gst_discoverer_video_info_get_par_num(vinfo); - guint pard = gst_discoverer_video_info_get_par_denom(vinfo); - video_stream_info.par_width = (video_stream_info.width * parn) / pard; - video_stream_info.interlaced = gst_discoverer_video_info_is_interlaced(vinfo); - video_stream_info.bitrate = gst_discoverer_video_info_get_bitrate(vinfo); - video_stream_info.isimage = gst_discoverer_video_info_is_image(vinfo); - // if its a video, set duration, framerate, etc. - if ( !video_stream_info.isimage ) { - video_stream_info.end = gst_discoverer_info_get_duration (info) ; - video_stream_info.seekable = gst_discoverer_info_get_seekable (info); - video_stream_info.framerate_n = gst_discoverer_video_info_get_framerate_num(vinfo); - video_stream_info.framerate_d = gst_discoverer_video_info_get_framerate_denom(vinfo); - if (video_stream_info.framerate_n == 0 || video_stream_info.framerate_d == 0) { - Log::Info("'%s': No framerate indicated in the file; using default 30fps", uri.c_str()); - video_stream_info.framerate_n = 30; - video_stream_info.framerate_d = 1; + + if ( result == GST_DISCOVERER_OK ) { + // get videos in information found + GList *streams = gst_discoverer_info_get_video_streams(info); + if ( g_list_length(streams) > 0) { + GList *tmp; + for (tmp = streams; tmp && !video_stream_info.valid; tmp = tmp->next ) { + GstDiscovererStreamInfo *tmpinf = (GstDiscovererStreamInfo *) tmp->data; + if ( GST_IS_DISCOVERER_VIDEO_INFO(tmpinf) ) + { + // found a video / image stream : fill-in information + GstDiscovererVideoInfo* vinfo = GST_DISCOVERER_VIDEO_INFO(tmpinf); + video_stream_info.width = gst_discoverer_video_info_get_width(vinfo); + video_stream_info.height = gst_discoverer_video_info_get_height(vinfo); + guint parn = gst_discoverer_video_info_get_par_num(vinfo); + guint pard = gst_discoverer_video_info_get_par_denom(vinfo); + video_stream_info.par_width = (video_stream_info.width * parn) / pard; + video_stream_info.interlaced = gst_discoverer_video_info_is_interlaced(vinfo); + video_stream_info.bitrate = gst_discoverer_video_info_get_bitrate(vinfo); + video_stream_info.isimage = gst_discoverer_video_info_is_image(vinfo); + // if its a video, set duration, framerate, etc. + if ( !video_stream_info.isimage ) { + video_stream_info.end = gst_discoverer_info_get_duration (info) ; + video_stream_info.seekable = gst_discoverer_info_get_seekable (info); + video_stream_info.framerate_n = gst_discoverer_video_info_get_framerate_num(vinfo); + video_stream_info.framerate_d = gst_discoverer_video_info_get_framerate_denom(vinfo); + if (video_stream_info.framerate_n == 0 || video_stream_info.framerate_d == 0) { + Log::Info("'%s': No framerate indicated in the file; using default 30fps", uri.c_str()); + video_stream_info.framerate_n = 30; + video_stream_info.framerate_d = 1; + } + video_stream_info.dt = ( (GST_SECOND * static_cast(video_stream_info.framerate_d)) / (static_cast(video_stream_info.framerate_n)) ); + // confirm (or infirm) that its not a single frame + if ( video_stream_info.end < video_stream_info.dt * 2) + video_stream_info.isimage = true; } - video_stream_info.dt = ( (GST_SECOND * static_cast(video_stream_info.framerate_d)) / (static_cast(video_stream_info.framerate_n)) ); - // confirm (or infirm) that its not a single frame - if ( video_stream_info.end < video_stream_info.dt * 2) - video_stream_info.isimage = true; + // try to fill-in the codec information + GstCaps *caps = gst_discoverer_stream_info_get_caps (tmpinf); + if (caps) { + gchar *codecstring = gst_pb_utils_get_codec_description(caps); + video_stream_info.codec_name = std::string( codecstring ); + g_free(codecstring); + gst_caps_unref (caps); + } + const GstTagList *tags = gst_discoverer_stream_info_get_tags(tmpinf); + if ( tags ) { + gchar *container = NULL; + if ( gst_tag_list_get_string (tags, GST_TAG_CONTAINER_FORMAT, &container) ) + video_stream_info.codec_name += ", " + std::string(container); + if (container) + g_free(container); + } + // exit loop + // inform that it succeeded + video_stream_info.valid = true; } - // try to fill-in the codec information - GstCaps *caps = gst_discoverer_stream_info_get_caps (tmpinf); - if (caps) { - gchar *codecstring = gst_pb_utils_get_codec_description(caps); - video_stream_info.codec_name = std::string( codecstring ); - g_free(codecstring); - gst_caps_unref (caps); - } - const GstTagList *tags = gst_discoverer_stream_info_get_tags(tmpinf); - if ( tags ) { - gchar *container = NULL; - if ( gst_tag_list_get_string (tags, GST_TAG_CONTAINER_FORMAT, &container) ) - video_stream_info.codec_name += ", " + std::string(container); - if (container) - g_free(container); - } - // exit loop - // inform that it succeeded - video_stream_info.valid = true; } + + if (!video_stream_info.valid) + Log::Warning("'%s': Invalid video stream", uri.c_str()); } + else + Log::Warning("'%s': No video stream", uri.c_str()); - if (!video_stream_info.valid) - Log::Warning("'%s': Invalid video stream", uri.c_str()); + gst_discoverer_stream_info_list_free(streams); } - else - Log::Warning("'%s': No supported video stream", uri.c_str()); - - gst_discoverer_stream_info_list_free(streams); if (info) gst_discoverer_info_unref (info); diff --git a/src/SessionVisitor.cpp b/src/SessionVisitor.cpp index 8655b7a..2d58f03 100644 --- a/src/SessionVisitor.cpp +++ b/src/SessionVisitor.cpp @@ -638,7 +638,8 @@ void SessionVisitor::visit (MediaSource& s) if (!sessionFilePath_.empty()) uri->SetAttribute("relative", SystemToolkit::path_relative_to_path(s.path(), sessionFilePath_).c_str()); - s.mediaplayer()->accept(*this); + if (!s.failed()) + s.mediaplayer()->accept(*this); } void SessionVisitor::visit (SessionFileSource& s) diff --git a/src/Source.h b/src/Source.h index fc696f4..9fb31fe 100644 --- a/src/Source.h +++ b/src/Source.h @@ -109,6 +109,7 @@ public: // cloning mechanism virtual CloneSource *clone (uint64_t id = 0); + inline bool cloned() const { return !clones_.empty(); } // Display mode typedef enum { diff --git a/src/SourceList.cpp b/src/SourceList.cpp index b107fe0..6d10308 100644 --- a/src/SourceList.cpp +++ b/src/SourceList.cpp @@ -45,6 +45,18 @@ SourceList playable_only (const SourceList &list) return pl; } + +bool isfailed (const Source *s) { return s->failed(); } + +SourceList valid_only (const SourceList &list) +{ + SourceList pl = list; + + pl.remove_if(isfailed); + + return pl; +} + bool notactive (const Source *s) { return !s->active(); } SourceList active_only (const SourceList &list) diff --git a/src/SourceList.h b/src/SourceList.h index a557425..9ed3fc7 100644 --- a/src/SourceList.h +++ b/src/SourceList.h @@ -12,6 +12,7 @@ typedef std::list SourceList; typedef std::list SourceCoreList; SourceList playable_only (const SourceList &list); +SourceList valid_only (const SourceList &list); SourceList active_only (const SourceList &list); SourceList depth_sorted (const SourceList &list); SourceList mixing_sorted (const SourceList &list, glm::vec2 center = glm::vec2(0.f, 0.f)); diff --git a/src/TextureView.cpp b/src/TextureView.cpp index 01f8968..ed30a3e 100644 --- a/src/TextureView.cpp +++ b/src/TextureView.cpp @@ -508,6 +508,10 @@ Source *TextureView::getEditOrCurrentSource() } } + if (_source != nullptr && _source->failed() ) { + _source = nullptr; + } + return _source; }