From 2e0732c75b5fc7bd3c9c1d25a3ffef83f7caddd5 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Fri, 2 Feb 2024 17:04:56 +0100 Subject: [PATCH] BugFix Improved Stream close (async) Unified mechanism for async close of pipeline for stream and mediaplayer --- src/MediaPlayer.cpp | 17 +++++++++++------ src/Stream.cpp | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/MediaPlayer.cpp b/src/MediaPlayer.cpp index caff080..9d39e38 100644 --- a/src/MediaPlayer.cpp +++ b/src/MediaPlayer.cpp @@ -490,6 +490,9 @@ void MediaPlayer::execute_open() opened_ = true; + // keep name in pipeline + gst_element_set_name(pipeline_, std::to_string(id_).c_str()); + // register media player MediaPlayer::registered_.push_back(this); } @@ -658,6 +661,9 @@ void MediaPlayer::execute_open() opened_ = true; + // keep name in pipeline + gst_element_set_name(pipeline_, std::to_string(id_).c_str()); + // register media player MediaPlayer::registered_.push_back(this); } @@ -707,8 +713,12 @@ void MediaPlayer::Frame::unmap() void delayed_terminate( GstElement *p ) { +#ifdef MEDIA_PLAYER_DEBUG + Log::Info("MediaPlayer %s closed", gst_element_get_name(p)); +#endif + // end pipeline - gst_element_set_state ( p, GST_STATE_NULL); + gst_element_set_state (p, GST_STATE_NULL); // unref to free pipeline gst_object_unref ( p ); @@ -755,11 +765,6 @@ void MediaPlayer::close() write_index_ = 0; last_index_ = 0; - -#ifdef MEDIA_PLAYER_DEBUG - Log::Info("MediaPlayer %s closed", std::to_string(id_).c_str()); -#endif - // unregister media player MediaPlayer::registered_.remove(this); } diff --git a/src/Stream.cpp b/src/Stream.cpp index fc1be26..155c07e 100644 --- a/src/Stream.cpp +++ b/src/Stream.cpp @@ -306,6 +306,9 @@ void Stream::execute_open() Log::Info("Stream %s Opened '%s' (%d x %d)", std::to_string(id_).c_str(), description.c_str(), width_, height_); opened_ = true; + // keep name in pipeline + gst_element_set_name(pipeline_, std::to_string(id_).c_str()); + // launch a timeout to check on open status std::thread( timeout_initialize, this ).detach(); } @@ -344,6 +347,27 @@ void Stream::Frame::unmap() full = false; } + +void async_terminate( GstElement *p ) +{ +#ifdef STREAM_DEBUG + Log::Info("Stream %s closed", gst_element_get_name(p)); +#endif + + // force flush + gst_element_send_event(p, gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, + GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_END, 0) ); + gst_element_get_state (p, NULL, NULL, 1000000); + + // force end + GstStateChangeReturn ret = gst_element_set_state (p, GST_STATE_NULL); + if (ret == GST_STATE_CHANGE_ASYNC) + gst_element_get_state (p, NULL, NULL, 1000000); + + // unref to free pipeline + gst_object_unref ( p ); +} + void Stream::close() { // not opened? @@ -360,15 +384,10 @@ void Stream::close() // clean up GST if (pipeline_ != nullptr) { - // force flush - gst_element_send_event(pipeline_, gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, - GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_END, 0) ); - gst_element_get_state (pipeline_, NULL, NULL, 1000000); - // force end - GstStateChangeReturn ret = gst_element_set_state (pipeline_, GST_STATE_NULL); - if (ret == GST_STATE_CHANGE_ASYNC) - gst_element_get_state (pipeline_, NULL, NULL, 1000000); - gst_object_unref (pipeline_); + + // end pipeline asynchronously + std::thread(async_terminate, pipeline_).detach(); + pipeline_ = nullptr; }