summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gsttools/qgstvideorenderersink.cpp17
-rw-r--r--src/gsttools/qvideosurfacegstsink.cpp23
-rw-r--r--src/multimedia/gsttools_headers/qgstvideorenderersink_p.h3
-rw-r--r--src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h4
4 files changed, 46 insertions, 1 deletions
diff --git a/src/gsttools/qgstvideorenderersink.cpp b/src/gsttools/qgstvideorenderersink.cpp
index c09d683a1..e44379220 100644
--- a/src/gsttools/qgstvideorenderersink.cpp
+++ b/src/gsttools/qgstvideorenderersink.cpp
@@ -201,6 +201,14 @@ void QVideoSurfaceGstDelegate::stop()
waitForAsyncEvent(&locker, &m_setupCondition, 500);
}
+void QVideoSurfaceGstDelegate::unlock()
+{
+ QMutexLocker locker(&m_mutex);
+
+ m_setupCondition.wakeAll();
+ m_renderCondition.wakeAll();
+}
+
bool QVideoSurfaceGstDelegate::proposeAllocation(GstQuery *query)
{
QMutexLocker locker(&m_mutex);
@@ -218,6 +226,7 @@ GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
{
QMutexLocker locker(&m_mutex);
+ m_renderReturn = GST_FLOW_OK;
m_renderBuffer = buffer;
GstFlowReturn flowReturn = waitForAsyncEvent(&locker, &m_renderCondition, 300)
@@ -423,6 +432,7 @@ void QGstVideoRendererSink::class_init(gpointer g_class, gpointer class_data)
base_sink_class->set_caps = QGstVideoRendererSink::set_caps;
base_sink_class->propose_allocation = QGstVideoRendererSink::propose_allocation;
base_sink_class->stop = QGstVideoRendererSink::stop;
+ base_sink_class->unlock = QGstVideoRendererSink::unlock;
GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
element_class->change_state = QGstVideoRendererSink::change_state;
@@ -519,6 +529,13 @@ gboolean QGstVideoRendererSink::stop(GstBaseSink *base)
return TRUE;
}
+gboolean QGstVideoRendererSink::unlock(GstBaseSink *base)
+{
+ VO_SINK(base);
+ sink->delegate->unlock();
+ return TRUE;
+}
+
GstFlowReturn QGstVideoRendererSink::show_frame(GstVideoSink *base, GstBuffer *buffer)
{
VO_SINK(base);
diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp
index 36644581e..4a786ea16 100644
--- a/src/gsttools/qvideosurfacegstsink.cpp
+++ b/src/gsttools/qvideosurfacegstsink.cpp
@@ -162,6 +162,15 @@ void QVideoSurfaceGstDelegate::stop()
m_started = false;
}
+void QVideoSurfaceGstDelegate::unlock()
+{
+ QMutexLocker locker(&m_mutex);
+
+ m_startCanceled = true;
+ m_setupCondition.wakeAll();
+ m_renderCondition.wakeAll();
+}
+
bool QVideoSurfaceGstDelegate::isActive()
{
QMutexLocker locker(&m_mutex);
@@ -218,8 +227,9 @@ GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
void QVideoSurfaceGstDelegate::queuedStart()
{
+ QMutexLocker locker(&m_mutex);
+
if (!m_startCanceled) {
- QMutexLocker locker(&m_mutex);
m_started = m_surface->start(m_format);
m_setupCondition.wakeAll();
}
@@ -238,6 +248,9 @@ void QVideoSurfaceGstDelegate::queuedRender()
{
QMutexLocker locker(&m_mutex);
+ if (!m_frame.isValid())
+ return;
+
if (m_surface.isNull()) {
qWarning() << "Rendering video frame to deleted surface, skip the frame";
m_renderReturn = GST_FLOW_OK;
@@ -347,6 +360,7 @@ void QVideoSurfaceGstSink::class_init(gpointer g_class, gpointer class_data)
base_sink_class->buffer_alloc = QVideoSurfaceGstSink::buffer_alloc;
base_sink_class->start = QVideoSurfaceGstSink::start;
base_sink_class->stop = QVideoSurfaceGstSink::stop;
+ base_sink_class->unlock = QVideoSurfaceGstSink::unlock;
GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
element_class->change_state = QVideoSurfaceGstSink::change_state;
@@ -601,6 +615,13 @@ gboolean QVideoSurfaceGstSink::stop(GstBaseSink *base)
return TRUE;
}
+gboolean QVideoSurfaceGstSink::unlock(GstBaseSink *base)
+{
+ VO_SINK(base);
+ sink->delegate->unlock();
+ return TRUE;
+}
+
GstFlowReturn QVideoSurfaceGstSink::show_frame(GstVideoSink *base, GstBuffer *buffer)
{
VO_SINK(base);
diff --git a/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h b/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h
index 72beceeaf..186708872 100644
--- a/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h
+++ b/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h
@@ -96,6 +96,7 @@ public:
bool start(GstCaps *caps);
void stop();
+ void unlock();
bool proposeAllocation(GstQuery *query);
GstFlowReturn render(GstBuffer *buffer);
@@ -153,6 +154,8 @@ private:
static gboolean stop(GstBaseSink *sink);
+ static gboolean unlock(GstBaseSink *sink);
+
static GstFlowReturn show_frame(GstVideoSink *sink, GstBuffer *buffer);
private:
diff --git a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
index 0b253462e..e8f61afe0 100644
--- a/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
+++ b/src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h
@@ -88,6 +88,8 @@ public:
bool start(const QVideoSurfaceFormat &format, int bytesPerLine);
void stop();
+ void unlock();
+
bool isActive();
QGstBufferPoolInterface *pool() { return m_pool; }
@@ -148,6 +150,8 @@ private:
static gboolean start(GstBaseSink *sink);
static gboolean stop(GstBaseSink *sink);
+ static gboolean unlock(GstBaseSink *sink);
+
static GstFlowReturn show_frame(GstVideoSink *sink, GstBuffer *buffer);
private: