BugFix Ensure complete close of session upon termination

Async ending of gst pipeline in stream and media player sources caused a crash at termination as source was still not closed when process was ended. Fix is to ask for an immediate termination of gst pipeline upon delete of stream, and to wait for mixer manager to end current session when clearing.
This commit is contained in:
Bruno Herbelin
2024-02-28 00:39:03 +01:00
parent 1ba8ff06e1
commit 05f593e40c
8 changed files with 33 additions and 27 deletions

View File

@@ -100,7 +100,7 @@ MediaPlayer::MediaPlayer()
MediaPlayer::~MediaPlayer()
{
close();
close(false);
// cleanup opengl texture
if (textureindex_)
@@ -714,9 +714,10 @@ void MediaPlayer::Frame::unmap()
}
void delayed_terminate( GstElement *p )
void pipeline_terminate( GstElement *p )
{
#ifdef MEDIA_PLAYER_DEBUG
g_printerr("MediaPlayer %s close\n", gst_element_get_name(p));
Log::Info("MediaPlayer %s closed", gst_element_get_name(p));
#endif
@@ -727,7 +728,7 @@ void delayed_terminate( GstElement *p )
gst_object_unref ( p );
}
void MediaPlayer::close()
void MediaPlayer::close(bool async)
{
// not opened?
if (!opened_) {
@@ -751,9 +752,12 @@ void MediaPlayer::close()
// clean up GST
if (pipeline_ != nullptr) {
// end pipeline asynchronously
std::thread(delayed_terminate, pipeline_).detach();
if (async)
// end pipeline asynchronously
std::thread(pipeline_terminate, pipeline_).detach();
else
// end pipeline immediately
pipeline_terminate(pipeline_);
pipeline_ = nullptr;
}

View File

@@ -101,7 +101,7 @@ public:
/**
* Close the Media
* */
void close();
void close(bool async = true);
/**
* Update texture with latest frame
* Must be called in rendering update loop

View File

@@ -77,7 +77,7 @@ Mixer::Mixer() : session_(nullptr), back_session_(nullptr), sessionSwapRequested
current_source_index_ = -1;
// initialize with a new empty session
clear();
set( new Session );
setView( View::MIXING );
}
@@ -1580,7 +1580,7 @@ void Mixer::close(bool smooth)
transition_.attach(ts);
}
else
clear();
set( new Session );
// closing session : filename at font in history should not be reloaded
Settings::application.recentSessions.front_is_valid = false;
@@ -1588,18 +1588,18 @@ void Mixer::close(bool smooth)
void Mixer::clear()
{
// delete previous back session if needed
if (back_session_)
garbage_.push_back(back_session_);
// wait finish saving / loading
while (busy())
update();
// create empty session
back_session_ = new Session;
// set for an empty session and update to ensure session is deleted
set(new Session);
while (sessionSwapRequested_ || garbage_.size() > 0)
update();
// swap current with empty
sessionSwapRequested_ = true;
// need to deeply update view to apply eventual changes
++View::need_deep_update_;
// all finished, we can clear the back session we just added
delete back_session_;
back_session_ = nullptr;
}
void Mixer::set(Session *s)

View File

@@ -120,7 +120,7 @@ void MultiFile::execute_open()
src_ = gst_bin_get_by_name (GST_BIN (pipeline_), "src");
}
void MultiFile::close ()
void MultiFile::close (bool)
{
if (src_ != nullptr) {
gst_object_unref (src_);

View File

@@ -25,7 +25,7 @@ class MultiFile : public Stream
public:
MultiFile ();
void open (const MultiFileSequence &sequence, uint framerate = 30);
void close () override;
void close (bool) override;
void rewind () override;
// dynamic change of gstreamer multifile source properties

View File

@@ -73,7 +73,7 @@ Stream::Stream()
Stream::~Stream()
{
Stream::close();
Stream::close(false);
// cleanup opengl texture
if (textureindex_)
@@ -368,7 +368,7 @@ void async_terminate( GstElement *p )
gst_object_unref ( p );
}
void Stream::close()
void Stream::close(bool async)
{
// not opened?
if (!opened_) {
@@ -386,7 +386,10 @@ void Stream::close()
if (pipeline_ != nullptr) {
// end pipeline asynchronously
std::thread(async_terminate, pipeline_).detach();
if (async)
std::thread(async_terminate, pipeline_).detach();
else
async_terminate(pipeline_);
pipeline_ = nullptr;
}

View File

@@ -74,7 +74,7 @@ public:
/**
* Close the Media
* */
virtual void close();
virtual void close(bool async = true);
/**
* Update texture with latest frame
* Must be called in rendering update loop

View File

@@ -248,8 +248,7 @@ int main(int argc, char *argv[])
///
/// MIXER TERMINATE
///
while (Mixer::manager().busy())
Mixer::manager().update();
Mixer::manager().clear();
///
/// RENDERING TERMINATE