BugFix Improved Stream close (async)

Unified mechanism for async close of pipeline for stream and mediaplayer
This commit is contained in:
Bruno Herbelin
2024-02-02 17:04:56 +01:00
parent 842247de54
commit 2e0732c75b
2 changed files with 39 additions and 15 deletions

View File

@@ -490,6 +490,9 @@ void MediaPlayer::execute_open()
opened_ = true; opened_ = true;
// keep name in pipeline
gst_element_set_name(pipeline_, std::to_string(id_).c_str());
// register media player // register media player
MediaPlayer::registered_.push_back(this); MediaPlayer::registered_.push_back(this);
} }
@@ -658,6 +661,9 @@ void MediaPlayer::execute_open()
opened_ = true; opened_ = true;
// keep name in pipeline
gst_element_set_name(pipeline_, std::to_string(id_).c_str());
// register media player // register media player
MediaPlayer::registered_.push_back(this); MediaPlayer::registered_.push_back(this);
} }
@@ -707,8 +713,12 @@ void MediaPlayer::Frame::unmap()
void delayed_terminate( GstElement *p ) void delayed_terminate( GstElement *p )
{ {
#ifdef MEDIA_PLAYER_DEBUG
Log::Info("MediaPlayer %s closed", gst_element_get_name(p));
#endif
// end pipeline // end pipeline
gst_element_set_state ( p, GST_STATE_NULL); gst_element_set_state (p, GST_STATE_NULL);
// unref to free pipeline // unref to free pipeline
gst_object_unref ( p ); gst_object_unref ( p );
@@ -755,11 +765,6 @@ void MediaPlayer::close()
write_index_ = 0; write_index_ = 0;
last_index_ = 0; last_index_ = 0;
#ifdef MEDIA_PLAYER_DEBUG
Log::Info("MediaPlayer %s closed", std::to_string(id_).c_str());
#endif
// unregister media player // unregister media player
MediaPlayer::registered_.remove(this); MediaPlayer::registered_.remove(this);
} }

View File

@@ -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_); Log::Info("Stream %s Opened '%s' (%d x %d)", std::to_string(id_).c_str(), description.c_str(), width_, height_);
opened_ = true; 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 // launch a timeout to check on open status
std::thread( timeout_initialize, this ).detach(); std::thread( timeout_initialize, this ).detach();
} }
@@ -344,6 +347,27 @@ void Stream::Frame::unmap()
full = false; 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() void Stream::close()
{ {
// not opened? // not opened?
@@ -360,15 +384,10 @@ void Stream::close()
// clean up GST // clean up GST
if (pipeline_ != nullptr) { if (pipeline_ != nullptr) {
// force flush
gst_element_send_event(pipeline_, gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, // end pipeline asynchronously
GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_END, 0) ); std::thread(async_terminate, pipeline_).detach();
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_);
pipeline_ = nullptr; pipeline_ = nullptr;
} }