qtmobility/plugins/multimedia/gstreamer/qvideosurfacegstsink.cpp
changeset 14 6fbed849b4f4
parent 11 06b8e2af4411
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
    37 **
    37 **
    38 ** $QT_END_LICENSE$
    38 ** $QT_END_LICENSE$
    39 **
    39 **
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include <QtMultimedia/QAbstractVideoSurface>
    42 #include <qabstractvideosurface.h>
    43 #include <QtMultimedia/QVideoFrame>
    43 #include <qvideoframe.h>
    44 #include <QDebug>
    44 #include <QDebug>
    45 #include <QMap>
    45 #include <QMap>
    46 #include <QDebug>
    46 #include <QDebug>
    47 #include <QThread>
    47 #include <QThread>
       
    48 
       
    49 #include "qgstvideobuffer.h"
       
    50 
       
    51 #if defined(Q_WS_X11) && !defined(QT_NO_XVIDEO)
    48 #include <QtGui/qx11info_x11.h>
    52 #include <QtGui/qx11info_x11.h>
       
    53 #include "qgstxvimagebuffer.h"
       
    54 #endif
    49 
    55 
    50 #include "qvideosurfacegstsink.h"
    56 #include "qvideosurfacegstsink.h"
    51 
    57 
    52 #include "qgstvideobuffer.h"
       
    53 #include "qgstxvimagebuffer.h"
       
    54 
    58 
    55 
    59 
    56 Q_DECLARE_METATYPE(QVideoSurfaceFormat)
    60 Q_DECLARE_METATYPE(QVideoSurfaceFormat)
    57 
    61 
    58 QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(QAbstractVideoSurface *surface)
    62 QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(QAbstractVideoSurface *surface)
    59     : m_surface(surface)
    63     : m_surface(surface)
    60     , m_renderReturn(GST_FLOW_ERROR)
    64     , m_renderReturn(GST_FLOW_ERROR)
    61     , m_bytesPerLine(0)
    65     , m_bytesPerLine(0)
    62 {
    66 {
    63     m_supportedPixelFormats = m_surface->supportedPixelFormats();
    67     if (m_surface) {
    64 
    68         m_supportedPixelFormats = m_surface->supportedPixelFormats();
    65     connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
    69         connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
       
    70     }
    66 }
    71 }
    67 
    72 
    68 QList<QVideoFrame::PixelFormat> QVideoSurfaceGstDelegate::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
    73 QList<QVideoFrame::PixelFormat> QVideoSurfaceGstDelegate::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
    69 {
    74 {
    70     QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
    75     QMutexLocker locker(const_cast<QMutex *>(&m_mutex));
    71 
    76 
    72     if (handleType == QAbstractVideoBuffer::NoHandle)
    77     if (handleType == QAbstractVideoBuffer::NoHandle || !m_surface)
    73         return m_supportedPixelFormats;
    78         return m_supportedPixelFormats;
    74     else
    79     else
    75         return m_surface->supportedPixelFormats(handleType);
    80         return m_surface->supportedPixelFormats(handleType);
    76 }
    81 }
    77 
    82 
    81     return m_format;
    86     return m_format;
    82 }
    87 }
    83 
    88 
    84 bool QVideoSurfaceGstDelegate::start(const QVideoSurfaceFormat &format, int bytesPerLine)
    89 bool QVideoSurfaceGstDelegate::start(const QVideoSurfaceFormat &format, int bytesPerLine)
    85 {
    90 {
       
    91     if (!m_surface)
       
    92         return false;
       
    93 
    86     QMutexLocker locker(&m_mutex);
    94     QMutexLocker locker(&m_mutex);
    87 
    95 
    88     m_format = format;
    96     m_format = format;
    89     m_bytesPerLine = bytesPerLine;
    97     m_bytesPerLine = bytesPerLine;
    90 
    98 
   101     return m_started;
   109     return m_started;
   102 }
   110 }
   103 
   111 
   104 void QVideoSurfaceGstDelegate::stop()
   112 void QVideoSurfaceGstDelegate::stop()
   105 {
   113 {
       
   114     if (!m_surface)
       
   115         return;
       
   116 
   106     QMutexLocker locker(&m_mutex);
   117     QMutexLocker locker(&m_mutex);
   107 
   118 
   108     if (QThread::currentThread() == thread()) {
   119     if (QThread::currentThread() == thread()) {
   109         if (!m_surface.isNull())
   120         if (!m_surface.isNull())
   110             m_surface->stop();
   121             m_surface->stop();
   123     return m_surface->isActive();
   134     return m_surface->isActive();
   124 }
   135 }
   125 
   136 
   126 GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
   137 GstFlowReturn QVideoSurfaceGstDelegate::render(GstBuffer *buffer)
   127 {
   138 {
       
   139     if (!m_surface)
       
   140         return GST_FLOW_NOT_NEGOTIATED;
       
   141 
   128     QMutexLocker locker(&m_mutex);
   142     QMutexLocker locker(&m_mutex);
   129 
   143 
   130     QGstVideoBuffer *videoBuffer = 0;
   144     QGstVideoBuffer *videoBuffer = 0;
   131 
   145 
       
   146 #if defined(Q_WS_X11) && !defined(QT_NO_XVIDEO)
   132     if (G_TYPE_CHECK_INSTANCE_TYPE(buffer, QGstXvImageBuffer::get_type())) {
   147     if (G_TYPE_CHECK_INSTANCE_TYPE(buffer, QGstXvImageBuffer::get_type())) {
   133         QGstXvImageBuffer *xvBuffer = reinterpret_cast<QGstXvImageBuffer *>(buffer);
   148         QGstXvImageBuffer *xvBuffer = reinterpret_cast<QGstXvImageBuffer *>(buffer);
   134         QVariant handle = QVariant::fromValue(xvBuffer->xvImage);
   149         QVariant handle = QVariant::fromValue(xvBuffer->xvImage);
   135         videoBuffer = new QGstVideoBuffer(buffer, m_bytesPerLine, XvHandleType, handle);
   150         videoBuffer = new QGstVideoBuffer(buffer, m_bytesPerLine, XvHandleType, handle);
   136     } else
   151     } else
       
   152 #endif
   137         videoBuffer = new QGstVideoBuffer(buffer, m_bytesPerLine);
   153         videoBuffer = new QGstVideoBuffer(buffer, m_bytesPerLine);
   138 
   154 
   139     m_frame = QVideoFrame(
   155     m_frame = QVideoFrame(
   140             videoBuffer,
   156             videoBuffer,
   141             m_format.frameSize(),
   157             m_format.frameSize(),
   208 
   224 
   209 void QVideoSurfaceGstDelegate::supportedFormatsChanged()
   225 void QVideoSurfaceGstDelegate::supportedFormatsChanged()
   210 {
   226 {
   211     QMutexLocker locker(&m_mutex);
   227     QMutexLocker locker(&m_mutex);
   212 
   228 
   213     m_supportedPixelFormats = m_surface->supportedPixelFormats();
   229     m_supportedPixelFormats.clear();
       
   230     if (m_surface)
       
   231         m_supportedPixelFormats = m_surface->supportedPixelFormats();
   214 }
   232 }
   215 
   233 
   216 struct YuvFormat
   234 struct YuvFormat
   217 {
   235 {
   218     QVideoFrame::PixelFormat pixelFormat;
   236     QVideoFrame::PixelFormat pixelFormat;
   383     VO_SINK(instance);
   401     VO_SINK(instance);
   384 
   402 
   385     Q_UNUSED(g_class);
   403     Q_UNUSED(g_class);
   386 
   404 
   387     sink->delegate = 0;
   405     sink->delegate = 0;
       
   406 #if defined(Q_WS_X11) && !defined(QT_NO_XVIDEO)
   388     sink->pool = new QGstXvImageBufferPool();
   407     sink->pool = new QGstXvImageBufferPool();
       
   408 #endif
   389     sink->lastRequestedCaps = 0;
   409     sink->lastRequestedCaps = 0;
   390     sink->lastBufferCaps = 0;
   410     sink->lastBufferCaps = 0;
   391     sink->lastSurfaceFormat = new QVideoSurfaceFormat;
   411     sink->lastSurfaceFormat = new QVideoSurfaceFormat;
   392 }
   412 }
   393 
   413 
   394 void QVideoSurfaceGstSink::finalize(GObject *object)
   414 void QVideoSurfaceGstSink::finalize(GObject *object)
   395 {
   415 {
   396     VO_SINK(object);
   416     VO_SINK(object);
       
   417 #if defined(Q_WS_X11) && !defined(QT_NO_XVIDEO)
   397     delete sink->pool;
   418     delete sink->pool;
   398     sink->pool = 0;
   419     sink->pool = 0;
       
   420 #endif
       
   421 
   399     delete sink->lastSurfaceFormat;
   422     delete sink->lastSurfaceFormat;
   400     sink->lastSurfaceFormat = 0;
   423     sink->lastSurfaceFormat = 0;
   401 
   424 
   402     if (sink->lastBufferCaps)
   425     if (sink->lastBufferCaps)
   403         gst_caps_unref(sink->lastBufferCaps);
   426         gst_caps_unref(sink->lastBufferCaps);
   584     Q_UNUSED(offset);
   607     Q_UNUSED(offset);
   585     Q_UNUSED(size);
   608     Q_UNUSED(size);
   586 
   609 
   587     *buffer = 0;
   610     *buffer = 0;
   588 
   611 
       
   612 #if defined(Q_WS_X11) && !defined(QT_NO_XVIDEO)
       
   613 
   589     if (sink->lastRequestedCaps && gst_caps_is_equal(sink->lastRequestedCaps, caps)) {
   614     if (sink->lastRequestedCaps && gst_caps_is_equal(sink->lastRequestedCaps, caps)) {
   590         //qDebug() << "reusing last caps";
   615         //qDebug() << "reusing last caps";
   591         *buffer = GST_BUFFER(sink->pool->takeBuffer(*sink->lastSurfaceFormat, sink->lastBufferCaps));
   616         *buffer = GST_BUFFER(sink->pool->takeBuffer(*sink->lastSurfaceFormat, sink->lastBufferCaps));
   592         return GST_FLOW_OK;
   617         return GST_FLOW_OK;
   593     }
   618     }
   645 
   670 
   646     *sink->lastSurfaceFormat = surfaceFormat;
   671     *sink->lastSurfaceFormat = surfaceFormat;
   647 
   672 
   648     *buffer =  GST_BUFFER(sink->pool->takeBuffer(surfaceFormat, intersection));
   673     *buffer =  GST_BUFFER(sink->pool->takeBuffer(surfaceFormat, intersection));
   649 
   674 
       
   675 #endif
   650     return GST_FLOW_OK;
   676     return GST_FLOW_OK;
   651 }
   677 }
   652 
   678 
   653 gboolean QVideoSurfaceGstSink::start(GstBaseSink *base)
   679 gboolean QVideoSurfaceGstSink::start(GstBaseSink *base)
   654 {
   680 {