summaryrefslogtreecommitdiffstats
path: root/src/gsttools/qvideosurfacegstsink.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsttools/qvideosurfacegstsink.cpp')
-rw-r--r--src/gsttools/qvideosurfacegstsink.cpp246
1 files changed, 24 insertions, 222 deletions
diff --git a/src/gsttools/qvideosurfacegstsink.cpp b/src/gsttools/qvideosurfacegstsink.cpp
index f3e2d884c..36644581e 100644
--- a/src/gsttools/qvideosurfacegstsink.cpp
+++ b/src/gsttools/qvideosurfacegstsink.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
@@ -10,9 +10,9 @@
** 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.
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** 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
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@@ -41,8 +41,13 @@
#include <private/qmediapluginloader_p.h>
#include "qgstvideobuffer_p.h"
+#include "qgstutils_p.h"
#include "qvideosurfacegstsink_p.h"
+#if GST_VERSION_MAJOR >=1
+#include <gst/video/video.h>
+#endif
+
//#define DEBUG_VIDEO_SURFACE_SINK
QT_BEGIN_NAMESPACE
@@ -62,10 +67,12 @@ QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
if (m_surface) {
foreach (QObject *instance, bufferPoolLoader()->instances(QGstBufferPoolPluginKey)) {
QGstBufferPoolInterface* plugin = qobject_cast<QGstBufferPoolInterface*>(instance);
+
if (plugin) {
m_pools.append(plugin);
}
}
+
updateSupportedFormats();
connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(updateSupportedFormats()));
}
@@ -191,13 +198,15 @@ GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
m_format.frameSize(),
m_format.pixelFormat());
- QVideoSurfaceGstSink::setFrameTimeStamps(&m_frame, buffer);
+ QGstUtils::setFrameTimeStamps(&m_frame, buffer);
m_renderReturn = GST_FLOW_OK;
if (QThread::currentThread() == thread()) {
if (!m_surface.isNull())
m_surface->present(m_frame);
+ else
+ qWarning() << "m_surface.isNull().";
} else {
QMetaObject::invokeMethod(this, "queuedRender", Qt::QueuedConnection);
m_renderCondition.wait(&m_mutex, 300);
@@ -283,90 +292,6 @@ void QVideoSurfaceGstDelegate::updateSupportedFormats()
}
}
-struct YuvFormat
-{
- QVideoFrame::PixelFormat pixelFormat;
- guint32 fourcc;
- int bitsPerPixel;
-};
-
-static const YuvFormat qt_yuvColorLookup[] =
-{
- { QVideoFrame::Format_YUV420P, GST_MAKE_FOURCC('I','4','2','0'), 8 },
- { QVideoFrame::Format_YV12, GST_MAKE_FOURCC('Y','V','1','2'), 8 },
- { QVideoFrame::Format_UYVY, GST_MAKE_FOURCC('U','Y','V','Y'), 16 },
- { QVideoFrame::Format_YUYV, GST_MAKE_FOURCC('Y','U','Y','2'), 16 },
- { QVideoFrame::Format_NV12, GST_MAKE_FOURCC('N','V','1','2'), 8 },
- { QVideoFrame::Format_NV21, GST_MAKE_FOURCC('N','V','2','1'), 8 },
- { QVideoFrame::Format_AYUV444, GST_MAKE_FOURCC('A','Y','U','V'), 32 }
-};
-
-static int indexOfYuvColor(QVideoFrame::PixelFormat format)
-{
- const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);
-
- for (int i = 0; i < count; ++i)
- if (qt_yuvColorLookup[i].pixelFormat == format)
- return i;
-
- return -1;
-}
-
-static int indexOfYuvColor(guint32 fourcc)
-{
- const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);
-
- for (int i = 0; i < count; ++i)
- if (qt_yuvColorLookup[i].fourcc == fourcc)
- return i;
-
- return -1;
-}
-
-struct RgbFormat
-{
- QVideoFrame::PixelFormat pixelFormat;
- int bitsPerPixel;
- int depth;
- int endianness;
- int red;
- int green;
- int blue;
- int alpha;
-};
-
-static const RgbFormat qt_rgbColorLookup[] =
-{
- { QVideoFrame::Format_RGB32 , 32, 24, 4321, 0x0000FF00, 0x00FF0000, int(0xFF000000), 0x00000000 },
- { QVideoFrame::Format_RGB32 , 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
- { QVideoFrame::Format_BGR32 , 32, 24, 4321, int(0xFF000000), 0x00FF0000, 0x0000FF00, 0x00000000 },
- { QVideoFrame::Format_BGR32 , 32, 24, 1234, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
- { QVideoFrame::Format_ARGB32, 32, 24, 4321, 0x0000FF00, 0x00FF0000, int(0xFF000000), 0x000000FF },
- { QVideoFrame::Format_ARGB32, 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, int(0xFF000000) },
- { QVideoFrame::Format_RGB24 , 24, 24, 4321, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
- { QVideoFrame::Format_BGR24 , 24, 24, 4321, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
- { QVideoFrame::Format_RGB565, 16, 16, 1234, 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }
-};
-
-static int indexOfRgbColor(
- int bits, int depth, int endianness, int red, int green, int blue, int alpha)
-{
- const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat);
-
- for (int i = 0; i < count; ++i) {
- if (qt_rgbColorLookup[i].bitsPerPixel == bits
- && qt_rgbColorLookup[i].depth == depth
- && qt_rgbColorLookup[i].endianness == endianness
- && qt_rgbColorLookup[i].red == red
- && qt_rgbColorLookup[i].green == green
- && qt_rgbColorLookup[i].blue == blue
- && qt_rgbColorLookup[i].alpha == alpha) {
- return i;
- }
- }
- return -1;
-}
-
static GstVideoSinkClass *sink_parent_class;
#define VO_SINK(s) QVideoSurfaceGstSink *sink(reinterpret_cast<QVideoSurfaceGstSink *>(s))
@@ -494,8 +419,6 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
{
VO_SINK(base);
- GstCaps *caps = gst_caps_new_empty();
-
// Find the supported pixel formats
// with buffer pool specific formats listed first
QList<QVideoFrame::PixelFormat> supportedFormats;
@@ -503,6 +426,7 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
QList<QVideoFrame::PixelFormat> poolHandleFormats;
sink->delegate->poolMutex()->lock();
QGstBufferPoolInterface *pool = sink->delegate->pool();
+
if (pool)
poolHandleFormats = sink->delegate->supportedPixelFormats(pool->handleType());
sink->delegate->poolMutex()->unlock();
@@ -513,47 +437,7 @@ GstCaps *QVideoSurfaceGstSink::get_caps(GstBaseSink *base)
supportedFormats.append(format);
}
- foreach (QVideoFrame::PixelFormat format, supportedFormats) {
- int index = indexOfYuvColor(format);
-
- if (index != -1) {
- gst_caps_append_structure(caps, gst_structure_new(
- "video/x-raw-yuv",
- "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
- "width" , GST_TYPE_INT_RANGE, 1, INT_MAX,
- "height" , GST_TYPE_INT_RANGE, 1, INT_MAX,
- "format" , GST_TYPE_FOURCC, qt_yuvColorLookup[index].fourcc,
- NULL));
- continue;
- }
-
- const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat);
-
- for (int i = 0; i < count; ++i) {
- if (qt_rgbColorLookup[i].pixelFormat == format) {
- GstStructure *structure = gst_structure_new(
- "video/x-raw-rgb",
- "framerate" , GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
- "width" , GST_TYPE_INT_RANGE, 1, INT_MAX,
- "height" , GST_TYPE_INT_RANGE, 1, INT_MAX,
- "bpp" , G_TYPE_INT, qt_rgbColorLookup[i].bitsPerPixel,
- "depth" , G_TYPE_INT, qt_rgbColorLookup[i].depth,
- "endianness", G_TYPE_INT, qt_rgbColorLookup[i].endianness,
- "red_mask" , G_TYPE_INT, qt_rgbColorLookup[i].red,
- "green_mask", G_TYPE_INT, qt_rgbColorLookup[i].green,
- "blue_mask" , G_TYPE_INT, qt_rgbColorLookup[i].blue,
- NULL);
-
- if (qt_rgbColorLookup[i].alpha != 0) {
- gst_structure_set(
- structure, "alpha_mask", G_TYPE_INT, qt_rgbColorLookup[i].alpha, NULL);
- }
- gst_caps_append_structure(caps, structure);
- }
- }
- }
-
- return caps;
+ return QGstUtils::capsForFormats(supportedFormats);
}
gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
@@ -575,7 +459,7 @@ gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
QAbstractVideoBuffer::HandleType handleType =
pool ? pool->handleType() : QAbstractVideoBuffer::NoHandle;
- QVideoSurfaceFormat format = formatForCaps(caps, &bytesPerLine, handleType);
+ QVideoSurfaceFormat format = QGstUtils::formatForCaps(caps, &bytesPerLine, handleType);
if (sink->delegate->isActive()) {
QVideoSurfaceFormat surfaceFormst = sink->delegate->surfaceFormat();
@@ -592,7 +476,7 @@ gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
sink->lastRequestedCaps = 0;
#ifdef DEBUG_VIDEO_SURFACE_SINK
- qDebug() << "Staring video surface, format:";
+ qDebug() << "Starting video surface, format:";
qDebug() << format;
qDebug() << "bytesPerLine:" << bytesPerLine;
#endif
@@ -606,87 +490,6 @@ gboolean QVideoSurfaceGstSink::set_caps(GstBaseSink *base, GstCaps *caps)
return FALSE;
}
-QVideoSurfaceFormat QVideoSurfaceGstSink::formatForCaps(GstCaps *caps, int *bytesPerLine, QAbstractVideoBuffer::HandleType handleType)
-{
- const GstStructure *structure = gst_caps_get_structure(caps, 0);
-
- QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_Invalid;
- int bitsPerPixel = 0;
-
- QSize size;
- gst_structure_get_int(structure, "width", &size.rwidth());
- gst_structure_get_int(structure, "height", &size.rheight());
-
- if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
- guint32 fourcc = 0;
- gst_structure_get_fourcc(structure, "format", &fourcc);
-
- int index = indexOfYuvColor(fourcc);
- if (index != -1) {
- pixelFormat = qt_yuvColorLookup[index].pixelFormat;
- bitsPerPixel = qt_yuvColorLookup[index].bitsPerPixel;
- }
- } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
- int depth = 0;
- int endianness = 0;
- int red = 0;
- int green = 0;
- int blue = 0;
- int alpha = 0;
-
- gst_structure_get_int(structure, "bpp", &bitsPerPixel);
- gst_structure_get_int(structure, "depth", &depth);
- gst_structure_get_int(structure, "endianness", &endianness);
- gst_structure_get_int(structure, "red_mask", &red);
- gst_structure_get_int(structure, "green_mask", &green);
- gst_structure_get_int(structure, "blue_mask", &blue);
- gst_structure_get_int(structure, "alpha_mask", &alpha);
-
- int index = indexOfRgbColor(bitsPerPixel, depth, endianness, red, green, blue, alpha);
-
- if (index != -1)
- pixelFormat = qt_rgbColorLookup[index].pixelFormat;
- }
-
- if (pixelFormat != QVideoFrame::Format_Invalid) {
- QVideoSurfaceFormat format(size, pixelFormat, handleType);
-
- QPair<int, int> rate;
- gst_structure_get_fraction(structure, "framerate", &rate.first, &rate.second);
-
- if (rate.second)
- format.setFrameRate(qreal(rate.first)/rate.second);
-
- gint aspectNum = 0;
- gint aspectDenum = 0;
- if (gst_structure_get_fraction(
- structure, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) {
- if (aspectDenum > 0)
- format.setPixelAspectRatio(aspectNum, aspectDenum);
- }
-
- if (bytesPerLine)
- *bytesPerLine = ((size.width() * bitsPerPixel / 8) + 3) & ~3;
-
- return format;
- }
-
- return QVideoSurfaceFormat();
-}
-
-void QVideoSurfaceGstSink::setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer)
-{
- // GStreamer uses nanoseconds, Qt uses microseconds
- qint64 startTime = GST_BUFFER_TIMESTAMP(buffer);
- if (startTime >= 0) {
- frame->setStartTime(startTime/G_GINT64_CONSTANT (1000));
-
- qint64 duration = GST_BUFFER_DURATION(buffer);
- if (duration >= 0)
- frame->setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000));
- }
-}
-
GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
GstBaseSink *base, guint64 offset, guint size, GstCaps *caps, GstBuffer **buffer)
{
@@ -731,7 +534,7 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
if (sink->delegate->isActive()) {
//if format was changed, restart the surface
- QVideoSurfaceFormat format = formatForCaps(intersection);
+ QVideoSurfaceFormat format = QGstUtils::formatForCaps(intersection);
QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat();
if (format.pixelFormat() != surfaceFormat.pixelFormat() ||
@@ -749,7 +552,7 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
QAbstractVideoBuffer::HandleType handleType =
pool ? pool->handleType() : QAbstractVideoBuffer::NoHandle;
- QVideoSurfaceFormat format = formatForCaps(intersection, &bytesPerLine, handleType);
+ QVideoSurfaceFormat format = QGstUtils::formatForCaps(intersection, &bytesPerLine, handleType);
if (!sink->delegate->start(format, bytesPerLine)) {
qWarning() << "failed to start video surface";
@@ -763,7 +566,7 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
QVideoSurfaceFormat surfaceFormat = sink->delegate->surfaceFormat();
if (!pool->isFormatSupported(surfaceFormat)) {
- //qDebug() << "sink doesn't support native pool format, skip custom buffers allocation";
+ qDebug() << "sink doesn't support native pool format, skip custom buffers allocation";
return GST_FLOW_OK;
}
@@ -787,7 +590,6 @@ GstFlowReturn QVideoSurfaceGstSink::buffer_alloc(
gboolean QVideoSurfaceGstSink::start(GstBaseSink *base)
{
Q_UNUSED(base);
-
return TRUE;
}