Some cleanup in the GStreamer plugin.

Removed QGstreamerVideoOverlay and related classes. It was used as
'Window' control but performs worse than QGstreamerVideoWindow which
does basically the same thing using GStreamer ready-made components
instead.
Removed X11 dependencies and related configuration tests. It was only
needed for QGstreamerVideoOverlay.

Change-Id: I2ad2636ccf0060e56cd64f3d9e5b3c24dc75f5a3
Reviewed-by: Andy Nichols <andy.nichols@digia.com>
This commit is contained in:
Yoann Lopes
2013-09-20 14:02:24 +02:00
committed by The Qt Project
parent ac029c65f2
commit c3ca3a760e
22 changed files with 35 additions and 1620 deletions

View File

@@ -1,53 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Multimedia module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <X11/Xlib.h>
#include <X11/extensions/Xv.h>
#include <X11/extensions/Xvlib.h>
int main(int argc, char** argv)
{
unsigned int count = 0;
XvAdaptorInfo *adaptors = 0;
XvQueryAdaptors(0, 0, &count, &adaptors);
return 0;
}

View File

@@ -1,8 +0,0 @@
SOURCES += main.cpp
CONFIG += link_pkgconfig
PKGCONFIG += \
x11 \
xext \
xv

View File

@@ -24,7 +24,6 @@ win32 {
qtCompileTest(gstreamer_appsrc)
}
qtCompileTest(resourcepolicy)
qtCompileTest(xvideo)
}
load(qt_parts)

View File

@@ -49,6 +49,7 @@ PRIVATE_HEADERS += \
qgstcodecsinfo_p.h \
qgstreamervideoprobecontrol_p.h \
qgstreameraudioprobecontrol_p.h \
qgstreamervideowindow_p.h
SOURCES += \
qgstbufferpoolinterface.cpp \
@@ -65,33 +66,16 @@ SOURCES += \
gstvideoconnector.c \
qgstreamervideoprobecontrol.cpp \
qgstreameraudioprobecontrol.cpp \
qgstreamervideowindow.cpp
config_xvideo {
DEFINES += HAVE_XVIDEO
LIBS += -lXv -lX11 -lXext
qtHaveModule(widgets) {
QT += multimediawidgets
PRIVATE_HEADERS += \
qgstxvimagebuffer_p.h \
qgstreamervideowidget_p.h
SOURCES += \
qgstxvimagebuffer.cpp \
qtHaveModule(widgets) {
QT += multimediawidgets
PRIVATE_HEADERS += \
qgstreamervideooverlay_p.h \
qgstreamervideowindow_p.h \
qgstreamervideowidget_p.h \
qx11videosurface_p.h \
SOURCES += \
qgstreamervideooverlay.cpp \
qgstreamervideowindow.cpp \
qgstreamervideowidget.cpp \
qx11videosurface.cpp \
}
qgstreamervideowidget.cpp
}
maemo6 {

View File

@@ -1,228 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qgstreamervideooverlay_p.h"
#include <private/qvideosurfacegstsink_p.h>
#include <qvideosurfaceformat.h>
#include <qx11videosurface_p.h>
QGstreamerVideoOverlay::QGstreamerVideoOverlay(QObject *parent)
: QVideoWindowControl(parent)
, m_surface(new QX11VideoSurface)
, m_videoSink(reinterpret_cast<GstElement*>(QVideoSurfaceGstSink::createSink(m_surface)))
, m_aspectRatioMode(Qt::KeepAspectRatio)
, m_fullScreen(false)
{
if (m_videoSink) {
gst_object_ref(GST_OBJECT(m_videoSink)); //Take ownership
gst_object_sink(GST_OBJECT(m_videoSink));
}
connect(m_surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)),
this, SLOT(surfaceFormatChanged()));
}
QGstreamerVideoOverlay::~QGstreamerVideoOverlay()
{
if (m_videoSink)
gst_object_unref(GST_OBJECT(m_videoSink));
delete m_surface;
}
WId QGstreamerVideoOverlay::winId() const
{
return m_surface->winId();
}
void QGstreamerVideoOverlay::setWinId(WId id)
{
bool wasReady = isReady();
m_surface->setWinId(id);
if (isReady() != wasReady)
emit readyChanged(!wasReady);
}
QRect QGstreamerVideoOverlay::displayRect() const
{
return m_displayRect;
}
void QGstreamerVideoOverlay::setDisplayRect(const QRect &rect)
{
m_displayRect = rect;
setScaledDisplayRect();
}
Qt::AspectRatioMode QGstreamerVideoOverlay::aspectRatioMode() const
{
return m_aspectRatioMode;
}
void QGstreamerVideoOverlay::setAspectRatioMode(Qt::AspectRatioMode mode)
{
m_aspectRatioMode = mode;
setScaledDisplayRect();
}
void QGstreamerVideoOverlay::repaint()
{
}
int QGstreamerVideoOverlay::brightness() const
{
return m_surface->brightness();
}
void QGstreamerVideoOverlay::setBrightness(int brightness)
{
m_surface->setBrightness(brightness);
emit brightnessChanged(m_surface->brightness());
}
int QGstreamerVideoOverlay::contrast() const
{
return m_surface->contrast();
}
void QGstreamerVideoOverlay::setContrast(int contrast)
{
m_surface->setContrast(contrast);
emit contrastChanged(m_surface->contrast());
}
int QGstreamerVideoOverlay::hue() const
{
return m_surface->hue();
}
void QGstreamerVideoOverlay::setHue(int hue)
{
m_surface->setHue(hue);
emit hueChanged(m_surface->hue());
}
int QGstreamerVideoOverlay::saturation() const
{
return m_surface->saturation();
}
void QGstreamerVideoOverlay::setSaturation(int saturation)
{
m_surface->setSaturation(saturation);
emit saturationChanged(m_surface->saturation());
}
bool QGstreamerVideoOverlay::isFullScreen() const
{
return m_fullScreen;
}
void QGstreamerVideoOverlay::setFullScreen(bool fullScreen)
{
emit fullScreenChanged(m_fullScreen = fullScreen);
}
QSize QGstreamerVideoOverlay::nativeSize() const
{
return m_surface->surfaceFormat().sizeHint();
}
QAbstractVideoSurface *QGstreamerVideoOverlay::surface() const
{
return m_surface;
}
GstElement *QGstreamerVideoOverlay::videoSink()
{
return m_videoSink;
}
void QGstreamerVideoOverlay::surfaceFormatChanged()
{
setScaledDisplayRect();
emit nativeSizeChanged();
}
void QGstreamerVideoOverlay::setScaledDisplayRect()
{
QRect formatViewport = m_surface->surfaceFormat().viewport();
switch (m_aspectRatioMode) {
case Qt::KeepAspectRatio:
{
QSize size = m_surface->surfaceFormat().sizeHint();
size.scale(m_displayRect.size(), Qt::KeepAspectRatio);
QRect rect(QPoint(0, 0), size);
rect.moveCenter(m_displayRect.center());
m_surface->setDisplayRect(rect);
m_surface->setViewport(formatViewport);
}
break;
case Qt::IgnoreAspectRatio:
m_surface->setDisplayRect(m_displayRect);
m_surface->setViewport(formatViewport);
break;
case Qt::KeepAspectRatioByExpanding:
{
QSize size = m_displayRect.size();
size.scale(m_surface->surfaceFormat().sizeHint(), Qt::KeepAspectRatio);
QRect viewport(QPoint(0, 0), size);
viewport.moveCenter(formatViewport.center());
m_surface->setDisplayRect(m_displayRect);
m_surface->setViewport(viewport);
}
break;
};
}

