BugFix improved complete close of session

Wait for all registered pipelines to end when clearing the mixer manager (closing is asynchronous).
This commit is contained in:
Bruno Herbelin
2024-02-28 18:47:54 +01:00
parent 05f593e40c
commit 03c68d1dc3
8 changed files with 41 additions and 39 deletions

View File

@@ -48,7 +48,7 @@
#include "RenderingManager.h"
#endif
std::list<MediaPlayer*> MediaPlayer::registered_;
std::list<GstElement*> MediaPlayer::registered_;
MediaPlayer::MediaPlayer()
{
@@ -100,7 +100,7 @@ MediaPlayer::MediaPlayer()
MediaPlayer::~MediaPlayer()
{
close(false);
close();
// cleanup opengl texture
if (textureindex_)
@@ -497,7 +497,7 @@ void MediaPlayer::execute_open()
gst_element_set_name(pipeline_, std::to_string(id_).c_str());
// register media player
MediaPlayer::registered_.push_back(this);
MediaPlayer::registered_.push_back(pipeline_);
}
#else
@@ -668,7 +668,7 @@ void MediaPlayer::execute_open()
gst_element_set_name(pipeline_, std::to_string(id_).c_str());
// register media player
MediaPlayer::registered_.push_back(this);
MediaPlayer::registered_.push_back(pipeline_);
}
#endif
@@ -714,7 +714,7 @@ void MediaPlayer::Frame::unmap()
}
void pipeline_terminate( GstElement *p )
void MediaPlayer::pipeline_terminate( GstElement *p )
{
#ifdef MEDIA_PLAYER_DEBUG
g_printerr("MediaPlayer %s close\n", gst_element_get_name(p));
@@ -726,9 +726,12 @@ void pipeline_terminate( GstElement *p )
// unref to free pipeline
gst_object_unref ( p );
// unregister
MediaPlayer::registered_.remove(p);
}
void MediaPlayer::close(bool async)
void MediaPlayer::close()
{
// not opened?
if (!opened_) {
@@ -752,13 +755,8 @@ void MediaPlayer::close(bool async)
// clean up GST
if (pipeline_ != nullptr) {
if (async)
// end pipeline asynchronously
std::thread(pipeline_terminate, pipeline_).detach();
else
// end pipeline immediately
pipeline_terminate(pipeline_);
// end pipeline asynchronously
std::thread(MediaPlayer::pipeline_terminate, pipeline_).detach();
pipeline_ = nullptr;
}
@@ -772,8 +770,6 @@ void MediaPlayer::close(bool async)
write_index_ = 0;
last_index_ = 0;
// unregister media player
MediaPlayer::registered_.remove(this);
}

View File

@@ -2,7 +2,6 @@
#define __GST_MEDIA_PLAYER_H_
#include <string>
#include <atomic>
#include <mutex>
#include <future>
@@ -101,7 +100,7 @@ public:
/**
* Close the Media
* */
void close(bool async = true);
void close();
/**
* Update texture with latest frame
* Must be called in rendering update loop
@@ -300,13 +299,13 @@ public:
* Accept visitors
* */
void accept(Visitor& v);
/**
* @brief registered
* @return list of media players currently registered
*/
static std::list<MediaPlayer*> registered() { return registered_; }
static std::list<MediaPlayer*>::const_iterator begin() { return registered_.cbegin(); }
static std::list<MediaPlayer*>::const_iterator end() { return registered_.cend(); }
static std::list<GstElement*> registered() { return registered_; }
/**
* Discoverer to check uri and get media info
* */
@@ -423,7 +422,8 @@ private:
static GstFlowReturn callback_new_sample (GstAppSink *, gpointer);
// global list of registered media player
static std::list<MediaPlayer*> registered_;
static void pipeline_terminate(GstElement *p);
static std::list<GstElement*> registered_;
};

View File

@@ -1,4 +1,3 @@
#include <atomic>
#include <iomanip>
#include <iostream>
#include <thread>

View File

@@ -19,7 +19,6 @@
#include <algorithm>
#include <thread>
#include <atomic>
#include <mutex>
#include <vector>
#include <chrono>
@@ -1592,9 +1591,9 @@ void Mixer::clear()
while (busy())
update();
// set for an empty session and update to ensure session is deleted
// set for an empty session and update to ensure all streams are deleted
set(new Session);
while (sessionSwapRequested_ || garbage_.size() > 0)
while ( !MediaPlayer::registered().empty() || !Stream::registered().empty() )
update();
// all finished, we can clear the back session we just added

View File

@@ -120,7 +120,7 @@ void MultiFile::execute_open()
src_ = gst_bin_get_by_name (GST_BIN (pipeline_), "src");
}
void MultiFile::close (bool)
void MultiFile::close ()
{
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 (bool) override;
void close () override;
void rewind () override;
// dynamic change of gstreamer multifile source properties

View File

@@ -31,6 +31,8 @@
#include "Stream.h"
std::list<GstElement*> Stream::registered_;
#ifndef NDEBUG
#define STREAM_DEBUG
#endif
@@ -73,7 +75,7 @@ Stream::Stream()
Stream::~Stream()
{
Stream::close(false);
Stream::close();
// cleanup opengl texture
if (textureindex_)
@@ -348,9 +350,10 @@ void Stream::Frame::unmap()
}
void async_terminate( GstElement *p )
void Stream::pipeline_terminate( GstElement *p )
{
#ifdef STREAM_DEBUG
g_printerr("Stream %s close\n", gst_element_get_name(p));
Log::Info("Stream %s closed", gst_element_get_name(p));
#endif
@@ -366,9 +369,12 @@ void async_terminate( GstElement *p )
// unref to free pipeline
gst_object_unref ( p );
// unregister
Stream::registered_.remove(p);
}
void Stream::close(bool async)
void Stream::close()
{
// not opened?
if (!opened_) {
@@ -384,13 +390,8 @@ void Stream::close(bool async)
// clean up GST
if (pipeline_ != nullptr) {
// end pipeline asynchronously
if (async)
std::thread(async_terminate, pipeline_).detach();
else
async_terminate(pipeline_);
std::thread(Stream::pipeline_terminate, pipeline_).detach();
pipeline_ = nullptr;
}

View File

@@ -2,7 +2,7 @@
#define STREAM_H
#include <string>
#include <atomic>
#include <list>
#include <mutex>
#include <future>
#include <condition_variable>
@@ -74,7 +74,7 @@ public:
/**
* Close the Media
* */
virtual void close(bool async = true);
virtual void close();
/**
* Update texture with latest frame
* Must be called in rendering update loop
@@ -160,7 +160,11 @@ public:
* Used for saving session file
* */
void accept(Visitor& v);
/**
* @brief registered
* @return list of streams currently registered
*/
static std::list<GstElement*> registered() { return registered_; }
protected:
@@ -249,6 +253,9 @@ protected:
static GstFlowReturn callback_new_preroll (GstAppSink *, gpointer );
static GstFlowReturn callback_new_sample (GstAppSink *, gpointer);
// global list of registered streams
static void pipeline_terminate(GstElement *p);
static std::list<GstElement*> registered_;
};