From b8cc86956ae45a6d07dfca04301e1b4905615ee7 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Tue, 25 Aug 2009 08:33:55 +1000 Subject: Integrate QAbstractVideoSurface API. This introduces a QAbstractVideoSurface interface for implementing arbitrary video outputs, and a QVideoFrame type. Also included is the QVideoSurfaceFormat class which is used to configure the input to a video surface, and the QAbstractVideoBuffer class which allows QVideoFrames to be constructed from non-native frame types. Reviewed-by: Dmytro Poplavskiy --- src/multimedia/multimedia.pro | 13 +- src/multimedia/video/qabstractvideobuffer.cpp | 199 +++++++ src/multimedia/video/qabstractvideobuffer.h | 104 ++++ src/multimedia/video/qabstractvideobuffer_p.h | 73 +++ src/multimedia/video/qabstractvideosurface.cpp | 268 +++++++++ src/multimedia/video/qabstractvideosurface.h | 110 ++++ src/multimedia/video/qabstractvideosurface_p.h | 79 +++ src/multimedia/video/qimagevideobuffer.cpp | 102 ++++ src/multimedia/video/qimagevideobuffer_p.h | 79 +++ src/multimedia/video/qmemoryvideobuffer.cpp | 129 +++++ src/multimedia/video/qmemoryvideobuffer_p.h | 83 +++ src/multimedia/video/qvideoframe.cpp | 742 +++++++++++++++++++++++++ src/multimedia/video/qvideoframe.h | 169 ++++++ src/multimedia/video/qvideosurfaceformat.cpp | 742 +++++++++++++++++++++++++ src/multimedia/video/qvideosurfaceformat.h | 157 ++++++ src/multimedia/video/video.pri | 21 + 16 files changed, 3064 insertions(+), 6 deletions(-) create mode 100644 src/multimedia/video/qabstractvideobuffer.cpp create mode 100644 src/multimedia/video/qabstractvideobuffer.h create mode 100644 src/multimedia/video/qabstractvideobuffer_p.h create mode 100644 src/multimedia/video/qabstractvideosurface.cpp create mode 100644 src/multimedia/video/qabstractvideosurface.h create mode 100644 src/multimedia/video/qabstractvideosurface_p.h create mode 100644 src/multimedia/video/qimagevideobuffer.cpp create mode 100644 src/multimedia/video/qimagevideobuffer_p.h create mode 100644 src/multimedia/video/qmemoryvideobuffer.cpp create mode 100644 src/multimedia/video/qmemoryvideobuffer_p.h create mode 100644 src/multimedia/video/qvideoframe.cpp create mode 100644 src/multimedia/video/qvideoframe.h create mode 100644 src/multimedia/video/qvideosurfaceformat.cpp create mode 100644 src/multimedia/video/qvideosurfaceformat.h create mode 100644 src/multimedia/video/video.pri (limited to 'src') diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro index 7d38afa52..53fcb492d 100644 --- a/src/multimedia/multimedia.pro +++ b/src/multimedia/multimedia.pro @@ -1,11 +1,12 @@ -TARGET = QtMultimedia -QPRO_PWD = $$PWD -QT = core -DEFINES += QT_BUILD_MULTIMEDIA_LIB +TARGET = QtMultimedia +QPRO_PWD = $$PWD +QT = core gui -win32-msvc*:QMAKE_LIBS += $$QMAKE_LIBS_CORE +DEFINES += QT_BUILD_MULTIMEDIA_LIB QT_NO_USING_NAMESPACE -unix:QMAKE_PKGCONFIG_REQUIRES = QtCore +unix:QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui include(../qbase.pri) + include(audio/audio.pri) +include(video/video.pri) diff --git a/src/multimedia/video/qabstractvideobuffer.cpp b/src/multimedia/video/qabstractvideobuffer.cpp new file mode 100644 index 000000000..702b9a0e0 --- /dev/null +++ b/src/multimedia/video/qabstractvideobuffer.cpp @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractvideobuffer_p.h" + +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QAbstractVideoBuffer + \brief The QAbstractVideoBuffer class is an abstraction for video data. + \preliminary + \since 4.6 + + The QVideoFrame class makes use of a QAbstractVideoBuffer internally to reference a buffer of + video data. Creating a subclass of QAbstractVideoBuffer will allow you to construct video + frames from preallocated or static buffers. + + The contents of a buffer can be accessed by mapping the buffer to memory using the map() + function which returns a pointer to memory containing the contents of the the video buffer. + The memory returned by map() is released by calling the unmap() function. + + The handle() of a buffer may also be used to manipulate it's contents using type specific APIs. + The type of a buffer's handle is given by the handleType() function. + + \sa QVideoFrame +*/ + +/*! + \enum QAbstractVideoBuffer::HandleType + + Identifies the type of a video buffers handle. + + \value NoHandle The buffer has no handle, its data can only be accessed by mapping the buffer. + \value GLTextureHandle The handle of the buffer is an OpenGL texture ID. + \value UserHandle Start value for user defined handle types. + + \sa handleType() +*/ + +/*! + \enum QAbstractVideoBuffer::MapMode + + Enumerates how a video buffer's data is mapped to memory. + + \value NotMapped The video buffer has is not mapped to memory. + \value ReadOnly The mapped memory is populated with data from the video buffer when mapped, but + the content of the mapped memory may be discarded when unmapped. + \value WriteOnly The mapped memory in unitialized when mapped, and the content will be used to + populate the video buffer when unmapped. + \value ReadWrite The mapped memory is populated with data from the video buffer, and the + video buffer is repopulated with the content of the mapped memory. + + \sa mapMode(), map() +*/ + +/*! + Constructs an abstract video buffer of the given \a type. +*/ + +QAbstractVideoBuffer::QAbstractVideoBuffer(HandleType type) + : d_ptr(new QAbstractVideoBufferPrivate) +{ + Q_D(QAbstractVideoBuffer); + + d->handleType = type; +} + +/*! + \internal +*/ + +QAbstractVideoBuffer::QAbstractVideoBuffer(QAbstractVideoBufferPrivate &dd, HandleType type) + : d_ptr(&dd) +{ + Q_D(QAbstractVideoBuffer); + + d->handleType = type; +} + +/*! + Destroys an abstract video buffer. +*/ + +QAbstractVideoBuffer::~QAbstractVideoBuffer() +{ + delete d_ptr; +} + +/*! + Returns the type of a video buffer's handle. + + \sa handle() +*/ + +QAbstractVideoBuffer::HandleType QAbstractVideoBuffer::handleType() const +{ + return d_func()->handleType; +} + +/*! + \fn QAbstractVideoBuffer::mapMode() const + + Returns the mode a video buffer is mapped in. + + \sa map() +*/ + +/*! + \fn QAbstractVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine) + + Maps the contents of a video buffer to memory. + + The map \a mode indicates whether the contents of the mapped memory should be read from and/or + written to the buffer. If the map mode includes the QAbstractVideoBuffer::ReadOnly flag the + mapped memory will be populated with the content of the video buffer when mapped. If the map + mode includes the QAbstractVideoBuffer::WriteOnly flag the content of the mapped memory will be + persisted in the buffer when unmapped. + + When access to the data is no longer needed be sure to call the unmap() function to release the + mapped memory. + + Returns a pointer to the mapped memory region, or a null pointer if the mapping failed. The + size in bytes of the mapped memory region is returned in \a numBytes, and the line stride in \a + bytesPerLine. + + When access to the data is no longer needed be sure to unmap() the buffer. + + \note Writing to memory that is mapped as read-only is undefined, and may result in changes + to shared data. + + \sa unmap(), mapMode() +*/ + +/*! + \fn QAbstractVideoBuffer::unmap() + + Releases the memory mapped by the map() function + + If the \l {QAbstractVideoBuffer::MapMode}{MapMode} included the QAbstractVideoBuffer::WriteOnly + flag this will persist the current content of the mapped memory to the video frame. + + \sa map() +*/ + +/*! + Returns a type specific handle to the data buffer. + + The type of the handle is given by handleType() function. + + \sa handleType() +*/ + +QVariant QAbstractVideoBuffer::handle() const +{ + return QVariant(); +} + + +QT_END_NAMESPACE diff --git a/src/multimedia/video/qabstractvideobuffer.h b/src/multimedia/video/qabstractvideobuffer.h new file mode 100644 index 000000000..3ffb87aca --- /dev/null +++ b/src/multimedia/video/qabstractvideobuffer.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTVIDEOBUFFER_H +#define QABSTRACTVIDEOBUFFER_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QVariant; + +class QAbstractVideoBufferPrivate; + +class Q_MULTIMEDIA_EXPORT QAbstractVideoBuffer +{ +public: + enum HandleType + { + NoHandle, + GLTextureHandle, + UserHandle = 1000 + }; + + enum MapMode + { + NotMapped = 0x00, + ReadOnly = 0x01, + WriteOnly = 0x02, + ReadWrite = ReadOnly | WriteOnly + }; + + QAbstractVideoBuffer(HandleType type); + virtual ~QAbstractVideoBuffer(); + + HandleType handleType() const; + + virtual MapMode mapMode() const = 0; + + virtual uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) = 0; + virtual void unmap() = 0; + + virtual QVariant handle() const; + +protected: + QAbstractVideoBuffer(QAbstractVideoBufferPrivate &dd, HandleType type); + + QAbstractVideoBufferPrivate *d_ptr; + +private: + Q_DECLARE_PRIVATE(QAbstractVideoBuffer) + Q_DISABLE_COPY(QAbstractVideoBuffer) +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QAbstractVideoBuffer::HandleType) +Q_DECLARE_METATYPE(QAbstractVideoBuffer::MapMode) + +QT_END_HEADER + +#endif diff --git a/src/multimedia/video/qabstractvideobuffer_p.h b/src/multimedia/video/qabstractvideobuffer_p.h new file mode 100644 index 000000000..afe22b343 --- /dev/null +++ b/src/multimedia/video/qabstractvideobuffer_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTVIDEOBUFFER_P_H +#define QABSTRACTVIDEOBUFFER_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 +#include + +QT_BEGIN_NAMESPACE + +class QAbstractVideoBufferPrivate +{ +public: + QAbstractVideoBufferPrivate() + : handleType(QAbstractVideoBuffer::NoHandle) + {} + + QAbstractVideoBuffer::HandleType handleType; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/multimedia/video/qabstractvideosurface.cpp b/src/multimedia/video/qabstractvideosurface.cpp new file mode 100644 index 000000000..5309e57c8 --- /dev/null +++ b/src/multimedia/video/qabstractvideosurface.cpp @@ -0,0 +1,268 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qabstractvideosurface_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QAbstractVideoSurface + \brief The QAbstractVideoSurface class is a base class for video presentation surfaces. + \preliminary + \since 4.6 + + The QAbstractVideoSurface class defines the standard interface that video producers use to + inter-operate with video presentation surfaces. It is not supposed to be instantiated directly. + Instead, you should subclass it to create new video surfaces. + + A video surface presents a continuous stream of identically formatted frames, where the format + of each frame is compatible with a stream format supplied when starting a presentation. + + A list of pixel formats a surface can present is given by the supportedPixelFormats() function, + and the isFormatSupported() function will test if a complete video format is supported. In + some cases when a format is not supported; isFormatSupported() may suggest a similar format. + For example if a surface supports fixed set of resolutions it may suggest the smallest + supported resolution that contains the proposed resolution. + + The start() function takes a supported format and enables a video surface. Once started a + surface will begin displaying the frames it receives in the present() function. Surfaces may + hold a reference to the buffer of a presented video frame until a new frame is presented or + streaming is stopped. The stop() function will disable a surface and a release any video + buffers it holds references to. +*/ + +/*! + \enum QAbstractVideoSurface::Error + This enum describes the errors that may be returned by the error() function. + + \value NoError No error occurred. + \value UnsupportedFormatError A video format was not supported. + \value IncorrectFormatError A video frame was not compatible with the format of the surface. + \value StoppedError The surface has not been started. + \value ResourceError The surface could not allocate some resource. +*/ + +/*! + Constructs a video surface with the given \a parent. +*/ + +QAbstractVideoSurface::QAbstractVideoSurface(QObject *parent) + : QObject(*new QAbstractVideoSurfacePrivate, parent) +{ +} + +/*! + \internal +*/ + +QAbstractVideoSurface::QAbstractVideoSurface(QAbstractVideoSurfacePrivate &dd, QObject *parent) + : QObject(dd, parent) +{ +} + +/*! + Destroys a video surface. +*/ + +QAbstractVideoSurface::~QAbstractVideoSurface() +{ +} + +/*! + \fn QAbstractVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const + + Returns a list of pixel formats a video surface can present for a given handle \a type. + + The pixel formats returned for the QAbstractVideoBuffer::NoHandle type are valid for any buffer + that can be mapped in read-only mode. + + Types that are first in the list can be assumed to be faster to render. +*/ + +/*! + Tests a video \a format to determine if a surface can accept it. If the format isn't supported + the surface may suggest a \a similar format that is supported. + + Returns true if the format is supported by the surface, and false otherwise. +*/ + +bool QAbstractVideoSurface::isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar) const +{ + Q_UNUSED(similar); + + return supportedPixelFormats(format.handleType()).contains(format.pixelFormat()); +} + +/*! + \fn QAbstractVideoSurface::supportedFormatsChanged() + + Signals that the set of formats supported by a video surface has changed. + + \sa supportedPixelFormats(), isFormatSupported() +*/ + +/*! + Returns the format of a video surface. +*/ + +QVideoSurfaceFormat QAbstractVideoSurface::surfaceFormat() const +{ + return d_func()->format; +} + +/*! + \fn QAbstractVideoSurface::surfaceFormatChanged(const QVideoSurfaceFormat &format) + + Signals that the configured \a format of a video surface has changed. + + \sa surfaceFormat(), start() +*/ + +/*! + Starts a video surface presenting \a format frames. + + Returns true if the surface was started, and false if an error occurred. + + \sa isStarted(), stop() +*/ + +bool QAbstractVideoSurface::start(const QVideoSurfaceFormat &format) +{ + Q_D(QAbstractVideoSurface); + + bool wasStarted = d->started; + + d->started = true; + d->format = format; + d->error = NoError; + + emit surfaceFormatChanged(d->format); + + if (!wasStarted) + emit startedChanged(true); + + return true; +} + +/*! + Stops a video surface presenting frames and releases any resources acquired in start(). + + \sa isStarted(), start() +*/ + +void QAbstractVideoSurface::stop() +{ + Q_D(QAbstractVideoSurface); + + if (d->started) { + d->format = QVideoSurfaceFormat(); + d->started = false; + + emit startedChanged(false); + emit surfaceFormatChanged(d->format); + } +} + +/*! + Indicates whether a video surface has been started. + + Returns true if the surface has been started, and false otherwise. +*/ + +bool QAbstractVideoSurface::isStarted() const +{ + return d_func()->started; +} + +/*! + \fn QAbstractVideoSurface::startedChanged(bool started) + + Signals that the \a started state of a video surface has changed. + + \sa isStarted(), start(), stop() +*/ + +/*! + \fn QAbstractVideoSurface::present(const QVideoFrame &frame) + + Presents a video \a frame. + + Returns true if the frame was presented, and false if an error occurred. + + Not all surfaces will block until the presentation of a frame has completed. Calling present() + on a non-blocking surface may fail if called before the presentation of a previous frame has + completed. In such cases the surface may not return to a ready state until it's had an + opportunity to process events. + + If present() fails for any other reason the surface will immediately enter the stopped state + and an error() value will be set. + + A video surface must be in the started state for present() to succeed, and the format of the + video frame must be compatible with the current video surface format. + + \sa error() +*/ + +/*! + Returns the last error that occurred. + + If a surface fails to start(), or stops unexpectedly this function can be called to discover + what error occurred. +*/ + +QAbstractVideoSurface::Error QAbstractVideoSurface::error() const +{ + return d_func()->error; +} + +/*! + Sets the value of error() to \a error. +*/ + +void QAbstractVideoSurface::setError(Error error) +{ + Q_D(QAbstractVideoSurface); + + d->error = error; +} + +QT_END_NAMESPACE diff --git a/src/multimedia/video/qabstractvideosurface.h b/src/multimedia/video/qabstractvideosurface.h new file mode 100644 index 000000000..78831f084 --- /dev/null +++ b/src/multimedia/video/qabstractvideosurface.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTVIDEOSURFACE_H +#define QABSTRACTVIDEOSURFACE_H + +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QRectF; +class QVideoSurfaceFormat; + +class QAbstractVideoSurfacePrivate; + +class Q_MULTIMEDIA_EXPORT QAbstractVideoSurface : public QObject +{ + Q_OBJECT + +public: + enum Error + { + NoError, + UnsupportedFormatError, + IncorrectFormatError, + StoppedError, + ResourceError + }; + + explicit QAbstractVideoSurface(QObject *parent = 0); + ~QAbstractVideoSurface(); + + virtual QList supportedPixelFormats( + QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const = 0; + virtual bool isFormatSupported( + const QVideoSurfaceFormat &format, QVideoSurfaceFormat *similar = 0) const; + + QVideoSurfaceFormat surfaceFormat() const; + + virtual bool start(const QVideoSurfaceFormat &format); + virtual void stop(); + + bool isStarted() const; + + virtual bool present(const QVideoFrame &frame) = 0; + + Error error() const; + +Q_SIGNALS: + void startedChanged(bool started); + void surfaceFormatChanged(const QVideoSurfaceFormat &format); + void supportedFormatsChanged(); + +protected: + QAbstractVideoSurface(QAbstractVideoSurfacePrivate &dd, QObject *parent); + + void setError(Error error); + +private: + Q_DECLARE_PRIVATE(QAbstractVideoSurface) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/video/qabstractvideosurface_p.h b/src/multimedia/video/qabstractvideosurface_p.h new file mode 100644 index 000000000..e40110292 --- /dev/null +++ b/src/multimedia/video/qabstractvideosurface_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QABSTRACTVIDEOSURFACE_P_H +#define QABSTRACTVIDEOSURFACE_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 +#include +#include + +QT_BEGIN_NAMESPACE + +class QAbstractVideoSurfacePrivate : public QObjectPrivate +{ +public: + QAbstractVideoSurfacePrivate() + : error(QAbstractVideoSurface::NoError) + , started(false) + { + } + + mutable QAbstractVideoSurface::Error error; + QVideoSurfaceFormat format; + bool started; + +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/multimedia/video/qimagevideobuffer.cpp b/src/multimedia/video/qimagevideobuffer.cpp new file mode 100644 index 000000000..d63f14579 --- /dev/null +++ b/src/multimedia/video/qimagevideobuffer.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qimagevideobuffer_p.h" + +#include + +#include +#include + +class QImageVideoBufferPrivate : public QAbstractVideoBufferPrivate +{ +public: + QImageVideoBufferPrivate() + : mapMode(QAbstractVideoBuffer::NotMapped) + { + } + + QAbstractVideoBuffer::MapMode mapMode; + QImage image; +}; + +QImageVideoBuffer::QImageVideoBuffer(const QImage &image) + : QAbstractVideoBuffer(*new QImageVideoBufferPrivate, NoHandle) +{ + Q_D(QImageVideoBuffer); + + d->image = image; +} + +QImageVideoBuffer::~QImageVideoBuffer() +{ +} + +QAbstractVideoBuffer::MapMode QImageVideoBuffer::mapMode() const +{ + return d_func()->mapMode; +} + +uchar *QImageVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine) +{ + Q_D(QImageVideoBuffer); + + if (d->mapMode == NotMapped && d->image.bits() && mode != NotMapped) { + d->mapMode = mode; + + if (numBytes) + *numBytes = d->image.numBytes(); + + if (bytesPerLine) + *bytesPerLine = d->image.bytesPerLine(); + + return d->image.bits(); + } else { + return 0; + } +} + +void QImageVideoBuffer::unmap() +{ + Q_D(QImageVideoBuffer); + + d->mapMode = NotMapped; +} diff --git a/src/multimedia/video/qimagevideobuffer_p.h b/src/multimedia/video/qimagevideobuffer_p.h new file mode 100644 index 000000000..dcbc0b31e --- /dev/null +++ b/src/multimedia/video/qimagevideobuffer_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QIMAGEVIDEOBUFFER_P_H +#define QIMAGEVIDEOBUFFER_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 + +QT_BEGIN_NAMESPACE + +class QImage; + +class QImageVideoBufferPrivate; + +class Q_MULTIMEDIA_EXPORT QImageVideoBuffer : public QAbstractVideoBuffer +{ + Q_DECLARE_PRIVATE(QImageVideoBuffer) +public: + QImageVideoBuffer(const QImage &image); + ~QImageVideoBuffer(); + + MapMode mapMode() const; + + uchar *map(MapMode mode, int *numBytes, int *bytesPerLine); + void unmap(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/multimedia/video/qmemoryvideobuffer.cpp b/src/multimedia/video/qmemoryvideobuffer.cpp new file mode 100644 index 000000000..f4578208e --- /dev/null +++ b/src/multimedia/video/qmemoryvideobuffer.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmemoryvideobuffer_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +class QMemoryVideoBufferPrivate : public QAbstractVideoBufferPrivate +{ +public: + QMemoryVideoBufferPrivate() + : bytesPerLine(0) + , mapMode(QAbstractVideoBuffer::NotMapped) + { + } + + int bytesPerLine; + QAbstractVideoBuffer::MapMode mapMode; + QByteArray data; +}; + +/*! + \class QMemoryVideoBuffer + \brief The QMemoryVideoBuffer class provides a system memory allocated video data buffer. + \internal + + QMemoryVideoBuffer is the default video buffer for allocating system memory. It may be used to + allocate memory for a QVideoFrame without implementing your own QAbstractVideoBuffer. +*/ + +/*! + Constructs a video buffer with an image stride of \a bytesPerLine from a byte \a array. +*/ +QMemoryVideoBuffer::QMemoryVideoBuffer(const QByteArray &array, int bytesPerLine) + : QAbstractVideoBuffer(*new QMemoryVideoBufferPrivate, NoHandle) +{ + Q_D(QMemoryVideoBuffer); + + d->data = array; + d->bytesPerLine = bytesPerLine; +} + +/*! + Destroys a system memory allocated video buffer. +*/ +QMemoryVideoBuffer::~QMemoryVideoBuffer() +{ +} + +/*! + \reimp +*/ +QAbstractVideoBuffer::MapMode QMemoryVideoBuffer::mapMode() const +{ + return d_func()->mapMode; +} + +/*! + \reimp +*/ +uchar *QMemoryVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine) +{ + Q_D(QMemoryVideoBuffer); + + if (d->mapMode == NotMapped && d->data.data() && mode != NotMapped) { + d->mapMode = mode; + + if (numBytes) + *numBytes = d->data.size(); + + if (bytesPerLine) + *bytesPerLine = d->bytesPerLine; + + return reinterpret_cast(d->data.data()); + } else { + return 0; + } +} + +/*! + \reimp +*/ +void QMemoryVideoBuffer::unmap() +{ + d_func()->mapMode = NotMapped; +} + +QT_END_NAMESPACE diff --git a/src/multimedia/video/qmemoryvideobuffer_p.h b/src/multimedia/video/qmemoryvideobuffer_p.h new file mode 100644 index 000000000..e84c4a14a --- /dev/null +++ b/src/multimedia/video/qmemoryvideobuffer_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMEMORYVIDEOBUFFER_P_H +#define QMEMORYVIDEOBUFFER_P_H + +#include + +// +// 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. +// + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QMemoryVideoBufferPrivate; + +class Q_MULTIMEDIA_EXPORT QMemoryVideoBuffer : public QAbstractVideoBuffer +{ + Q_DECLARE_PRIVATE(QMemoryVideoBuffer) +public: + QMemoryVideoBuffer(const QByteArray &data, int bytesPerLine); + ~QMemoryVideoBuffer(); + + MapMode mapMode() const; + + uchar *map(MapMode mode, int *numBytes, int *bytesPerLine); + void unmap(); +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp new file mode 100644 index 000000000..c3584b7f6 --- /dev/null +++ b/src/multimedia/video/qvideoframe.cpp @@ -0,0 +1,742 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qvideoframe.h" + +#include +#include + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QVideoFramePrivate : public QSharedData +{ +public: + QVideoFramePrivate() + : startTime(-1) + , endTime(-1) + , data(0) + , numBytes(0) + , bytesPerLine(0) + , pixelFormat(QVideoFrame::Format_Invalid) + , fieldType(QVideoFrame::ProgressiveFrame) + , buffer(0) + { + } + + QVideoFramePrivate(const QSize &size, QVideoFrame::PixelFormat format) + : size(size) + , startTime(-1) + , endTime(-1) + , data(0) + , numBytes(0) + , bytesPerLine(0) + , pixelFormat(format) + , fieldType(QVideoFrame::ProgressiveFrame) + , buffer(0) + { + } + + ~QVideoFramePrivate() + { + delete buffer; + } + + QSize size; + qint64 startTime; + qint64 endTime; + uchar *data; + int numBytes; + int bytesPerLine; + QVideoFrame::PixelFormat pixelFormat; + QVideoFrame::FieldType fieldType; + QAbstractVideoBuffer *buffer; + +private: + Q_DISABLE_COPY(QVideoFramePrivate) +}; + +/*! + \class QVideoFrame + \brief The QVideoFrame class provides a representation of a frame of video data. + \preliminary + \since 4.6 + + A QVideoFrame encapsulates the data of a video frame, and information about the frame. + + The contents of a video frame can be mapped to memory using the map() function. While + mapped the video data can accessed using the bits() function which returns a pointer to a + buffer, the total size of which is given by the numBytes(), and the size of each line is given + by bytesPerLine(). The return value of the handle() function may be used to access frame data + using the internal buffer's native APIs. + + The video data in a QVideoFrame is encapsulated in a QAbstractVideoBuffer. A QVideoFrame + may be constructed from any buffer type by subclassing the QAbstractVideoBuffer class. + + \note QVideoFrame is explicitly shared, any change made to video frame will also apply to any + copies. +*/ + +/*! + \enum QVideoFrame::PixelFormat + + Enumerates video data types. + + \value Format_Invalid + The frame is invalid. + + \value Format_ARGB32 + The frame is stored using a 32-bit ARGB format (0xAARRGGBB). This is equivalent to + QImage::Format_ARGB32. + + \value Format_ARGB32_Premultiplied + The frame stored using a premultiplied 32-bit ARGB format (0xAARRGGBB). This is equivalent + to QImage::Format_ARGB32_Premultiplied. + + \value Format_RGB32 + The frame stored using a 32-bit RGB format (0xffRRGGBB). This is equivalent to + QImage::Format_RGB32 + + \value Format_RGB24 + The frame is stored using a 24-bit RGB format (8-8-8). This is equivalent to + QImage::Format_RGB888 + + \value Format_RGB565 + The frame is stored using a 16-bit RGB format (5-6-5). This is equivalent to + QImage::Format_RGB16. + + \value Format_RGB555 + The frame is stored using a 16-bit RGB format (5-5-5). This is equivalent to + QImage::Format_RGB555. + + \value Format_ARGB8565_Premultiplied + The frame is stored using a 24-bit premultiplied ARGB format (8-6-6-5). + + \value Format_BGRA32 + The frame is stored using a 32-bit ARGB format (0xBBGGRRAA). + + \value Format_BGRA32_Premultiplied + The frame is stored using a premultiplied 32bit BGRA format. + + \value Format_BGR32 + The frame is stored using a 32-bit BGR format (0xBBGGRRff). + + \value Format_BGR24 + The frame is stored using a 24-bit BGR format (0xBBGGRR). + + \value Format_BGR565 + The frame is stored using a 16-bit BGR format (5-6-5). + + \value Format_BGR555 + The frame is stored using a 16-bit BGR format (5-5-5). + + \value Format_BGRA5658_Premultiplied + The frame is stored using a 24-bit premultiplied BGRA format (5-6-5-8). + + \value Format_AYUV444 + The frame is stored using a packed 32-bit AYUV format (0xAAYYUUVV). + + \value Format_AYUV444_Premultiplied + The frame is stored using a packed premultiplied 32-bit AYUV format (0xAAYYUUVV). + + \value Format_YUV444 + The frame is stored using a 24-bit packed YUV format (8-8-8). + + \value Format_YUV420P + The frame is stored using an 8-bit per component planar YUV format with the U and V planes + horizontally and vertically sub-sampled, i.e. the height and width of the U and V planes are + half that of the Y plane. + + \value Format_YV12 + The frame is stored using an 8-bit per component planar YVU format with the V and U planes + horizontally and vertically sub-sampled, i.e. the height and width of the V and U planes are + half that of the Y plane. + + \value Format_UYVY + The frame is stored using an 8-bit per component packed YUV format with the U and V planes + horizontally sub-sampled (U-Y-V-Y), i.e. two horizontally adjacent pixels are stored as a 32-bit + macropixel which has a Y value for each pixel and common U and V values. + + \value Format_YUYV + The frame is stored using an 8-bit per component packed YUV format with the U and V planes + horizontally sub-sampled (Y-U-Y-V), i.e. two horizontally adjacent pixels are stored as a 32-bit + macropixel which has a Y value for each pixel and common U and V values. + + \value Format_NV12 + The frame is stored using an 8-bit per component semi-planar YUV format with a Y plane (Y) + followed by a horizontally and vertically sub-sampled, packed UV plane (U-V). + + \value Format_NV21 + The frame is stored using an 8-bit per component semi-planar YUV format with a Y plane (Y) + followed by a horizontally and vertically sub-sampled, packed VU plane (V-U). + + \value Format_IMC1 + The frame is stored using an 8-bit per component planar YUV format with the U and V planes + horizontally and vertically sub-sampled. This is similar to the Format_YUV420P type, except + that the bytes per line of the U and V planes are padded out to the same stride as the Y plane. + + \value Format_IMC2 + The frame is stored using an 8-bit per component planar YUV format with the U and V planes + horizontally and vertically sub-sampled. This is similar to the Format_YUV420P type, except + that the lines of the U and V planes are interleaved, i.e. each line of U data is followed by a + line of V data creating a single line of the same stride as the Y data. + + \value Format_IMC3 + The frame is stored using an 8-bit per component planar YVU format with the V and U planes + horizontally and vertically sub-sampled. This is similar to the Format_YV12 type, except that + the bytes per line of the V and U planes are padded out to the same stride as the Y plane. + + \value Format_IMC4 + The frame is stored using an 8-bit per component planar YVU format with the V and U planes + horizontally and vertically sub-sampled. This is similar to the Format_YV12 type, except that + the lines of the V and U planes are interleaved, i.e. each line of V data is followed by a line + of U data creating a single line of the same stride as the Y data. + + \value Format_Y8 + The frame is stored using an 8-bit greyscale format. + + \value Format_Y16 + The frame is stored using a 16-bit linear greyscale format. Little endian. + + \value Format_User + Start value for user defined pixel formats. +*/ + +/*! + \enum QVideoFrame::FieldType + + Specifies the field an interlaced video frame belongs to. + + \value ProgressiveFrame The frame is not interlaced. + \value TopField The frame contains a top field. + \value BottomField The frame contains a bottom field. + \value InterlacedFrame The frame contains a merged top and bottom field. +*/ + +/*! + Constructs a null video frame. +*/ + +QVideoFrame::QVideoFrame() + : d(new QVideoFramePrivate) +{ +} + +/*! + Constructs a video frame from a \a buffer of the given pixel \a format and \a size in pixels. + + \note This doesn't increment the reference count of the video buffer. +*/ + +QVideoFrame::QVideoFrame( + QAbstractVideoBuffer *buffer, const QSize &size, PixelFormat format) + : d(new QVideoFramePrivate(size, format)) +{ + d->buffer = buffer; +} + +/*! + Constructs a video frame of the given pixel \a format and \a size in pixels. + + The \a bytesPerLine (stride) is the length of each scan line in bytes, and \a bytes is the total + number of bytes that must be allocated for the frame. +*/ + +QVideoFrame::QVideoFrame(int bytes, const QSize &size, int bytesPerLine, PixelFormat format) + : d(new QVideoFramePrivate(size, format)) +{ + if (bytes > 0) { + QByteArray data; + data.resize(bytes); + + // Check the memory was successfully allocated. + if (!data.isEmpty()) + d->buffer = new QMemoryVideoBuffer(data, bytesPerLine); + } +} + +/*! + Constructs a video frame from an \a image. + + \note This will construct an invalid video frame if there is no frame type equivalent to the + image format. + + \sa equivalentPixelFormat() +*/ + +QVideoFrame::QVideoFrame(const QImage &image) + : d(new QVideoFramePrivate( + image.size(), equivalentPixelFormat(image.format()))) +{ + if (d->pixelFormat != Format_Invalid) + d->buffer = new QImageVideoBuffer(image); +} + +/*! + Constructs a copy of \a other. +*/ + +QVideoFrame::QVideoFrame(const QVideoFrame &other) + : d(other.d) +{ +} + +/*! + Assigns the contents of \a other to a video frame. +*/ + +QVideoFrame &QVideoFrame::operator =(const QVideoFrame &other) +{ + d = other.d; + + return *this; +} + +/*! + Destroys a video frame. +*/ + +QVideoFrame::~QVideoFrame() +{ +} + +/*! + Identifies whether a video frame is valid. + + An invalid frame has no video buffer associated with it. + + Returns true if the frame is valid, and false if it is not. +*/ + +bool QVideoFrame::isValid() const +{ + return d->buffer != 0; +} + +/*! + Returns the color format of a video frame. +*/ + +QVideoFrame::PixelFormat QVideoFrame::pixelFormat() const +{ + return d->pixelFormat; +} + +/*! + Returns the type of a video frame's handle. +*/ + +QAbstractVideoBuffer::HandleType QVideoFrame::handleType() const +{ + return d->buffer ? d->buffer->handleType() : QAbstractVideoBuffer::NoHandle; +} + +/*! + Returns the size of a video frame. +*/ + +QSize QVideoFrame::size() const +{ + return d->size; +} + +/*! + Returns the width of a video frame. +*/ + +int QVideoFrame::width() const +{ + return d->size.width(); +} + +/*! + Returns the height of a video frame. +*/ + +int QVideoFrame::height() const +{ + return d->size.height(); +} + +/*! + Returns the field an interlaced video frame belongs to. + + If the video is not interlaced this will return WholeFrame. +*/ + +QVideoFrame::FieldType QVideoFrame::fieldType() const +{ + return d->fieldType; +} + +/*! + Sets the \a field an interlaced video frame belongs to. +*/ + +void QVideoFrame::setFieldType(QVideoFrame::FieldType field) +{ + d->fieldType = field; +} + +/*! + Identifies if a video frame's contents are currently mapped to system memory. + + This is a convenience function which checks that the \l {QAbstractVideoBuffer::MapMode}{MapMode} + of the frame is not equal to QAbstractVideoBuffer::NotMapped. + + Returns true if the contents of the video frame are mapped to system memory, and false + otherwise. + + \sa mapMode() QAbstractVideoBuffer::MapMode +*/ + +bool QVideoFrame::isMapped() const +{ + return d->buffer != 0 && d->buffer->mapMode() != QAbstractVideoBuffer::NotMapped; +} + +/*! + Identifies if the mapped contents of a video frame will be persisted when the frame is unmapped. + + This is a convenience function which checks if the \l {QAbstractVideoBuffer::MapMode}{MapMode} + contains the QAbstractVideoBuffer::WriteOnly flag. + + Returns true if the video frame will be updated when unmapped, and false otherwise. + + \note The result of altering the data of a frame that is mapped in read-only mode is undefined. + Depending on the buffer implementation the changes may be persisted, or worse alter a shared + buffer. + + \sa mapMode(), QAbstractVideoBuffer::MapMode +*/ + +bool QVideoFrame::isWritable() const +{ + return d->buffer != 0 && (d->buffer->mapMode() & QAbstractVideoBuffer::WriteOnly); +} + +/*! + Identifies if the mapped contents of a video frame were read from the frame when it was mapped. + + This is a convenience function which checks if the \l {QAbstractVideoBuffer::MapMode}{MapMode} + contains the QAbstractVideoBuffer::WriteOnly flag. + + Returns true if the contents of the mapped memory were read from the video frame, and false + otherwise. + + \sa mapMode(), QAbstractVideoBuffer::MapMode +*/ + +bool QVideoFrame::isReadable() const +{ + return d->buffer != 0 && (d->buffer->mapMode() & QAbstractVideoBuffer::ReadOnly); +} + +/*! + Returns the mode a video frame was mapped to system memory in. + + \sa map(), QAbstractVideoBuffer::MapMode +*/ + +QAbstractVideoBuffer::MapMode QVideoFrame::mapMode() const +{ + return d->buffer != 0 ? d->buffer->mapMode() : QAbstractVideoBuffer::NotMapped; +} + +/*! + Maps the contents of a video frame to memory. + + The map \a mode indicates whether the contents of the mapped memory should be read from and/or + written to the frame. If the map mode includes the QAbstractVideoBuffer::ReadOnly flag the + mapped memory will be populated with the content of the video frame when mapped. If the map + mode inclues the QAbstractVideoBuffer::WriteOnly flag the content of the mapped memory will be + persisted in the frame when unmapped. + + While mapped the contents of a video frame can be accessed directly through the pointer returned + by the bits() function. + + When access to the data is no longer needed be sure to call the unmap() function to release the + mapped memory. + + Returns true if the buffer was mapped to memory in the given \a mode and false otherwise. + + \sa unmap(), mapMode(), bits() +*/ + +bool QVideoFrame::map(QAbstractVideoBuffer::MapMode mode) +{ + if (d->buffer != 0 && d->data == 0) { + Q_ASSERT(d->bytesPerLine == 0); + Q_ASSERT(d->numBytes == 0); + + d->data = d->buffer->map(mode, &d->numBytes, &d->bytesPerLine); + + return d->data != 0; + } + + return false; +} + +/*! + Releases the memory mapped by the map() function. + + If the \l {QAbstractVideoBuffer::MapMode}{MapMode} included the QAbstractVideoBuffer::WriteOnly + flag this will persist the current content of the mapped memory to the video frame. + + \sa map() +*/ + +void QVideoFrame::unmap() +{ + if (d->data != 0) { + d->numBytes = 0; + d->bytesPerLine = 0; + d->data = 0; + + d->buffer->unmap(); + } +} + +/*! + Returns the number of bytes in a scan line. + + \note This is the bytes per line of the first plane only. The bytes per line of subsequent + planes should be calculated as per the frame type. + + This value is only valid while the frame data is \l {map()}{mapped}. + + \sa bits(), map(), numBytes() +*/ + +int QVideoFrame::bytesPerLine() const +{ + return d->bytesPerLine; +} + +/*! + Returns a pointer to the start of the frame data buffer. + + This value is only valid while the frame data is \l {map()}{mapped}. + + \sa map(), numBytes(), bytesPerLine() +*/ + +uchar *QVideoFrame::bits() +{ + return d->data; +} + +/*! + Returns a pointer to the start of the frame data buffer. + + This value is only valid while the frame data is \l {map()}{mapped}. + + \sa map(), numBytes(), bytesPerLine() +*/ + +const uchar *QVideoFrame::bits() const +{ + return d->data; +} + +/*! + Returns the number of bytes occupied by the frame data. + + This value is only valid while the frame data is \l {map()}{mapped}. + + \sa map() +*/ + +int QVideoFrame::numBytes() const +{ + return d->numBytes; +} + +/*! + Returns a type specific handle to a video frame's buffer. + + For an OpenGL texture this would be the texture ID. + + \sa QAbstractVideoBuffer::handle() +*/ + +QVariant QVideoFrame::handle() const +{ + return d->buffer != 0 ? d->buffer->handle() : QVariant(); +} + +/*! + Returns the presentation time when the frame should be displayed. +*/ + +qint64 QVideoFrame::startTime() const +{ + return d->startTime; +} + +/*! + Sets the presentation \a time when the frame should be displayed. +*/ + +void QVideoFrame::setStartTime(qint64 time) +{ + d->startTime = time; +} + +/*! + Returns the presentation time when a frame should stop being displayed. +*/ + +qint64 QVideoFrame::endTime() const +{ + return d->endTime; +} + +/*! + Sets the presentation \a time when a frame should stop being displayed. +*/ + +void QVideoFrame::setEndTime(qint64 time) +{ + d->endTime = time; +} + +/*! + Returns an video pixel format equivalent to an image \a format. If there is no equivalent + format QVideoFrame::InvalidType is returned instead. +*/ + +QVideoFrame::PixelFormat QVideoFrame::equivalentPixelFormat(QImage::Format format) +{ + switch (format) { + case QImage::Format_Invalid: + case QImage::Format_Mono: + case QImage::Format_MonoLSB: + case QImage::Format_Indexed8: + return Format_Invalid; + case QImage::Format_RGB32: + return Format_RGB32; + case QImage::Format_ARGB32: + return Format_ARGB32; + case QImage::Format_ARGB32_Premultiplied: + return Format_ARGB32_Premultiplied; + case QImage::Format_RGB16: + return Format_RGB565; + case QImage::Format_ARGB8565_Premultiplied: + case QImage::Format_RGB666: + case QImage::Format_ARGB6666_Premultiplied: + return Format_Invalid; + case QImage::Format_RGB555: + return Format_RGB555; + case QImage::Format_ARGB8555_Premultiplied: + return Format_Invalid; + case QImage::Format_RGB888: + return Format_RGB24; + case QImage::Format_RGB444: + case QImage::Format_ARGB4444_Premultiplied: + return Format_Invalid; + case QImage::NImageFormats: + return Format_Invalid; + } + return Format_Invalid; +} + +/*! + Returns an image format equivalent to a video frame pixel \a format. If there is no equivalent + format QImage::Format_Invalid is returned instead. +*/ + +QImage::Format QVideoFrame::equivalentImageFormat(PixelFormat format) +{ + switch (format) { + case Format_Invalid: + return QImage::Format_Invalid; + case Format_ARGB32: + return QImage::Format_ARGB32; + case Format_ARGB32_Premultiplied: + return QImage::Format_ARGB32_Premultiplied; + case Format_RGB32: + return QImage::Format_RGB32; + case Format_RGB24: + return QImage::Format_RGB888; + case Format_RGB565: + return QImage::Format_RGB16; + case Format_RGB555: + return QImage::Format_RGB555; + case Format_ARGB8565_Premultiplied: + return QImage::Format_ARGB8565_Premultiplied; + case Format_BGRA32: + case Format_BGRA32_Premultiplied: + case Format_BGR32: + case Format_BGR24: + return QImage::Format_Invalid; + case Format_BGR565: + case Format_BGR555: + case Format_BGRA5658_Premultiplied: + case Format_AYUV444: + case Format_AYUV444_Premultiplied: + case Format_YUV444: + case Format_YUV420P: + case Format_YV12: + case Format_UYVY: + case Format_YUYV: + case Format_NV12: + case Format_NV21: + case Format_IMC1: + case Format_IMC2: + case Format_IMC3: + case Format_IMC4: + case Format_Y8: + case Format_Y16: + return QImage::Format_Invalid; + case Format_User: + return QImage::Format_Invalid; + } + return QImage::Format_Invalid; +} + +QT_END_NAMESPACE + diff --git a/src/multimedia/video/qvideoframe.h b/src/multimedia/video/qvideoframe.h new file mode 100644 index 000000000..5bd9ac33c --- /dev/null +++ b/src/multimedia/video/qvideoframe.h @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QVIDEOFRAME_H +#define QVIDEOFRAME_H + +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QSize; +class QVariant; + +class QVideoFramePrivate; + +class Q_MULTIMEDIA_EXPORT QVideoFrame +{ +public: + enum FieldType + { + ProgressiveFrame, + TopField, + BottomField, + InterlacedFrame + }; + + enum PixelFormat + { + Format_Invalid, + Format_ARGB32, + Format_ARGB32_Premultiplied, + Format_RGB32, + Format_RGB24, + Format_RGB565, + Format_RGB555, + Format_ARGB8565_Premultiplied, + Format_BGRA32, + Format_BGRA32_Premultiplied, + Format_BGR32, + Format_BGR24, + Format_BGR565, + Format_BGR555, + Format_BGRA5658_Premultiplied, + + Format_AYUV444, + Format_AYUV444_Premultiplied, + Format_YUV444, + Format_YUV420P, + Format_YV12, + Format_UYVY, + Format_YUYV, + Format_NV12, + Format_NV21, + Format_IMC1, + Format_IMC2, + Format_IMC3, + Format_IMC4, + Format_Y8, + Format_Y16, + + Format_User = 1000 + }; + + QVideoFrame(); + QVideoFrame(QAbstractVideoBuffer *buffer, const QSize &size, PixelFormat format); + QVideoFrame(int bytes, const QSize &size, int bytesPerLine, PixelFormat format); + QVideoFrame(const QImage &image); + QVideoFrame(const QVideoFrame &other); + ~QVideoFrame(); + + QVideoFrame &operator =(const QVideoFrame &other); + + bool isValid() const; + + PixelFormat pixelFormat() const; + + QAbstractVideoBuffer::HandleType handleType() const; + + QSize size() const; + int width() const; + int height() const; + + FieldType fieldType() const; + void setFieldType(FieldType); + + bool isMapped() const; + bool isReadable() const; + bool isWritable() const; + + QAbstractVideoBuffer::MapMode mapMode() const; + + bool map(QAbstractVideoBuffer::MapMode mode); + void unmap(); + + int bytesPerLine() const; + + uchar *bits(); + const uchar *bits() const; + int numBytes() const; + + QVariant handle() const; + + qint64 startTime() const; + void setStartTime(qint64 time); + + qint64 endTime() const; + void setEndTime(qint64 time); + + static PixelFormat equivalentPixelFormat(QImage::Format format); + static QImage::Format equivalentImageFormat(PixelFormat format); + +private: + QExplicitlySharedDataPointer d; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QVideoFrame::FieldType) +Q_DECLARE_METATYPE(QVideoFrame::PixelFormat) + +QT_END_HEADER + +#endif + diff --git a/src/multimedia/video/qvideosurfaceformat.cpp b/src/multimedia/video/qvideosurfaceformat.cpp new file mode 100644 index 000000000..7e18ddab7 --- /dev/null +++ b/src/multimedia/video/qvideosurfaceformat.cpp @@ -0,0 +1,742 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qvideosurfaceformat.h" + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QVideoSurfaceFormatPrivate : public QSharedData +{ +public: + QVideoSurfaceFormatPrivate() + : pixelFormat(QVideoFrame::Format_Invalid) + , handleType(QAbstractVideoBuffer::NoHandle) + , scanLineDirection(QVideoSurfaceFormat::TopToBottom) + , pixelAspectRatio(1, 1) + , yuvColorSpace(QVideoSurfaceFormat::YCbCr_Undefined) + , frameRate(0, 0) + { + } + + QVideoSurfaceFormatPrivate( + const QSize &size, + QVideoFrame::PixelFormat format, + QAbstractVideoBuffer::HandleType type) + : pixelFormat(format) + , handleType(type) + , scanLineDirection(QVideoSurfaceFormat::TopToBottom) + , frameSize(size) + , pixelAspectRatio(1, 1) + , yuvColorSpace(QVideoSurfaceFormat::YCbCr_Undefined) + , viewport(QPoint(0, 0), size) + , frameRate(0, 0) + { + } + + QVideoSurfaceFormatPrivate(const QVideoSurfaceFormatPrivate &other) + : QSharedData(other) + , pixelFormat(other.pixelFormat) + , handleType(other.handleType) + , scanLineDirection(other.scanLineDirection) + , frameSize(other.frameSize) + , pixelAspectRatio(other.pixelAspectRatio) + , yuvColorSpace(other.yuvColorSpace) + , viewport(other.viewport) + , frameRate(other.frameRate) + , propertyNames(other.propertyNames) + , propertyValues(other.propertyValues) + { + } + + bool operator ==(const QVideoSurfaceFormatPrivate &other) const + { + if (pixelFormat == other.pixelFormat + && handleType == other.handleType + && scanLineDirection == other.scanLineDirection + && frameSize == other.frameSize + && pixelAspectRatio == other.pixelAspectRatio + && viewport == other.viewport + && frameRate == other.frameRate + && yuvColorSpace == other.yuvColorSpace + && propertyNames.count() == other.propertyNames.count()) { + for (int i = 0; i < propertyNames.count(); ++i) { + int j = other.propertyNames.indexOf(propertyNames.at(i)); + + if (j == -1 || propertyValues.at(i) != other.propertyValues.at(j)) + return false; + } + return true; + } else { + return false; + } + } + + QVideoFrame::PixelFormat pixelFormat; + QAbstractVideoBuffer::HandleType handleType; + QVideoSurfaceFormat::Direction scanLineDirection; + QSize frameSize; + QSize pixelAspectRatio; + QVideoSurfaceFormat::YuvColorSpace yuvColorSpace; + QRect viewport; + QVideoSurfaceFormat::FrameRate frameRate; + QList propertyNames; + QList propertyValues; +}; + +/*! + \class QVideoSurfaceFormat + \brief The QVideoSurfaceFormat class specifies the stream format of a video presentation + surface. + \preliminary + \since 4.6 + + A video surface presents a stream of video frames. The surface's format describes the type of + the frames and determines how they should be presented. + + The core properties of a video stream required to setup a video surface are the pixel format + given by pixelFormat(), and the frame dimensions given by frameSize(). + + If the surface is to present frames using a frame's handle a surface format will also include + a handle type which is given by the handleType() function. + + The region of a frame that is actually displayed on a video surface is given by the viewport(). + A stream may have a viewport less than the entire region of a frame to allow for videos smaller + than the nearest optimal size of a video frame. For example the width of a frame may be + extended so that the start of each scan line is eight byte aligned. + + Other common properties are the pixelAspectRatio(), scanLineDirection(), and frameRate(). + Additionally a stream may have some additional type specific properties which are listed by the + dynamicPropertyNames() function and can be accessed using the property(), and setProperty() + functions. +*/ + +/*! + \enum QVideoSurfaceFormat::Direction + + Enumerates the layout direction of video scan lines. + + \value TopToBottom Scan lines are arranged from the top of the frame to the bottom. + \value BottomToTop Scan lines are arranged from the bottom of the frame to the top. +*/ + +/*! + \enum QVideoSurfaceFormat::ViewportMode + + Enumerates the methods for updating the stream viewport when the frame size is changed. + + \value ResetViewport The viewport is reset to cover an entire frame. + \value KeepViewport The viewport is kept within the bounds the frame. +*/ + +/*! + \enum QVideoSurfaceFormat::YuvColorSpace + + Enumerates the YUV color space of video frames. + + \value YCbCr_Undefined + No color space is specified. + + \value YCbCr_BT601 + A Y'CbCr color space defined by ITU-R recommendation BT.601 + with Y value range from 16 to 235, and Cb/Cr range from 16 to 240. + Used in standard definition video. + + \value YCbCr_BT709 + A Y'CbCr color space defined by ITU-R BT.709 with the same values range as YCbCr_BT601. Used + for HDTV. + + \value YCbCr_xvYCC601 + The BT.601 color space with the value range extended to 0 to 255. + It is backward compatibile with BT.601 and uses values outside BT.601 range to represent + wider colors range. + + \value YCbCr_xvYCC709 + The BT.709 color space with the value range extended to 0 to 255. + + \value YCbCr_JPEG + The full range Y'CbCr color space used in JPEG files. +*/ + + +/*! + \typedef QVideoSurfaceFormat::FrameRate + + A pair of integers representing the frame rate of a video stream. + + The first number is the numerator and the second the denominator. +*/ + +/*! + Constructs a null video stream format. +*/ + +QVideoSurfaceFormat::QVideoSurfaceFormat() + : d(new QVideoSurfaceFormatPrivate) +{ +} + +/*! + Contructs a description of stream which receives stream of \a type buffers with given frame + \a size and pixel \a format. +*/ + +QVideoSurfaceFormat::QVideoSurfaceFormat( + const QSize& size, QVideoFrame::PixelFormat format, QAbstractVideoBuffer::HandleType type) + : d(new QVideoSurfaceFormatPrivate(size, format, type)) +{ +} + +/*! + Constructs a copy of \a other. +*/ + +QVideoSurfaceFormat::QVideoSurfaceFormat(const QVideoSurfaceFormat &other) + : d(other.d) +{ +} + +/*! + Assigns the values of \a other to a video stream description. +*/ + +QVideoSurfaceFormat &QVideoSurfaceFormat::operator =(const QVideoSurfaceFormat &other) +{ + d = other.d; + + return *this; +} + +/*! + Destroys a video stream description. +*/ + +QVideoSurfaceFormat::~QVideoSurfaceFormat() +{ +} + +/*! + Identifies if a video surface format has a valid pixel format and frame size. + + Returns true if the format is valid, and false otherwise. +*/ + +bool QVideoSurfaceFormat::isValid() const +{ + return d->pixelFormat == QVideoFrame::Format_Invalid && d->frameSize.isValid(); +} + +/*! + Returns true if \a other is the same as a video format, and false if they are the different. +*/ + +bool QVideoSurfaceFormat::operator ==(const QVideoSurfaceFormat &other) const +{ + return d == other.d || *d == *other.d; +} + +/*! + Returns true if \a other is different to a video format, and false if they are the same. +*/ + +bool QVideoSurfaceFormat::operator !=(const QVideoSurfaceFormat &other) const +{ + return d != other.d && !(*d == *other.d); +} + +/*! + Returns the pixel format of frames in a video stream. +*/ + +QVideoFrame::PixelFormat QVideoSurfaceFormat::pixelFormat() const +{ + return d->pixelFormat; +} + +/*! + Returns the type of handle the surface uses to present the frame data. + + If the handle type is QAbstractVideoBuffer::NoHandle buffers with any handle type are valid + provided they can be \l {QAbstractVideoBuffer::map()}{mapped} with the + QAbstractVideoBuffer::ReadOnly flag. If the handleType() is not QAbstractVideoBuffer::NoHandle + then the handle type of the buffer be the same as that of the surface format. +*/ + +QAbstractVideoBuffer::HandleType QVideoSurfaceFormat::handleType() const +{ + return d->handleType; +} + +/*! + Returns the size of frames in a video stream. + + \sa frameWidth(), frameHeight() +*/ + +QSize QVideoSurfaceFormat::frameSize() const +{ + return d->frameSize; +} + +/*! + Returns the width of frames in a video stream. + + \sa frameSize(), frameHeight() +*/ + +int QVideoSurfaceFormat::frameWidth() const +{ + return d->frameSize.width(); +} + +/*! + Returns the height of frame in a video stream. +*/ + +int QVideoSurfaceFormat::frameHeight() const +{ + return d->frameSize.height(); +} + +/*! + Sets the size of frames in a video stream to \a size. + + The viewport \a mode indicates how the view port should be updated. +*/ + +void QVideoSurfaceFormat::setFrameSize(const QSize &size, ViewportMode mode) +{ + d->frameSize = size; + + switch (mode) { + case ResetViewport: + d->viewport = QRect(QPoint(0, 0), size); + break; + case KeepViewport: + d->viewport = QRect(QPoint(0, 0), size).intersected(d->viewport); + break; + } +} + +/*! + \overload + + Sets the \a width and \a height of frames in a video stream. + + The viewport \a mode indicates how the view port should be updated. +*/ + +void QVideoSurfaceFormat::setFrameSize(int width, int height, ViewportMode mode) +{ + setFrameSize(QSize(width, height), mode); +} + +/*! + Returns the viewport of a video stream. + + The viewport is the region of a video frame that is actually displayed. + + By default the viewport covers an entire frame. +*/ + +QRect QVideoSurfaceFormat::viewport() const +{ + return d->viewport; +} + +/*! + Sets the viewport of a video stream to \a viewport. +*/ + +void QVideoSurfaceFormat::setViewport(const QRect &viewport) +{ + d->viewport = viewport; +} + +/*! + Returns the direction of scan lines. +*/ + +QVideoSurfaceFormat::Direction QVideoSurfaceFormat::scanLineDirection() const +{ + return d->scanLineDirection; +} + +/*! + Sets the \a direction of scan lines. +*/ + +void QVideoSurfaceFormat::setScanLineDirection(Direction direction) +{ + d->scanLineDirection = direction; +} + +/*! + Returns the frame rate of a video stream. + + The frame rate is a rational number represented by a pair of integers. + The first integer is the numerator and the second the denominator. +*/ + +QVideoSurfaceFormat::FrameRate QVideoSurfaceFormat::frameRate() const +{ + return d->frameRate; +} + +/*! + Sets the frame \a rate of a video stream. + + The frame rate is a rational number represented by a pair of integers. + The first integer is the numerator and the second the denominator. +*/ + +void QVideoSurfaceFormat::setFrameRate(const FrameRate &rate) +{ + d->frameRate = rate; +} + +/*! + \overload + + Sets the \a numerator and \a denominator of the frame rate of a video stream. +*/ + +void QVideoSurfaceFormat::setFrameRate(int numerator, int denominator) +{ + d->frameRate = qMakePair(numerator, denominator); +} + +/*! + Returns a video stream's pixel aspect ratio. +*/ + +QSize QVideoSurfaceFormat::pixelAspectRatio() const +{ + return d->pixelAspectRatio; +} + +/*! + Sets a video stream's pixel aspect \a ratio. +*/ + +void QVideoSurfaceFormat::setPixelAspectRatio(const QSize &ratio) +{ + d->pixelAspectRatio = ratio; +} + +/*! + \overload + + Sets the \a horizontal and \a vertical elements of a video stream's pixel aspect ratio. +*/ + +void QVideoSurfaceFormat::setPixelAspectRatio(int horizontal, int vertical) +{ + d->pixelAspectRatio = QSize(horizontal, vertical); +} + +/*! + Returns a YUV color space of a video stream. +*/ + +QVideoSurfaceFormat::YuvColorSpace QVideoSurfaceFormat::yuvColorSpace() const +{ + return d->yuvColorSpace; +} + +/*! + Sets a YUV color \a space of a video stream. + It is only used with raw YUV frame types. +*/ + +void QVideoSurfaceFormat::setYuvColorSpace(QVideoSurfaceFormat::YuvColorSpace space) +{ + d->yuvColorSpace = space; +} + +/*! + Returns a suggested size in pixels for the video stream. + + This is the size of the viewport scaled according to the pixel aspect ratio. +*/ + +QSize QVideoSurfaceFormat::sizeHint() const +{ + QSize size = d->viewport.size(); + + if (d->pixelAspectRatio.height() != 0) + size.setWidth(size.width() * d->pixelAspectRatio.width() / d->pixelAspectRatio.height()); + + return size; +} + +/*! + Returns a list of video format dynamic property names. +*/ + +QList QVideoSurfaceFormat::propertyNames() const +{ + return (QList() + << "handleType" + << "pixelFormat" + << "frameSize" + << "frameWidth" + << "viewport" + << "scanLineDirection" + << "frameRate" + << "pixelAspectRatio" + << "sizeHint" + << "yuvColorSpace") + + d->propertyNames; +} + +/*! + Returns the value of the video format's \a name property. +*/ + +QVariant QVideoSurfaceFormat::property(const char *name) const +{ + if (qstrcmp(name, "handleType") == 0) { + return qVariantFromValue(d->handleType); + } else if (qstrcmp(name, "pixelFormat") == 0) { + return qVariantFromValue(d->pixelFormat); + } else if (qstrcmp(name, "handleType") == 0) { + return qVariantFromValue(d->handleType); + } else if (qstrcmp(name, "frameSize") == 0) { + return d->frameSize; + } else if (qstrcmp(name, "frameWidth") == 0) { + return d->frameSize.width(); + } else if (qstrcmp(name, "frameHeight") == 0) { + return d->frameSize.height(); + } else if (qstrcmp(name, "viewport") == 0) { + return d->viewport; + } else if (qstrcmp(name, "scanLineDirection") == 0) { + return qVariantFromValue(d->scanLineDirection); + } else if (qstrcmp(name, "frameRate") == 0) { + return qVariantFromValue(d->frameRate); + } else if (qstrcmp(name, "pixelAspectRatio") == 0) { + return qVariantFromValue(d->pixelAspectRatio); + } else if (qstrcmp(name, "sizeHint") == 0) { + return sizeHint(); + } else if (qstrcmp(name, "yuvColorSpace") == 0) { + return qVariantFromValue(d->yuvColorSpace); + } else { + int id = 0; + for (; id < d->propertyNames.count() && d->propertyNames.at(id) != name; ++id) {} + + return id < d->propertyValues.count() + ? d->propertyValues.at(id) + : QVariant(); + } +} + +/*! + Sets the video format's \a name property to \a value. +*/ + +void QVideoSurfaceFormat::setProperty(const char *name, const QVariant &value) +{ + if (qstrcmp(name, "handleType") == 0) { + // read only. + } else if (qstrcmp(name, "pixelFormat") == 0) { + // read only. + } else if (qstrcmp(name, "frameSize") == 0) { + if (qVariantCanConvert(value)) { + d->frameSize = qvariant_cast(value); + d->viewport = QRect(QPoint(0, 0), d->frameSize); + } + } else if (qstrcmp(name, "frameWidth") == 0) { + // read only. + } else if (qstrcmp(name, "frameHeight") == 0) { + // read only. + } else if (qstrcmp(name, "viewport") == 0) { + if (qVariantCanConvert(value)) + d->viewport = qvariant_cast(value); + } else if (qstrcmp(name, "scanLineDirection") == 0) { + if (qVariantCanConvert(value)) + d->scanLineDirection = qvariant_cast(value); + } else if (qstrcmp(name, "frameRate") == 0) { + if (qVariantCanConvert(value)) + d->frameRate = qvariant_cast(value); + } else if (qstrcmp(name, "pixelAspectRatio") == 0) { + if (qVariantCanConvert(value)) + d->pixelAspectRatio = qvariant_cast(value); + } else if (qstrcmp(name, "sizeHint") == 0) { + // read only. + } else if (qstrcmp(name, "yuvColorSpace") == 0) { + if (qVariantCanConvert(value)) + d->yuvColorSpace = qvariant_cast(value); + } else { + int id = 0; + for (; id < d->propertyNames.count() && d->propertyNames.at(id) != name; ++id) {} + + if (id < d->propertyValues.count()) { + if (value.isNull()) { + d->propertyNames.removeAt(id); + d->propertyValues.removeAt(id); + } else { + d->propertyValues[id] = value; + } + } else if (!value.isNull()) { + d->propertyNames.append(QByteArray(name)); + d->propertyValues.append(value); + } + } +} + + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug dbg, const QVideoSurfaceFormat &f) +{ + QString typeName; + switch (f.pixelFormat()) { + case QVideoFrame::Format_Invalid: + typeName = QLatin1String("Format_Invalid"); + break; + case QVideoFrame::Format_ARGB32: + typeName = QLatin1String("Format_ARGB32"); + break; + case QVideoFrame::Format_ARGB32_Premultiplied: + typeName = QLatin1String("Format_ARGB32_Premultiplied"); + break; + case QVideoFrame::Format_RGB32: + typeName = QLatin1String("Format_RGB32"); + break; + case QVideoFrame::Format_RGB24: + typeName = QLatin1String("Format_RGB24"); + break; + case QVideoFrame::Format_RGB565: + typeName = QLatin1String("Format_RGB565"); + break; + case QVideoFrame::Format_RGB555: + typeName = QLatin1String("Format_RGB555"); + break; + case QVideoFrame::Format_ARGB8565_Premultiplied: + typeName = QLatin1String("Format_ARGB8565_Premultiplied"); + break; + case QVideoFrame::Format_BGRA32: + typeName = QLatin1String("Format_BGRA32"); + break; + case QVideoFrame::Format_BGRA32_Premultiplied: + typeName = QLatin1String("Format_BGRA32_Premultiplied"); + break; + case QVideoFrame::Format_BGR32: + typeName = QLatin1String("Format_BGR32"); + break; + case QVideoFrame::Format_BGR24: + typeName = QLatin1String("Format_BGR24"); + break; + case QVideoFrame::Format_BGR565: + typeName = QLatin1String("Format_BGR565"); + break; + case QVideoFrame::Format_BGR555: + typeName = QLatin1String("Format_BGR555"); + break; + case QVideoFrame::Format_BGRA5658_Premultiplied: + typeName = QLatin1String("Format_BGRA5658_Premultiplied"); + break; + case QVideoFrame::Format_AYUV444: + typeName = QLatin1String("Format_AYUV444"); + break; + case QVideoFrame::Format_AYUV444_Premultiplied: + typeName = QLatin1String("Format_AYUV444_Premultiplied"); + break; + case QVideoFrame::Format_YUV444: + typeName = QLatin1String("Format_YUV444"); + break; + case QVideoFrame::Format_YUV420P: + typeName = QLatin1String("Format_YUV420P"); + break; + case QVideoFrame::Format_YV12: + typeName = QLatin1String("Format_YV12"); + break; + case QVideoFrame::Format_UYVY: + typeName = QLatin1String("Format_UYVY"); + break; + case QVideoFrame::Format_YUYV: + typeName = QLatin1String("Format_YUYV"); + break; + case QVideoFrame::Format_NV12: + typeName = QLatin1String("Format_NV12"); + break; + case QVideoFrame::Format_NV21: + typeName = QLatin1String("Format_NV21"); + break; + case QVideoFrame::Format_IMC1: + typeName = QLatin1String("Format_IMC1"); + break; + case QVideoFrame::Format_IMC2: + typeName = QLatin1String("Format_IMC2"); + break; + case QVideoFrame::Format_IMC3: + typeName = QLatin1String("Format_IMC3"); + break; + case QVideoFrame::Format_IMC4: + typeName = QLatin1String("Format_IMC4"); + break; + case QVideoFrame::Format_Y8: + typeName = QLatin1String("Format_Y8"); + break; + case QVideoFrame::Format_Y16: + typeName = QLatin1String("Format_Y16"); + default: + typeName = QString(QLatin1String("UserType(%1)" )).arg(int(f.pixelFormat())); + } + + dbg.nospace() << "QVideoSurfaceFormat(" << typeName; + dbg.nospace() << ", " << f.frameSize(); + dbg.nospace() << ", viewport=" << f.viewport(); + dbg.nospace() << ", pixelAspectRatio=" << f.pixelAspectRatio(); + dbg.nospace() << ")"; + + foreach(const QByteArray& propertyName, f.propertyNames()) + dbg << "\n " << propertyName.data() << " = " << f.property(propertyName.data()); + + return dbg.space(); +} +#endif + +QT_END_NAMESPACE diff --git a/src/multimedia/video/qvideosurfaceformat.h b/src/multimedia/video/qvideosurfaceformat.h new file mode 100644 index 000000000..72a2452a1 --- /dev/null +++ b/src/multimedia/video/qvideosurfaceformat.h @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QVIDEOSURFACEFORMAT_H +#define QVIDEOSURFACEFORMAT_H + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Multimedia) + +class QDebug; + +class QVideoSurfaceFormatPrivate; + +class Q_MULTIMEDIA_EXPORT QVideoSurfaceFormat +{ +public: + enum Direction + { + TopToBottom, + BottomToTop + }; + + enum ViewportMode + { + ResetViewport, + KeepViewport + }; + + enum YuvColorSpace + { + YCbCr_Undefined, + YCbCr_BT601, + YCbCr_BT709, + YCbCr_xvYCC601, + YCbCr_xvYCC709, + YCbCr_JPEG, +#ifndef qdoc + YCbCr_CustomMatrix +#endif + }; + + typedef QPair FrameRate; + + QVideoSurfaceFormat(); + QVideoSurfaceFormat( + const QSize &size, + QVideoFrame::PixelFormat pixelFormat, + QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle); + QVideoSurfaceFormat(const QVideoSurfaceFormat &format); + ~QVideoSurfaceFormat(); + + QVideoSurfaceFormat &operator =(const QVideoSurfaceFormat &format); + + bool operator ==(const QVideoSurfaceFormat &format) const; + bool operator !=(const QVideoSurfaceFormat &format) const; + + bool isValid() const; + + QVideoFrame::PixelFormat pixelFormat() const; + QAbstractVideoBuffer::HandleType handleType() const; + + QSize frameSize() const; + void setFrameSize(const QSize &size, ViewportMode mode = ResetViewport); + void setFrameSize(int width, int height, ViewportMode mode = ResetViewport); + + int frameWidth() const; + int frameHeight() const; + + QRect viewport() const; + void setViewport(const QRect &viewport); + + Direction scanLineDirection() const; + void setScanLineDirection(Direction direction); + + FrameRate frameRate() const; + void setFrameRate(const FrameRate &rate); + void setFrameRate(int numerator, int denominator = 1); + + QSize pixelAspectRatio() const; + void setPixelAspectRatio(const QSize &ratio); + void setPixelAspectRatio(int width, int height); + + YuvColorSpace yuvColorSpace() const; + void setYuvColorSpace(YuvColorSpace colorSpace); + + QSize sizeHint() const; + + QList propertyNames() const; + QVariant property(const char *name) const; + void setProperty(const char *name, const QVariant &value); + +private: + QSharedDataPointer d; +}; + +#ifndef QT_NO_DEBUG_STREAM +Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, const QVideoSurfaceFormat &); +#endif + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QVideoSurfaceFormat::FrameRate); +Q_DECLARE_METATYPE(QVideoSurfaceFormat::Direction) +Q_DECLARE_METATYPE(QVideoSurfaceFormat::YuvColorSpace) + +QT_END_HEADER + +#endif + diff --git a/src/multimedia/video/video.pri b/src/multimedia/video/video.pri new file mode 100644 index 000000000..0547a4c3e --- /dev/null +++ b/src/multimedia/video/video.pri @@ -0,0 +1,21 @@ + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qabstractvideobuffer.h \ + $$PWD/qabstractvideobuffer_p.h \ + $$PWD/qabstractvideosurface.h \ + $$PWD/qabstractvideosurface_p.h \ + $$PWD/qimagevideobuffer_p.h \ + $$PWD/qmemoryvideobuffer_p.h \ + $$PWD/qvideoframe.h \ + $$PWD/qvideosurfaceformat.h + +SOURCES += \ + $$PWD/qabstractvideobuffer.cpp \ + $$PWD/qabstractvideosurface.cpp \ + $$PWD/qimagevideobuffer.cpp \ + $$PWD/qmemoryvideobuffer.cpp \ + $$PWD/qvideoframe.cpp \ + $$PWD/qvideosurfaceformat.cpp + -- cgit v1.2.3