View File

@@ -47,9 +47,6 @@
#include <QtWidgets/qapplication.h>
#include <QtGui/qpainter.h>
#ifdef Q_WS_X11
# include <X11/Xlib.h>
#endif
#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
#include <gst/interfaces/propertyprobe.h>

View File

@@ -48,14 +48,6 @@
#include <gst/interfaces/xoverlay.h>
#include <gst/interfaces/propertyprobe.h>
/*
QGstreamerVideoWindow is similar to QGstreamerVideoOverlay,
but uses xvimagesink like gstreamer element instead of QX11VideoSurface.
This allows to use the accelerated elements if available on the target platform,
but requires at least 0.10.29 gstreamer version
with gst_x_overlay_set_render_rectangle to set display rect.
*/
QGstreamerVideoWindow::QGstreamerVideoWindow(QObject *parent, const char *elementName)
: QVideoWindowControl(parent)
@@ -95,8 +87,6 @@ void QGstreamerVideoWindow::setWinId(WId id)
if (m_windowId == id)
return;
qDebug() << Q_FUNC_INFO << id;
WId oldId = m_windowId;
m_windowId = id;

View File

@@ -1,329 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/qdebug.h>
#include <QtCore/qthread.h>
#include <QtCore/qvariant.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qwindow.h>
#include <qpa/qplatformnativeinterface.h>
#include "qgstxvimagebuffer_p.h"
#include "qvideosurfacegstsink_p.h"
#include "qgstvideobuffer_p.h"
QT_BEGIN_NAMESPACE
GstBufferClass *QGstXvImageBuffer::parent_class = NULL;
GType QGstXvImageBuffer::get_type(void)
{
static GType buffer_type = 0;
if (buffer_type == 0) {
static const GTypeInfo buffer_info = {
sizeof (GstBufferClass),
NULL,
NULL,
QGstXvImageBuffer::class_init,
NULL,
NULL,
sizeof(QGstXvImageBuffer),
0,
(GInstanceInitFunc)QGstXvImageBuffer::buffer_init,
NULL
};
buffer_type = g_type_register_static(GST_TYPE_BUFFER,
"QGstXvImageBuffer", &buffer_info, GTypeFlags(0));
}
return buffer_type;
}
void QGstXvImageBuffer::class_init(gpointer g_class, gpointer class_data)
{
Q_UNUSED(class_data);
GST_MINI_OBJECT_CLASS(g_class)->finalize =
(GstMiniObjectFinalizeFunction)buffer_finalize;
parent_class = (GstBufferClass*)g_type_class_peek_parent(g_class);
}
void QGstXvImageBuffer::buffer_init(QGstXvImageBuffer *xvImage, gpointer g_class)
{
Q_UNUSED(g_class);
xvImage->pool = 0;
xvImage->shmInfo.shmaddr = ((char *) -1);
xvImage->shmInfo.shmid = -1;
xvImage->markedForDeletion = false;
}
void QGstXvImageBuffer::buffer_finalize(QGstXvImageBuffer * xvImage)
{
if (xvImage->pool) {
if (xvImage->markedForDeletion)
xvImage->pool->destroyBuffer(xvImage);
else
xvImage->pool->recycleBuffer(xvImage);
}
}
QGstXvImageBufferPool::QGstXvImageBufferPool(QObject *parent)
:QObject(parent)
{
m_threadId = QThread::currentThreadId();
}
QGstXvImageBufferPool::~QGstXvImageBufferPool()
{
}
bool QGstXvImageBufferPool::isFormatSupported(const QVideoSurfaceFormat &surfaceFormat) const
{
bool ok = true;
surfaceFormat.property("portId").toULongLong(&ok);
if (!ok)
return false;
int xvFormatId = surfaceFormat.property("xvFormatId").toInt(&ok);
if (!ok || xvFormatId < 0)
return false;
int dataSize = surfaceFormat.property("dataSize").toInt(&ok);
if (!ok || dataSize<=0)
return false;
return true;
}
GType QGstXvImageBufferPool::bufferType() const
{
return QGstXvImageBuffer::get_type();
}
GstBuffer *QGstXvImageBufferPool::takeBuffer(
const QVideoSurfaceFormat &format, GstCaps *caps)
{
m_poolMutex.lock();
m_caps = caps;
if (format != m_format) {
doClear();
m_format = format;
}
if (m_pool.isEmpty()) {
//qDebug() << "QGstXvImageBufferPool::takeBuffer: no buffer available, allocate the new one" << QThread::currentThreadId() << m_threadId;
if (QThread::currentThreadId() == m_threadId) {
doAlloc();
} else {
QMetaObject::invokeMethod(this, "queuedAlloc", Qt::QueuedConnection);
m_allocWaitCondition.wait(&m_poolMutex, 300);
}
}
QGstXvImageBuffer *res = 0;
if (!m_pool.isEmpty()) {
res = m_pool.takeLast();
}
m_poolMutex.unlock();
return GST_BUFFER(res);
}
QAbstractVideoBuffer::HandleType QGstXvImageBufferPool::handleType() const
{
return QAbstractVideoBuffer::XvShmImageHandle;
}
QAbstractVideoBuffer *QGstXvImageBufferPool::prepareVideoBuffer(GstBuffer *buffer, int bytesPerLine)
{
if (!G_TYPE_CHECK_INSTANCE_TYPE(buffer, bufferType()))
return 0;
QGstXvImageBuffer *xvBuffer = reinterpret_cast<QGstXvImageBuffer *>(buffer);
QVariant handle = QVariant::fromValue(xvBuffer->xvImage);
return new QGstVideoBuffer(buffer, bytesPerLine, QAbstractVideoBuffer::XvShmImageHandle, handle);
}
QStringList QGstXvImageBufferPool::keys() const
{
return QStringList() << QGstBufferPoolPluginKey;
}
void QGstXvImageBufferPool::queuedAlloc()
{
QMutexLocker lock(&m_poolMutex);
doAlloc();
m_allocWaitCondition.wakeOne();
}
void QGstXvImageBufferPool::doAlloc()
{
//should be always called from the main thread with m_poolMutex locked
//Q_ASSERT(QThread::currentThread() == thread());
XSync(display(), false);
QGstXvImageBuffer *xvBuffer = (QGstXvImageBuffer *)gst_mini_object_new(QGstXvImageBuffer::get_type());
quint64 portId = m_format.property("portId").toULongLong();
int xvFormatId = m_format.property("xvFormatId").toInt();
xvBuffer->xvImage = XvShmCreateImage(
display(),
portId,
xvFormatId,
0,
m_format.frameWidth(),
m_format.frameHeight(),
&xvBuffer->shmInfo
);
if (!xvBuffer->xvImage) {
qWarning() << "QGstXvImageBufferPool: XvShmCreateImage failed";
return;
}
XSync(display(), false);
xvBuffer->shmInfo.shmid = shmget(IPC_PRIVATE, xvBuffer->xvImage->data_size, IPC_CREAT | 0777);
xvBuffer->shmInfo.shmaddr = xvBuffer->xvImage->data = (char*)shmat(xvBuffer->shmInfo.shmid, 0, 0);
xvBuffer->shmInfo.readOnly = False;
if (!XShmAttach(display(), &xvBuffer->shmInfo)) {
qWarning() << "QGstXvImageBufferPool: XShmAttach failed";
return;
}
XSync(display(), false);
shmctl (xvBuffer->shmInfo.shmid, IPC_RMID, NULL);
xvBuffer->pool = this;
GST_MINI_OBJECT_CAST(xvBuffer)->flags = 0;
gst_buffer_set_caps(GST_BUFFER_CAST(xvBuffer), m_caps);
GST_BUFFER_DATA(xvBuffer) = (uchar*)xvBuffer->xvImage->data;
GST_BUFFER_SIZE(xvBuffer) = xvBuffer->xvImage->data_size;
m_allBuffers.append(xvBuffer);
m_pool.append(xvBuffer);
XSync(display(), false);
}
void QGstXvImageBufferPool::clear()
{
QMutexLocker lock(&m_poolMutex);
doClear();
}
void QGstXvImageBufferPool::doClear()
{
foreach (QGstXvImageBuffer *xvBuffer, m_allBuffers) {
xvBuffer->markedForDeletion = true;
}
m_allBuffers.clear();
foreach (QGstXvImageBuffer *xvBuffer, m_pool) {
gst_buffer_unref(GST_BUFFER(xvBuffer));
}
m_pool.clear();
m_format = QVideoSurfaceFormat();
}
void QGstXvImageBufferPool::queuedDestroy()
{
QMutexLocker lock(&m_destroyMutex);
XSync(display(), false);
foreach(XvShmImage xvImage, m_imagesToDestroy) {
if (xvImage.shmInfo.shmaddr != ((void *) -1)) {
XShmDetach(display(), &xvImage.shmInfo);
XSync(display(), false);
shmdt(xvImage.shmInfo.shmaddr);
}
if (xvImage.xvImage)
XFree(xvImage.xvImage);
}
m_imagesToDestroy.clear();
XSync(display(), false);
}
void QGstXvImageBufferPool::recycleBuffer(QGstXvImageBuffer *xvBuffer)
{
QMutexLocker lock(&m_poolMutex);
gst_buffer_ref(GST_BUFFER_CAST(xvBuffer));
m_pool.append(xvBuffer);
}
void QGstXvImageBufferPool::destroyBuffer(QGstXvImageBuffer *xvBuffer)
{
XvShmImage imageToDestroy;
imageToDestroy.xvImage = xvBuffer->xvImage;
imageToDestroy.shmInfo = xvBuffer->shmInfo;
m_destroyMutex.lock();
m_imagesToDestroy.append(imageToDestroy);
m_destroyMutex.unlock();
if (m_imagesToDestroy.size() == 1)
QMetaObject::invokeMethod(this, "queuedDestroy", Qt::QueuedConnection);
}
Display *QGstXvImageBufferPool::display() const
{
QWindow *window = QGuiApplication::topLevelWindows().first();
Display *display = static_cast<Display *>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("Display", window));
return display;
}
QT_END_NAMESPACE

View File

@@ -49,10 +49,6 @@
#include <private/qmediapluginloader_p.h>
#include "qgstvideobuffer_p.h"
#if defined(HAVE_XVIDEO)
#include "qgstxvimagebuffer_p.h"
#endif
#include "qvideosurfacegstsink_p.h"
//#define DEBUG_VIDEO_SURFACE_SINK
@@ -79,9 +75,6 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
m_pools.append(plugin);
}
}
#ifdef HAVE_XVIDEO
m_pools.append(new QGstXvImageBufferPool(this));
#endif
updateSupportedFormats();
connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(updateSupportedFormats()));
}

View File

@@ -1,534 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/qvariant.h>
#include <QtCore/qdebug.h>
#include <QtGui/qguiapplication.h>
#include <qpa/qplatformnativeinterface.h>
#include <qvideosurfaceformat.h>
#include "qx11videosurface_p.h"
Q_DECLARE_METATYPE(XvImage*);
struct XvFormatRgb
{
QVideoFrame::PixelFormat pixelFormat;
int bits_per_pixel;
int format;
int num_planes;
int depth;
unsigned int red_mask;
unsigned int green_mask;
unsigned int blue_mask;
};
bool operator ==(const XvImageFormatValues &format, const XvFormatRgb &rgb)
{
return format.type == XvRGB
&& format.bits_per_pixel == rgb.bits_per_pixel
&& format.format == rgb.format
&& format.num_planes == rgb.num_planes
&& format.depth == rgb.depth
&& format.red_mask == rgb.red_mask
&& format.blue_mask == rgb.blue_mask;
}
static const XvFormatRgb qt_xvRgbLookup[] =
{
{ QVideoFrame::Format_ARGB32, 32, XvPacked, 1, 32, 0x00FF0000, 0x0000FF00, 0x000000FF },
{ QVideoFrame::Format_RGB32 , 32, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF },
{ QVideoFrame::Format_RGB24 , 24, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF },
{ QVideoFrame::Format_RGB565, 16, XvPacked, 1, 16, 0x0000F800, 0x000007E0, 0x0000001F },
{ QVideoFrame::Format_BGRA32, 32, XvPacked, 1, 32, 0xFF000000, 0x00FF0000, 0x0000FF00 },
{ QVideoFrame::Format_BGR32 , 32, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF },
{ QVideoFrame::Format_BGR24 , 24, XvPacked, 1, 24, 0x00FF0000, 0x0000FF00, 0x000000FF },
{ QVideoFrame::Format_BGR565, 16, XvPacked, 1, 16, 0x0000F800, 0x000007E0, 0x0000001F }
};
struct XvFormatYuv
{
QVideoFrame::PixelFormat pixelFormat;
int bits_per_pixel;
int format;
int num_planes;
unsigned int y_sample_bits;
unsigned int u_sample_bits;
unsigned int v_sample_bits;
unsigned int horz_y_period;
unsigned int horz_u_period;
unsigned int horz_v_period;
unsigned int vert_y_period;
unsigned int vert_u_period;
unsigned int vert_v_period;
char component_order[32];
};
bool operator ==(const XvImageFormatValues &format, const XvFormatYuv &yuv)
{
return format.type == XvYUV
&& format.bits_per_pixel == yuv.bits_per_pixel
&& format.format == yuv.format
&& format.num_planes == yuv.num_planes
&& format.y_sample_bits == yuv.y_sample_bits
&& format.u_sample_bits == yuv.u_sample_bits
&& format.v_sample_bits == yuv.v_sample_bits
&& format.horz_y_period == yuv.horz_y_period
&& format.horz_u_period == yuv.horz_u_period
&& format.horz_v_period == yuv.horz_v_period
&& format.horz_y_period == yuv.vert_y_period
&& format.vert_u_period == yuv.vert_u_period
&& format.vert_v_period == yuv.vert_v_period
&& qstrncmp(format.component_order, yuv.component_order, 32) == 0;
}
static const XvFormatYuv qt_xvYuvLookup[] =
{
{ QVideoFrame::Format_YUV444 , 24, XvPacked, 1, 8, 8, 8, 1, 1, 1, 1, 1, 1, "YUV" },
{ QVideoFrame::Format_YUV420P, 12, XvPlanar, 3, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YUV" },
{ QVideoFrame::Format_YV12 , 12, XvPlanar, 3, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YVU" },
{ QVideoFrame::Format_UYVY , 16, XvPacked, 1, 8, 8, 8, 1, 2, 2, 1, 1, 1, "UYVY" },
{ QVideoFrame::Format_YUYV , 16, XvPacked, 1, 8, 8, 8, 1, 2, 2, 1, 1, 1, "YUY2" },
{ QVideoFrame::Format_YUYV , 16, XvPacked, 1, 8, 8, 8, 1, 2, 2, 1, 1, 1, "YUYV" },
{ QVideoFrame::Format_NV12 , 12, XvPlanar, 2, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YUV" },
{ QVideoFrame::Format_NV12 , 12, XvPlanar, 2, 8, 8, 8, 1, 2, 2, 1, 2, 2, "YVU" },
{ QVideoFrame::Format_Y8 , 8 , XvPlanar, 1, 8, 0, 0, 1, 0, 0, 1, 0, 0, "Y" }
};
QX11VideoSurface::QX11VideoSurface(QObject *parent)
: QAbstractVideoSurface(parent)
, m_winId(0)
, m_portId(0)
, m_gc(0)
, m_image(0)
{
}
QX11VideoSurface::~QX11VideoSurface()
{
if (m_gc)
XFreeGC(display(), m_gc);
if (m_portId != 0)
XvUngrabPort(display(), m_portId, 0);
}
WId QX11VideoSurface::winId() const
{
return m_winId;
}
void QX11VideoSurface::setWinId(WId id)
{
//qDebug() << "setWinID:" << id;
if (id == m_winId)
return;
if (m_image)
XFree(m_image);
if (m_gc) {
XFreeGC(display(), m_gc);
m_gc = 0;
}
if (m_portId != 0)
XvUngrabPort(display(), m_portId, 0);
m_supportedPixelFormats.clear();
m_formatIds.clear();
m_winId = id;
if (m_winId && findPort()) {
querySupportedFormats();
m_gc = XCreateGC(display(), m_winId, 0, 0);
if (m_image) {
m_image = 0;
if (!start(surfaceFormat())) {
QAbstractVideoSurface::stop();
qWarning() << "Failed to start video surface with format" << surfaceFormat();
}
}
} else {
qWarning() << "Failed to find XVideo port";
if (m_image) {
m_image = 0;
QAbstractVideoSurface::stop();
}
}
emit supportedFormatsChanged();
}
QRect QX11VideoSurface::displayRect() const
{
return m_displayRect;
}
void QX11VideoSurface::setDisplayRect(const QRect &rect)
{
m_displayRect = rect;
}
QRect QX11VideoSurface::viewport() const
{
return m_viewport;
}
void QX11VideoSurface::setViewport(const QRect &rect)
{
m_viewport = rect;
}
int QX11VideoSurface::brightness() const
{
return getAttribute("XV_BRIGHTNESS", m_brightnessRange.first, m_brightnessRange.second);
}
void QX11VideoSurface::setBrightness(int brightness)
{
setAttribute("XV_BRIGHTNESS", brightness, m_brightnessRange.first, m_brightnessRange.second);
}
int QX11VideoSurface::contrast() const
{
return getAttribute("XV_CONTRAST", m_contrastRange.first, m_contrastRange.second);
}
void QX11VideoSurface::setContrast(int contrast)
{
setAttribute("XV_CONTRAST", contrast, m_contrastRange.first, m_contrastRange.second);
}
int QX11VideoSurface::hue() const
{
return getAttribute("XV_HUE", m_hueRange.first, m_hueRange.second);
}
void QX11VideoSurface::setHue(int hue)
{
setAttribute("XV_HUE", hue, m_hueRange.first, m_hueRange.second);
}
int QX11VideoSurface::saturation() const
{
return getAttribute("XV_SATURATION", m_saturationRange.first, m_saturationRange.second);
}
void QX11VideoSurface::setSaturation(int saturation)
{
setAttribute("XV_SATURATION", saturation, m_saturationRange.first, m_saturationRange.second);
}
int QX11VideoSurface::getAttribute(const char *attribute, int minimum, int maximum) const
{
if (m_portId != 0) {
Display *disp = display();
Atom atom = XInternAtom(disp, attribute, True);
int value = 0;
XvGetPortAttribute(disp, m_portId, atom, &value);
return redistribute(value, minimum, maximum, -100, 100);
} else {
return 0;
}
}
void QX11VideoSurface::setAttribute(const char *attribute, int value, int minimum, int maximum)
{
if (m_portId != 0) {
Display *disp = display();
Atom atom = XInternAtom(disp, attribute, True);
XvSetPortAttribute(
disp, m_portId, atom, redistribute(value, -100, 100, minimum, maximum));
}
}
int QX11VideoSurface::redistribute(
int value, int fromLower, int fromUpper, int toLower, int toUpper)
{
return fromUpper != fromLower
? ((value - fromLower) * (toUpper - toLower) / (fromUpper - fromLower)) + toLower
: 0;
}
QList<QVideoFrame::PixelFormat> QX11VideoSurface::supportedPixelFormats(
QAbstractVideoBuffer::HandleType handleType) const
{
return handleType == QAbstractVideoBuffer::NoHandle || handleType == QAbstractVideoBuffer::XvShmImageHandle
? m_supportedPixelFormats
: QList<QVideoFrame::PixelFormat>();
}
bool QX11VideoSurface::start(const QVideoSurfaceFormat &format)
{
if (m_image)
XFree(m_image);
int xvFormatId = 0;
for (int i = 0; i < m_supportedPixelFormats.count(); ++i) {
if (m_supportedPixelFormats.at(i) == format.pixelFormat()) {
xvFormatId = m_formatIds.at(i);
break;
}
}
if (xvFormatId == 0) {
setError(UnsupportedFormatError);
} else {
XvImage *image = XvCreateImage(
display(),
m_portId,
xvFormatId,
0,
format.frameWidth(),
format.frameHeight());
if (!image) {
setError(ResourceError);
} else {
m_viewport = format.viewport();
m_image = image;
QVideoSurfaceFormat newFormat = format;
newFormat.setProperty("portId", QVariant(quint64(m_portId)));
newFormat.setProperty("xvFormatId", xvFormatId);
newFormat.setProperty("dataSize", image->data_size);
return QAbstractVideoSurface::start(newFormat);
}
}
if (m_image) {
m_image = 0;
QAbstractVideoSurface::stop();
}
return false;
}
void QX11VideoSurface::stop()
{
if (m_image) {
XFree(m_image);
m_image = 0;
QAbstractVideoSurface::stop();
}
}
bool QX11VideoSurface::present(const QVideoFrame &frame)
{
if (!m_image) {
setError(StoppedError);
return false;
} else if (m_image->width != frame.width() || m_image->height != frame.height()) {
setError(IncorrectFormatError);
return false;
} else {
QVideoFrame frameCopy(frame);
if (!frameCopy.map(QAbstractVideoBuffer::ReadOnly)) {
setError(IncorrectFormatError);
return false;
} else {
bool presented = false;
if (frame.handleType() != QAbstractVideoBuffer::XvShmImageHandle &&
m_image->data_size > frame.mappedBytes()) {
qWarning("Insufficient frame buffer size");
setError(IncorrectFormatError);
} else if (frame.handleType() != QAbstractVideoBuffer::XvShmImageHandle &&
m_image->num_planes > 0 &&
m_image->pitches[0] != frame.bytesPerLine()) {
qWarning("Incompatible frame pitches");
setError(IncorrectFormatError);
} else {
if (frame.handleType() != QAbstractVideoBuffer::XvShmImageHandle) {
m_image->data = reinterpret_cast<char *>(frameCopy.bits());
//qDebug() << "copy frame";
XvPutImage(
display(),
m_portId,
m_winId,
m_gc,
m_image,
m_viewport.x(),
m_viewport.y(),
m_viewport.width(),
m_viewport.height(),
m_displayRect.x(),
m_displayRect.y(),
m_displayRect.width(),
m_displayRect.height());
m_image->data = 0;
} else {
XvImage *img = frame.handle().value<XvImage*>();
//qDebug() << "render directly";
if (img)
XvShmPutImage(
display(),
m_portId,
m_winId,
m_gc,
img,
m_viewport.x(),
m_viewport.y(),
m_viewport.width(),
m_viewport.height(),
m_displayRect.x(),
m_displayRect.y(),
m_displayRect.width(),
m_displayRect.height(),
false);
}
presented = true;
}
frameCopy.unmap();
return presented;
}
}
}
Display *QX11VideoSurface::display() const
{
QWindow *window = QGuiApplication::focusWindow();
Display *display = (Display *)QGuiApplication::platformNativeInterface()->nativeResourceForWindow("Display", window);
return display;
}
bool QX11VideoSurface::findPort()
{
unsigned int count = 0;
XvAdaptorInfo *adaptors = 0;
bool portFound = false;
if (XvQueryAdaptors(display(), m_winId, &count, &adaptors) == Success) {
for (unsigned int i = 0; i < count && !portFound; ++i) {
if (adaptors[i].type & XvImageMask) {
m_portId = adaptors[i].base_id;
for (unsigned int j = 0; j < adaptors[i].num_ports && !portFound; ++j, ++m_portId)
portFound = XvGrabPort(display(), m_portId, 0) == Success;
}
}
XvFreeAdaptorInfo(adaptors);
}
return portFound;
}
void QX11VideoSurface::querySupportedFormats()
{
int count = 0;
if (XvImageFormatValues *imageFormats = XvListImageFormats(
display(), m_portId, &count)) {
const int rgbCount = sizeof(qt_xvRgbLookup) / sizeof(XvFormatRgb);
const int yuvCount = sizeof(qt_xvYuvLookup) / sizeof(XvFormatYuv);
for (int i = 0; i < count; ++i) {
switch (imageFormats[i].type) {
case XvRGB:
for (int j = 0; j < rgbCount; ++j) {
if (imageFormats[i] == qt_xvRgbLookup[j]) {
m_supportedPixelFormats.append(qt_xvRgbLookup[j].pixelFormat);
m_formatIds.append(imageFormats[i].id);
break;
}
}
break;
case XvYUV:
for (int j = 0; j < yuvCount; ++j) {
if (imageFormats[i] == qt_xvYuvLookup[j]) {
m_supportedPixelFormats.append(qt_xvYuvLookup[j].pixelFormat);
m_formatIds.append(imageFormats[i].id);
break;
}
}
break;
}
}
XFree(imageFormats);
}
m_brightnessRange = qMakePair(0, 0);
m_contrastRange = qMakePair(0, 0);
m_hueRange = qMakePair(0, 0);
m_saturationRange = qMakePair(0, 0);
if (XvAttribute *attributes = XvQueryPortAttributes(display(), m_portId, &count)) {
for (int i = 0; i < count; ++i) {
if (qstrcmp(attributes[i].name, "XV_BRIGHTNESS") == 0)
m_brightnessRange = qMakePair(attributes[i].min_value, attributes[i].max_value);
else if (qstrcmp(attributes[i].name, "XV_CONTRAST") == 0)
m_contrastRange = qMakePair(attributes[i].min_value, attributes[i].max_value);
else if (qstrcmp(attributes[i].name, "XV_HUE") == 0)
m_hueRange = qMakePair(attributes[i].min_value, attributes[i].max_value);
else if (qstrcmp(attributes[i].name, "XV_SATURATION") == 0)
m_saturationRange = qMakePair(attributes[i].min_value, attributes[i].max_value);
}
XFree(attributes);
}
}

View File

@@ -1,114 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QGSTREAMERVIDEOOVERLAY_H
#define QGSTREAMERVIDEOOVERLAY_H
#include <qvideowindowcontrol.h>
#include "qgstreamervideorendererinterface_p.h"
QT_BEGIN_NAMESPACE
class QAbstractVideoSurface;
class QX11VideoSurface;
class QGstreamerVideoOverlay : public QVideoWindowControl, public QGstreamerVideoRendererInterface
{
Q_OBJECT
Q_INTERFACES(QGstreamerVideoRendererInterface)
public:
QGstreamerVideoOverlay(QObject *parent = 0);
~QGstreamerVideoOverlay();
WId winId() const;
void setWinId(WId id);
QRect displayRect() const;
void setDisplayRect(const QRect &rect);
bool isFullScreen() const;
void setFullScreen(bool fullScreen);
QSize nativeSize() const;
Qt::AspectRatioMode aspectRatioMode() const;
void setAspectRatioMode(Qt::AspectRatioMode mode);
void repaint();
int brightness() const;
void setBrightness(int brightness);
int contrast() const;
void setContrast(int contrast);
int hue() const;
void setHue(int hue);
int saturation() const;
void setSaturation(int saturation);
QAbstractVideoSurface *surface() const;
GstElement *videoSink();
bool isReady() const { return winId() != 0; }
signals:
void sinkChanged();
void readyChanged(bool);
private slots:
void surfaceFormatChanged();
private:
void setScaledDisplayRect();
QX11VideoSurface *m_surface;
GstElement *m_videoSink;
Qt::AspectRatioMode m_aspectRatioMode;
QRect m_displayRect;
bool m_fullScreen;
};
QT_END_NAMESPACE
#endif

View File

@@ -50,7 +50,6 @@
QT_BEGIN_NAMESPACE
class QAbstractVideoSurface;
class QX11VideoSurface;
class QGstreamerVideoWindow : public QVideoWindowControl,
public QGstreamerVideoRendererInterface,

View File

@@ -1,150 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QGSTXVIMAGEBUFFER_P_H
#define QGSTXVIMAGEBUFFER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <qabstractvideobuffer.h>
#include <qvideosurfaceformat.h>
#include <QtCore/qmutex.h>
#include <QtCore/qwaitcondition.h>
#include <QtCore/qqueue.h>
#include <gst/gst.h>
#include "qgstbufferpoolinterface_p.h"
#include <X11/Xlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xv.h>
#include <X11/extensions/Xvlib.h>
QT_BEGIN_NAMESPACE
class QGstXvImageBufferPool;
class QGstXvImageBuffer {
public:
GstBuffer buffer;
QGstXvImageBufferPool *pool;
XvImage *xvImage;
XShmSegmentInfo shmInfo;
bool markedForDeletion;
static GType get_type(void);
static void class_init(gpointer g_class, gpointer class_data);
static void buffer_init(QGstXvImageBuffer *xvimage, gpointer g_class);
static void buffer_finalize(QGstXvImageBuffer * xvimage);
static GstBufferClass *parent_class;
};
QT_END_NAMESPACE
Q_DECLARE_METATYPE(XvImage*)
QT_BEGIN_NAMESPACE
class QGstXvImageBufferPool : public QObject, public QGstBufferPoolInterface {
Q_OBJECT
Q_INTERFACES(QGstBufferPoolInterface)
friend class QGstXvImageBuffer;
public:
QGstXvImageBufferPool(QObject *parent = 0);
virtual ~QGstXvImageBufferPool();
bool isFormatSupported(const QVideoSurfaceFormat &format) const;
GType bufferType() const;
GstBuffer *takeBuffer(const QVideoSurfaceFormat &format, GstCaps *caps);
void clear();
QAbstractVideoBuffer::HandleType handleType() const;
QAbstractVideoBuffer *prepareVideoBuffer(GstBuffer *buffer, int bytesPerLine);
virtual QStringList keys() const;
private slots:
void queuedAlloc();
void queuedDestroy();
void doClear();
void recycleBuffer(QGstXvImageBuffer *);
void destroyBuffer(QGstXvImageBuffer *);
private:
void doAlloc();
Display *display() const;
struct XvShmImage {
XvImage *xvImage;
XShmSegmentInfo shmInfo;
};
QMutex m_poolMutex;
QMutex m_allocMutex;
QWaitCondition m_allocWaitCondition;
QMutex m_destroyMutex;
QVideoSurfaceFormat m_format;
GstCaps *m_caps;
QList<QGstXvImageBuffer*> m_pool;
QList<QGstXvImageBuffer*> m_allBuffers;
QList<XvShmImage> m_imagesToDestroy;
Qt::HANDLE m_threadId;
};
QT_END_NAMESPACE
#endif

View File

@@ -69,11 +69,6 @@
QT_BEGIN_NAMESPACE
class QAbstractVideoSurface;
#ifdef HAVE_XVIDEO
class QGstXvImageBuffer;
class QGstXvImageBufferPool;
#endif
class QVideoSurfaceGstDelegate : public QObject
{
Q_OBJECT

View File

@@ -1,117 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QX11VIDEOSURFACE_H
#define QX11VIDEOSURFACE_H
#include <QtWidgets/qwidget.h>
#include <qabstractvideosurface.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xv.h>
#include <X11/extensions/Xvlib.h>
QT_BEGIN_NAMESPACE
class QX11VideoSurface : public QAbstractVideoSurface
{
Q_OBJECT
public:
QX11VideoSurface(QObject *parent = 0);
~QX11VideoSurface();
WId winId() const;
void setWinId(WId id);
QRect displayRect() const;
void setDisplayRect(const QRect &rect);
QRect viewport() const;
void setViewport(const QRect &rect);
int brightness() const;
void setBrightness(int brightness);
int contrast() const;
void setContrast(int contrast);
int hue() const;
void setHue(int hue);
int saturation() const;
void setSaturation(int saturation);
QList<QVideoFrame::PixelFormat> supportedPixelFormats(
QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;
bool start(const QVideoSurfaceFormat &format);
void stop();
bool present(const QVideoFrame &frame);
private:
Display *display() const;
WId m_winId;
XvPortID m_portId;
GC m_gc;
XvImage *m_image;
QList<QVideoFrame::PixelFormat> m_supportedPixelFormats;
QVector<int> m_formatIds;
QRect m_viewport;
QRect m_displayRect;
QPair<int, int> m_brightnessRange;
QPair<int, int> m_contrastRange;
QPair<int, int> m_hueRange;
QPair<int, int> m_saturationRange;
bool findPort();
void querySupportedFormats();
int getAttribute(const char *attribute, int minimum, int maximum) const;
void setAttribute(const char *attribute, int value, int minimum, int maximum);
static int redistribute(int value, int fromLower, int fromUpper, int toLower, int toUpper);
};
QT_END_NAMESPACE
#endif

View File

@@ -66,12 +66,11 @@
#include <private/qgstreameraudioinputselector_p.h>
#include <private/qgstreamervideoinputdevicecontrol_p.h>
#if defined(HAVE_WIDGETS)
#include <private/qgstreamervideooverlay_p.h>
#include <private/qgstreamervideowindow_p.h>
#include <private/qgstreamervideowidget_p.h>
#endif
#include <private/qgstreamervideowindow_p.h>
#include <private/qgstreamervideorenderer_p.h>
#if defined(Q_WS_MAEMO_6) && defined(__arm__)
@@ -101,8 +100,8 @@ CameraBinService::CameraBinService(const QString &service, QObject *parent):
m_videoOutput = 0;
m_videoRenderer = 0;
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
m_videoWindow = 0;
#if defined(HAVE_WIDGETS)
m_videoWidgetControl = 0;
#endif
m_imageCaptureControl = 0;
@@ -125,12 +124,13 @@ CameraBinService::CameraBinService(const QString &service, QObject *parent):
m_videoRenderer = new QGstreamerVideoRenderer(this);
#endif
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
#ifdef Q_WS_MAEMO_6
m_videoWindow = new QGstreamerVideoWindow(this, "omapxvsink");
#else
m_videoWindow = new QGstreamerVideoOverlay(this);
m_videoWindow = new QGstreamerVideoWindow(this);
#endif
#if defined(HAVE_WIDGETS)
m_videoWidgetControl = new QGstreamerVideoWidgetControl(this);
#endif
@@ -169,11 +169,11 @@ QMediaControl *CameraBinService::requestControl(const char *name)
if (!m_videoOutput) {
if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
m_videoOutput = m_videoRenderer;
}
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
} else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
m_videoOutput = m_videoWindow;
} else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
}
#if defined(HAVE_WIDGETS)
else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
m_videoOutput = m_videoWidgetControl;
}
#endif

View File

@@ -56,7 +56,6 @@ class CameraBinControl;
class QGstreamerMessage;
class QGstreamerBusHelper;
class QGstreamerVideoRenderer;
class QGstreamerVideoOverlay;
class QGstreamerVideoWidgetControl;
class QGstreamerElementFactory;
class CameraBinMetaData;
@@ -89,8 +88,8 @@ private:
QMediaControl *m_videoOutput;
QMediaControl *m_videoRenderer;
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
QMediaControl *m_videoWindow;
#if defined(HAVE_WIDGETS)
QGstreamerVideoWidgetControl *m_videoWidgetControl;
#endif
CameraBinImageCapture *m_imageCaptureControl;

View File

@@ -26,11 +26,6 @@ config_resourcepolicy {
PKGCONFIG += libresourceqt5
}
config_xvideo:qtHaveModule(widgets) {
DEFINES += HAVE_XVIDEO
LIBS += -lXv -lX11 -lXext
}
config_gstreamer_appsrc {
PKGCONFIG += gstreamer-app-0.10
DEFINES += HAVE_GST_APPSRC

View File

@@ -57,9 +57,9 @@
#include <private/qgstreameraudioprobecontrol_p.h>
#include <private/qgstreamervideorenderer_p.h>
#include <private/qgstreamervideowindow_p.h>
#if defined(HAVE_WIDGETS)
#include <private/qgstreamervideooverlay_p.h>
#include <private/qgstreamervideowidget_p.h>
#endif
@@ -80,8 +80,8 @@ QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObje
m_videoOutput = 0;
m_videoRenderer = 0;
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
m_videoWindow = 0;
#if defined(HAVE_WIDGETS)
m_videoWidgetControl = 0;
#endif
m_imageCaptureControl = 0;
@@ -104,9 +104,9 @@ QGstreamerCaptureService::QGstreamerCaptureService(const QString &service, QObje
m_videoInput->setDevice(m_videoInputDevice->deviceName(m_videoInputDevice->selectedDevice()));
m_videoRenderer = new QGstreamerVideoRenderer(this);
m_videoWindow = new QGstreamerVideoWindow(this);
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
m_videoWindow = new QGstreamerVideoOverlay(this);
#if defined(HAVE_WIDGETS)
m_videoWidgetControl = new QGstreamerVideoWidgetControl(this);
#endif
m_imageCaptureControl = new QGstreamerImageCaptureControl(m_captureSession);
@@ -175,11 +175,11 @@ QMediaControl *QGstreamerCaptureService::requestControl(const char *name)
if (!m_videoOutput) {
if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
m_videoOutput = m_videoRenderer;
}
#if defined(HAVE_WIDGETS) && defined(HAVE_XVIDEO)
else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
} else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
m_videoOutput = m_videoWindow;
} else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
}
#if defined(HAVE_WIDGETS)
else if (qstrcmp(name, QVideoWidgetControl_iid) == 0) {
m_videoOutput = m_videoWidgetControl;
}
#endif

