GStreamer 1.0: fix some problems with QGstVideoRendererSink.

- Correctly free resources on deletion.
- Correctly stop the sink. We were stopping only when null caps
  were passed to set_caps() but that doesn't seem to always happen.
  Implement GstBaseSink.stop() which is always and consistently
  called by GStreamer.
- Remove pre-roll support (as done previously for 0.10, see
  commit 3b20608f).

Change-Id: I4c5808938f244f4f8a35e121a3a4a862588b752d
Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
This commit is contained in:
Yoann Lopes
2015-01-28 15:17:57 +01:00
parent e4bf7d90bf
commit d4f88c3ec9
2 changed files with 22 additions and 97 deletions

View File

@@ -114,10 +114,9 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(QAbstractVideoSurface *surfac
, m_activeRenderer(0)
, m_surfaceCaps(0)
, m_startCaps(0)
, m_lastBuffer(0)
, m_renderBuffer(0)
, m_notified(false)
, m_stop(false)
, m_render(false)
, m_flush(false)
{
foreach (QObject *instance, rendererLoader()->instances(QGstVideoRendererPluginKey)) {
@@ -137,6 +136,8 @@ QVideoSurfaceGstDelegate::~QVideoSurfaceGstDelegate()
if (m_surfaceCaps)
gst_caps_unref(m_surfaceCaps);
if (m_startCaps)
gst_caps_unref(m_startCaps);
}
GstCaps *QVideoSurfaceGstDelegate::caps()
@@ -157,13 +158,6 @@ bool QVideoSurfaceGstDelegate::start(GstCaps *caps)
m_stop = true;
}
m_render = false;
if (m_lastBuffer) {
gst_buffer_unref(m_lastBuffer);
m_lastBuffer = 0;
}
if (m_startCaps)
gst_caps_unref(m_startCaps);
m_startCaps = caps;
@@ -204,11 +198,6 @@ void QVideoSurfaceGstDelegate::stop()
m_startCaps = 0;
}
if (m_lastBuffer) {
gst_buffer_unref(m_lastBuffer);
m_lastBuffer = 0;
}
waitForAsyncEvent(&locker, &m_setupCondition, 500);
}
@@ -225,68 +214,19 @@ bool QVideoSurfaceGstDelegate::proposeAllocation(GstQuery *query)
}
}
void QVideoSurfaceGstDelegate::flush()
GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
{
QMutexLocker locker(&m_mutex);
m_flush = true;
m_render = false;
m_renderBuffer = buffer;
if (m_lastBuffer) {
gst_buffer_unref(m_lastBuffer);
m_lastBuffer = 0;
}
GstFlowReturn flowReturn = waitForAsyncEvent(&locker, &m_renderCondition, 300)
? m_renderReturn
: GST_FLOW_ERROR;
notify();
}
m_renderBuffer = 0;
GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer, bool show)
{
QMutexLocker locker(&m_mutex);
if (m_lastBuffer)
gst_buffer_unref(m_lastBuffer);
m_lastBuffer = buffer;
gst_buffer_ref(m_lastBuffer);
if (show) {
m_render = true;
return waitForAsyncEvent(&locker, &m_renderCondition, 300)
? m_renderReturn
: GST_FLOW_ERROR;
} else {
return GST_FLOW_OK;
}
}
void QVideoSurfaceGstDelegate::handleShowPrerollChange(GObject *object, GParamSpec *, gpointer d)
{
QVideoSurfaceGstDelegate * const delegate = static_cast<QVideoSurfaceGstDelegate *>(d);
gboolean showPreroll = true; // "show-preroll-frame" property is true by default
g_object_get(object, "show-preroll-frame", &showPreroll, NULL);
GstState state = GST_STATE_NULL;
GstState pendingState = GST_STATE_NULL;
gst_element_get_state(GST_ELEMENT(object), &state, &pendingState, 0);
const bool paused
= (pendingState == GST_STATE_VOID_PENDING && state == GST_STATE_PAUSED)
|| pendingState == GST_STATE_PAUSED;
if (paused) {
QMutexLocker locker(&delegate->m_mutex);
if (!showPreroll && delegate->m_lastBuffer) {
delegate->m_render = false;
delegate->m_flush = true;
delegate->notify();
} else if (delegate->m_lastBuffer) {
delegate->m_render = true;
delegate->notify();
}
}
return flowReturn;
}
bool QVideoSurfaceGstDelegate::event(QEvent *event)
@@ -350,11 +290,9 @@ bool QVideoSurfaceGstDelegate::handleEvent(QMutexLocker *locker)
}
gst_caps_unref(startCaps);
} else if (m_render) {
m_render = false;
if (m_activeRenderer && m_surface && m_lastBuffer) {
GstBuffer *buffer = m_lastBuffer;
} else if (m_renderBuffer) {
if (m_activeRenderer && m_surface) {
GstBuffer *buffer = m_renderBuffer;
gst_buffer_ref(buffer);
locker->unlock();
@@ -442,12 +380,6 @@ QGstVideoRendererSink *QGstVideoRendererSink::createSink(QAbstractVideoSurface *
sink->delegate = new QVideoSurfaceGstDelegate(surface);
g_signal_connect(
G_OBJECT(sink),
"notify::show-preroll-frame",
G_CALLBACK(QVideoSurfaceGstDelegate::handleShowPrerollChange),
sink->delegate);
return sink;
}
@@ -487,7 +419,7 @@ void QGstVideoRendererSink::class_init(gpointer g_class, gpointer class_data)
base_sink_class->get_caps = QGstVideoRendererSink::get_caps;
base_sink_class->set_caps = QGstVideoRendererSink::set_caps;
base_sink_class->propose_allocation = QGstVideoRendererSink::propose_allocation;
base_sink_class->preroll = QGstVideoRendererSink::preroll;
base_sink_class->stop = QGstVideoRendererSink::stop;
base_sink_class->render = QGstVideoRendererSink::render;
GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
@@ -578,20 +510,17 @@ gboolean QGstVideoRendererSink::propose_allocation(GstBaseSink *base, GstQuery *
return sink->delegate->proposeAllocation(query);
}
GstFlowReturn QGstVideoRendererSink::preroll(GstBaseSink *base, GstBuffer *buffer)
gboolean QGstVideoRendererSink::stop(GstBaseSink *base)
{
VO_SINK(base);
gboolean showPreroll = true; // "show-preroll-frame" property is true by default
g_object_get(G_OBJECT(base), "show-preroll-frame", &showPreroll, NULL);
return sink->delegate->render(buffer, showPreroll); // display frame
sink->delegate->stop();
return TRUE;
}
GstFlowReturn QGstVideoRendererSink::render(GstBaseSink *base, GstBuffer *buffer)
{
VO_SINK(base);
return sink->delegate->render(buffer, true);
return sink->delegate->render(buffer);
}
QT_END_NAMESPACE

View File

@@ -98,14 +98,10 @@ public:
void stop();
bool proposeAllocation(GstQuery *query);
void flush();
GstFlowReturn render(GstBuffer *buffer, bool show);
GstFlowReturn render(GstBuffer *buffer);
bool event(QEvent *event);
static void handleShowPrerollChange(GObject *o, GParamSpec *p, gpointer d);
private slots:
bool handleEvent(QMutexLocker *locker);
void updateSupportedFormats();
@@ -126,11 +122,10 @@ private:
GstCaps *m_surfaceCaps;
GstCaps *m_startCaps;
GstBuffer *m_lastBuffer;
GstBuffer *m_renderBuffer;
bool m_notified;
bool m_stop;
bool m_render;
bool m_flush;
};
@@ -156,7 +151,8 @@ private:
static gboolean propose_allocation(GstBaseSink *sink, GstQuery *query);
static GstFlowReturn preroll(GstBaseSink *sink, GstBuffer *buffer);
static gboolean stop(GstBaseSink *sink);
static GstFlowReturn render(GstBaseSink *sink, GstBuffer *buffer);
private: