mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-17 21:29:59 +01:00
BugFix MediaPlayer terminate asynchronously to avoid hanging
Deleting a MediaPlayer requires stopping the pipeline and deleting it; the call to gst_element_set_state (pipeline_, GST_STATE_NULL); is however hanging. Running this in a separate thread seems to fix the problem. It is not 100% sure however if the gst_object_unref ( GST_OBJECT (pipeline_) ); will be thread safe and not crashing...
This commit is contained in:
@@ -27,7 +27,6 @@
|
|||||||
#include "SystemToolkit.h"
|
#include "SystemToolkit.h"
|
||||||
#include "BaseToolkit.h"
|
#include "BaseToolkit.h"
|
||||||
#include "GstToolkit.h"
|
#include "GstToolkit.h"
|
||||||
#include "RenderingManager.h"
|
|
||||||
#include "Metronome.h"
|
#include "Metronome.h"
|
||||||
|
|
||||||
#include "MediaPlayer.h"
|
#include "MediaPlayer.h"
|
||||||
@@ -331,7 +330,7 @@ void MediaPlayer::execute_open()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set app sink
|
// set app sink
|
||||||
description += "appsink name=sink";
|
description += "queue ! appsink name=sink";
|
||||||
|
|
||||||
// parse pipeline descriptor
|
// parse pipeline descriptor
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
@@ -451,6 +450,19 @@ void MediaPlayer::Frame::unmap()
|
|||||||
full = false;
|
full = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void delayed_terminate( GstElement *p )
|
||||||
|
{
|
||||||
|
GstElement *__pipeline = p;
|
||||||
|
|
||||||
|
// end pipeline
|
||||||
|
gst_element_set_state (__pipeline, GST_STATE_NULL);
|
||||||
|
|
||||||
|
// unref to free pipeline
|
||||||
|
gst_object_unref ( GST_OBJECT (__pipeline) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MediaPlayer::close()
|
void MediaPlayer::close()
|
||||||
{
|
{
|
||||||
// not opened?
|
// not opened?
|
||||||
@@ -469,16 +481,17 @@ void MediaPlayer::close()
|
|||||||
// clean up GST
|
// clean up GST
|
||||||
if (pipeline_ != nullptr) {
|
if (pipeline_ != nullptr) {
|
||||||
|
|
||||||
// force flush
|
// // force flush
|
||||||
gst_element_send_event(pipeline_, gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
|
// gst_element_send_event(pipeline_, gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
|
||||||
GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0) );
|
// GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0) );
|
||||||
gst_element_get_state (pipeline_, NULL, NULL, GST_CLOCK_TIME_NONE);
|
// gst_element_get_state (pipeline_, NULL, NULL, GST_CLOCK_TIME_NONE);
|
||||||
|
// // end pipeline
|
||||||
|
// gst_element_set_state (pipeline_, GST_STATE_NULL);
|
||||||
|
// gst_object_unref ( GST_OBJECT (pipeline_) );
|
||||||
|
|
||||||
// end pipeline
|
// end pipeline asynchronously // TODO more stress test?
|
||||||
gst_element_set_state (pipeline_, GST_STATE_NULL);
|
std::thread(delayed_terminate, pipeline_).detach();
|
||||||
gst_element_get_state (pipeline_, NULL, NULL, GST_CLOCK_TIME_NONE);
|
|
||||||
|
|
||||||
gst_object_unref (pipeline_);
|
|
||||||
pipeline_ = nullptr;
|
pipeline_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user