View File

@@ -56,7 +56,6 @@ class QGstreamerCameraControl;
class QGstreamerMessage;
class QGstreamerBusHelper;
class QGstreamerVideoRenderer;
class QGstreamerVideoOverlay;
class QGstreamerVideoWidgetControl;
class QGstreamerElementFactory;
class QGstreamerCaptureMetaDataControl;
@@ -88,8 +87,8 @@ private:
QMediaControl *m_videoOutput;
QGstreamerVideoRenderer *m_videoRenderer;
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
QMediaControl *m_videoWindow;
#if defined(HAVE_WIDGETS)
QMediaControl *m_videoWidgetControl;
#endif
QGstreamerImageCaptureControl *m_imageCaptureControl;

View File

@@ -53,11 +53,9 @@
#include "qgstreameravailabilitycontrol.h"
#if defined(HAVE_WIDGETS)
#include <private/qgstreamervideooverlay_p.h>
#include <private/qgstreamervideowindow_p.h>
#include <private/qgstreamervideowidget_p.h>
#endif
#include <private/qgstreamervideowindow_p.h>
#include <private/qgstreamervideorenderer_p.h>
#if defined(Q_WS_MAEMO_6) && defined(__arm__)
@@ -78,8 +76,8 @@ QGstreamerPlayerService::QGstreamerPlayerService(QObject *parent):
QMediaService(parent)
, m_videoOutput(0)
, m_videoRenderer(0)
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
, m_videoWindow(0)
#if defined(HAVE_WIDGETS)
, m_videoWidget(0)
#endif
, m_videoReferenceCount(0)
@@ -96,12 +94,13 @@ QGstreamerPlayerService::QGstreamerPlayerService(QObject *parent):
m_videoRenderer = new QGstreamerVideoRenderer(this);
#endif
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
#ifdef Q_WS_MAEMO_6
m_videoWindow = new QGstreamerVideoWindow(this, "omapxvsink");
#else
m_videoWindow = new QGstreamerVideoOverlay(this);
m_videoWindow = new QGstreamerVideoWindow(this);
#endif
#if defined(HAVE_WIDGETS)
m_videoWidget = new QGstreamerVideoWidgetControl(this);
#endif
}
@@ -146,11 +145,11 @@ QMediaControl *QGstreamerPlayerService::requestControl(const char *name)
if (!m_videoOutput) {
if (qstrcmp(name, QVideoRendererControl_iid) == 0)
m_videoOutput = m_videoRenderer;
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
else if (qstrcmp(name, QVideoWindowControl_iid) == 0)
m_videoOutput = m_videoWindow;
#if defined(HAVE_WIDGETS)
else if (qstrcmp(name, QVideoWidgetControl_iid) == 0)
m_videoOutput = m_videoWidget;
else if (qstrcmp(name, QVideoWindowControl_iid) == 0)
m_videoOutput = m_videoWindow;
#endif
if (m_videoOutput) {

View File

@@ -58,7 +58,6 @@ class QGstreamerPlayerSession;
class QGstreamerMetaDataProvider;
class QGstreamerStreamsControl;
class QGstreamerVideoRenderer;
class QGstreamerVideoOverlay;
class QGstreamerVideoWidgetControl;
class QGStreamerAvailabilityControl;
@@ -81,8 +80,8 @@ private:
QMediaControl *m_videoOutput;
QMediaControl *m_videoRenderer;
#if defined(HAVE_XVIDEO) && defined(HAVE_WIDGETS)
QMediaControl *m_videoWindow;
#if defined(HAVE_WIDGETS)
QMediaControl *m_videoWidget;
#endif