mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-13 19:29:58 +01:00
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:
@@ -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) {
|
||||
|
||||
if (async)
|
||||
// end pipeline asynchronously
|
||||
std::thread(delayed_terminate, pipeline_).detach();
|
||||
std::thread(pipeline_terminate, pipeline_).detach();
|
||||
else
|
||||
// end pipeline immediately
|
||||
pipeline_terminate(pipeline_);
|
||||
|
||||
pipeline_ = nullptr;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
if (async)
|
||||
std::thread(async_terminate, pipeline_).detach();
|
||||
else
|
||||
async_terminate(pipeline_);
|
||||
|
||||
pipeline_ = nullptr;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -248,8 +248,7 @@ int main(int argc, char *argv[])
|
||||
///
|
||||
/// MIXER TERMINATE
|
||||
///
|
||||
while (Mixer::manager().busy())
|
||||
Mixer::manager().update();
|
||||
Mixer::manager().clear();
|
||||
|
||||
///
|
||||
/// RENDERING TERMINATE
|
||||
|
||||
Reference in New Issue
Block a user