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()
|
MediaPlayer::~MediaPlayer()
|
||||||
{
|
{
|
||||||
close();
|
close(false);
|
||||||
|
|
||||||
// cleanup opengl texture
|
// cleanup opengl texture
|
||||||
if (textureindex_)
|
if (textureindex_)
|
||||||
@@ -714,9 +714,10 @@ void MediaPlayer::Frame::unmap()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void delayed_terminate( GstElement *p )
|
void pipeline_terminate( GstElement *p )
|
||||||
{
|
{
|
||||||
#ifdef MEDIA_PLAYER_DEBUG
|
#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));
|
Log::Info("MediaPlayer %s closed", gst_element_get_name(p));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -727,7 +728,7 @@ void delayed_terminate( GstElement *p )
|
|||||||
gst_object_unref ( p );
|
gst_object_unref ( p );
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPlayer::close()
|
void MediaPlayer::close(bool async)
|
||||||
{
|
{
|
||||||
// not opened?
|
// not opened?
|
||||||
if (!opened_) {
|
if (!opened_) {
|
||||||
@@ -751,9 +752,12 @@ void MediaPlayer::close()
|
|||||||
|
|
||||||
// clean up GST
|
// clean up GST
|
||||||
if (pipeline_ != nullptr) {
|
if (pipeline_ != nullptr) {
|
||||||
|
if (async)
|
||||||
// end pipeline asynchronously
|
// end pipeline asynchronously
|
||||||
std::thread(delayed_terminate, pipeline_).detach();
|
std::thread(pipeline_terminate, pipeline_).detach();
|
||||||
|
else
|
||||||
|
// end pipeline immediately
|
||||||
|
pipeline_terminate(pipeline_);
|
||||||
|
|
||||||
pipeline_ = nullptr;
|
pipeline_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Close the Media
|
* Close the Media
|
||||||
* */
|
* */
|
||||||
void close();
|
void close(bool async = true);
|
||||||
/**
|
/**
|
||||||
* Update texture with latest frame
|
* Update texture with latest frame
|
||||||
* Must be called in rendering update loop
|
* Must be called in rendering update loop
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ Mixer::Mixer() : session_(nullptr), back_session_(nullptr), sessionSwapRequested
|
|||||||
current_source_index_ = -1;
|
current_source_index_ = -1;
|
||||||
|
|
||||||
// initialize with a new empty session
|
// initialize with a new empty session
|
||||||
clear();
|
set( new Session );
|
||||||
setView( View::MIXING );
|
setView( View::MIXING );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1580,7 +1580,7 @@ void Mixer::close(bool smooth)
|
|||||||
transition_.attach(ts);
|
transition_.attach(ts);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
clear();
|
set( new Session );
|
||||||
|
|
||||||
// closing session : filename at font in history should not be reloaded
|
// closing session : filename at font in history should not be reloaded
|
||||||
Settings::application.recentSessions.front_is_valid = false;
|
Settings::application.recentSessions.front_is_valid = false;
|
||||||
@@ -1588,18 +1588,18 @@ void Mixer::close(bool smooth)
|
|||||||
|
|
||||||
void Mixer::clear()
|
void Mixer::clear()
|
||||||
{
|
{
|
||||||
// delete previous back session if needed
|
// wait finish saving / loading
|
||||||
if (back_session_)
|
while (busy())
|
||||||
garbage_.push_back(back_session_);
|
update();
|
||||||
|
|
||||||
// create empty session
|
// set for an empty session and update to ensure session is deleted
|
||||||
back_session_ = new Session;
|
set(new Session);
|
||||||
|
while (sessionSwapRequested_ || garbage_.size() > 0)
|
||||||
|
update();
|
||||||
|
|
||||||
// swap current with empty
|
// all finished, we can clear the back session we just added
|
||||||
sessionSwapRequested_ = true;
|
delete back_session_;
|
||||||
|
back_session_ = nullptr;
|
||||||
// need to deeply update view to apply eventual changes
|
|
||||||
++View::need_deep_update_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mixer::set(Session *s)
|
void Mixer::set(Session *s)
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ void MultiFile::execute_open()
|
|||||||
src_ = gst_bin_get_by_name (GST_BIN (pipeline_), "src");
|
src_ = gst_bin_get_by_name (GST_BIN (pipeline_), "src");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiFile::close ()
|
void MultiFile::close (bool)
|
||||||
{
|
{
|
||||||
if (src_ != nullptr) {
|
if (src_ != nullptr) {
|
||||||
gst_object_unref (src_);
|
gst_object_unref (src_);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class MultiFile : public Stream
|
|||||||
public:
|
public:
|
||||||
MultiFile ();
|
MultiFile ();
|
||||||
void open (const MultiFileSequence &sequence, uint framerate = 30);
|
void open (const MultiFileSequence &sequence, uint framerate = 30);
|
||||||
void close () override;
|
void close (bool) override;
|
||||||
void rewind () override;
|
void rewind () override;
|
||||||
|
|
||||||
// dynamic change of gstreamer multifile source properties
|
// dynamic change of gstreamer multifile source properties
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ Stream::Stream()
|
|||||||
|
|
||||||
Stream::~Stream()
|
Stream::~Stream()
|
||||||
{
|
{
|
||||||
Stream::close();
|
Stream::close(false);
|
||||||
|
|
||||||
// cleanup opengl texture
|
// cleanup opengl texture
|
||||||
if (textureindex_)
|
if (textureindex_)
|
||||||
@@ -368,7 +368,7 @@ void async_terminate( GstElement *p )
|
|||||||
gst_object_unref ( p );
|
gst_object_unref ( p );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stream::close()
|
void Stream::close(bool async)
|
||||||
{
|
{
|
||||||
// not opened?
|
// not opened?
|
||||||
if (!opened_) {
|
if (!opened_) {
|
||||||
@@ -386,7 +386,10 @@ void Stream::close()
|
|||||||
if (pipeline_ != nullptr) {
|
if (pipeline_ != nullptr) {
|
||||||
|
|
||||||
// end pipeline asynchronously
|
// end pipeline asynchronously
|
||||||
|
if (async)
|
||||||
std::thread(async_terminate, pipeline_).detach();
|
std::thread(async_terminate, pipeline_).detach();
|
||||||
|
else
|
||||||
|
async_terminate(pipeline_);
|
||||||
|
|
||||||
pipeline_ = nullptr;
|
pipeline_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Close the Media
|
* Close the Media
|
||||||
* */
|
* */
|
||||||
virtual void close();
|
virtual void close(bool async = true);
|
||||||
/**
|
/**
|
||||||
* Update texture with latest frame
|
* Update texture with latest frame
|
||||||
* Must be called in rendering update loop
|
* Must be called in rendering update loop
|
||||||
|
|||||||
@@ -248,8 +248,7 @@ int main(int argc, char *argv[])
|
|||||||
///
|
///
|
||||||
/// MIXER TERMINATE
|
/// MIXER TERMINATE
|
||||||
///
|
///
|
||||||
while (Mixer::manager().busy())
|
Mixer::manager().clear();
|
||||||
Mixer::manager().update();
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// RENDERING TERMINATE
|
/// RENDERING TERMINATE
|
||||||
|
|||||||
Reference in New Issue
Block a user