diff options
author | Yoann Lopes <yoann.lopes@theqtcompany.com> | 2015-03-23 14:28:41 +0100 |
---|---|---|
committer | Yoann Lopes <yoann.lopes@theqtcompany.com> | 2015-04-07 11:35:05 +0000 |
commit | cbbcf4f3a54fe981ad9d7e649572f86bcdbaf4c6 (patch) | |
tree | f262a36735c031a4c1cbdc7c3b4ff2bbf855cd21 | |
parent | f3ee857564934332da67cc51265841bd76d62b29 (diff) |
GStreamer: implement unlock() in QGstVideoRendererSink.
There are cases where blocking operations happening in the video sink
need to be unblocked, that's why GstBaseSink has an unlock() virtual
function. Since our custom video sink blocks when starting and when
rendering a frame (while waiting for the main thread to actually do
these operations), we need to implement the unlock() function in order
to unblock these operations when requested by GstBaseSink.
Change-Id: I5cb19ea689e655f572729d931cefec8a4266c94e
Reviewed-by: Andrew den Exter <andrew.den.exter@qinetic.com.au>
-rw-r--r-- | src/gsttools/qgstvideorenderersink.cpp | 17 | ||||
-rw-r--r-- | src/gsttools/qvideosurfacegstsink.cpp | 23 | ||||
-rw-r--r-- | src/multimedia/gsttools_headers/qgstvideorenderersink_p.h | 3 | ||||
-rw-r--r-- | src/multimedia/gsttools_headers/qvideosurfacegstsink_p.h | 4 |
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: |