Add video filtering support to VideoOutput

Add the QAbstractVideoFilter base class and integrate it with VideoOutput.

This can be used to perform arbitrary filtering or image processing
on the frames of a video stream of a VideoOutput element right before
the OpenGL texture is provided to the scenegraph by the video node.

This opens up the possibility to integrate computer vision
frameworks or accelerated image processing with Qt Quick applications
that display video streams using Qt Multimedia.

Conceptually it is somewhat similar to QVideoProbe, this
approach however allows modifying the frame, in real time
with tight integration to the scenegraph node, and targets
Qt Quick meaning setting up the filter and processing the results
of the computations happen completely in QML.

[ChangeLog] Added QAbstractVideoFilter that serves as a base class for QML
video filtering elements that integrate compute, vision, and image processing
frameworks with VideoOutput.

Change-Id: Ice1483f8c2daec5a43536978627a7bbb64549480
Reviewed-by: Yoann Lopes <yoann.lopes@theqtcompany.com>
This commit is contained in:
Laszlo Agocs
2015-01-08 14:32:41 +01:00
committed by Yoann Lopes
parent 2f49444638
commit 3e94b7ce2d
33 changed files with 1539 additions and 68 deletions

View File

@@ -262,6 +262,12 @@ bool QDeclarativeVideoOutput::createBackend(QMediaService *service)
m_backend->updateGeometry();
}
if (m_backend) {
m_backend->clearFilters();
for (int i = 0; i < m_filters.count(); ++i)
m_backend->appendFilter(m_filters[i]);
}
return backendAvailable;
}
@@ -795,6 +801,12 @@ void QDeclarativeVideoOutput::itemChange(QQuickItem::ItemChange change,
m_backend->itemChange(change, changeData);
}
void QDeclarativeVideoOutput::releaseResources()
{
if (m_backend)
m_backend->releaseResources();
}
void QDeclarativeVideoOutput::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_UNUSED(newGeometry);
@@ -809,4 +821,54 @@ void QDeclarativeVideoOutput::geometryChanged(const QRectF &newGeometry, const Q
_q_updateGeometry();
}
/*!
\qmlproperty list<object> QtMultimedia::VideoOutput::filters
This property holds the list of video filters that are run on the video
frames. The order of the filters in the list matches the order in which
they will be invoked on the video frames. The objects in the list must be
instances of a subclass of QAbstractVideoFilter.
\sa QAbstractVideoFilter
*/
QQmlListProperty<QAbstractVideoFilter> QDeclarativeVideoOutput::filters()
{
return QQmlListProperty<QAbstractVideoFilter>(this, 0, filter_append, filter_count, filter_at, filter_clear);
}
void QDeclarativeVideoOutput::filter_append(QQmlListProperty<QAbstractVideoFilter> *property, QAbstractVideoFilter *value)
{
QDeclarativeVideoOutput *self = static_cast<QDeclarativeVideoOutput *>(property->object);
self->m_filters.append(value);
if (self->m_backend)
self->m_backend->appendFilter(value);
}
int QDeclarativeVideoOutput::filter_count(QQmlListProperty<QAbstractVideoFilter> *property)
{
QDeclarativeVideoOutput *self = static_cast<QDeclarativeVideoOutput *>(property->object);
return self->m_filters.count();
}
QAbstractVideoFilter *QDeclarativeVideoOutput::filter_at(QQmlListProperty<QAbstractVideoFilter> *property, int index)
{
QDeclarativeVideoOutput *self = static_cast<QDeclarativeVideoOutput *>(property->object);
return self->m_filters.at(index);
}
void QDeclarativeVideoOutput::filter_clear(QQmlListProperty<QAbstractVideoFilter> *property)
{
QDeclarativeVideoOutput *self = static_cast<QDeclarativeVideoOutput *>(property->object);
self->m_filters.clear();
if (self->m_backend)
self->m_backend->clearFilters();
}
void QDeclarativeVideoOutput::_q_invalidateSceneGraph()
{
if (m_backend)
m_backend->invalidateSceneGraph();
}
QT_END_NAMESPACE