/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qabstractvideobuffer_p.h"

#include <qvariant.h>

#include <QDebug>


QT_BEGIN_NAMESPACE

static void qRegisterAbstractVideoBufferMetaTypes()
{
    qRegisterMetaType<QAbstractVideoBuffer::HandleType>();
    qRegisterMetaType<QAbstractVideoBuffer::MapMode>();
}

Q_CONSTRUCTOR_FUNCTION(qRegisterAbstractVideoBufferMetaTypes)

int QAbstractVideoBufferPrivate::map(
            QAbstractVideoBuffer::MapMode mode,
            int *numBytes,
            int bytesPerLine[4],
            uchar *data[4])
{
    data[0] = q_ptr->map(mode, numBytes, bytesPerLine);
    return data[0] ? 1 : 0;
}

/*!
    \class QAbstractVideoBuffer
    \brief The QAbstractVideoBuffer class is an abstraction for video data.
    \inmodule QtMultimedia
    \ingroup multimedia
    \ingroup multimedia_video

    The QVideoFrame class makes use of a QAbstractVideoBuffer internally to reference a buffer of
    video data.  Quite often video data buffers may reside in video memory rather than system
    memory, and this class provides an abstraction of the location.

    In addition, creating a subclass of QAbstractVideoBuffer will allow you to construct video
    frames from preallocated or static buffers, in cases where the QVideoFrame constructors
    taking a QByteArray or a QImage do not suffice.  This may be necessary when implementing
    a new hardware accelerated video system, for example.

    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 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 its 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 XvShmImageHandle The handle contains pointer to shared memory XVideo image.
    \value CoreImageHandle The handle contains pointer to \macos CIImage.
    \value QPixmapHandle The handle of the buffer is a QPixmap.
    \value EGLImageHandle The handle of the buffer is an EGLImageKHR.
    \value UserHandle Start value for user defined handle types.

    \sa handleType()
*/

/*!
    \enum QAbstractVideoBuffer::MapMode

    Enumerates how a video buffer's data is mapped to system memory.

    \value NotMapped The video buffer 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 is uninitialized when mapped, but the possibly modified 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 when it is unmapped.

    \sa mapMode(), map()
*/

/*!
    Constructs an abstract video buffer of the given \a type.
*/
QAbstractVideoBuffer::QAbstractVideoBuffer(HandleType type)
    : d_ptr(nullptr)
    , m_type(type)
{
}

/*!
    \internal
*/
QAbstractVideoBuffer::QAbstractVideoBuffer(QAbstractVideoBufferPrivate &dd, HandleType type)
    : d_ptr(&dd)
    , m_type(type)
{
    d_ptr->q_ptr = this;
}

/*!
    Destroys an abstract video buffer.
*/
QAbstractVideoBuffer::~QAbstractVideoBuffer()
{
    delete d_ptr;
}

/*!
    Releases the video buffer.

    QVideoFrame calls QAbstractVideoBuffer::release when the buffer is not used
    any more and can be destroyed or returned to the buffer pool.

    The default implementation deletes the buffer instance.
*/
void QAbstractVideoBuffer::release()
{
    delete this;
}

/*!
    Returns the type of a video buffer's handle.

    \sa handle()
*/
QAbstractVideoBuffer::HandleType QAbstractVideoBuffer::handleType() const
{
    return m_type;
}

/*!
    \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.

    In some cases the video buffer might be stored in video memory or otherwise inaccessible
    memory, so it is necessary to map the buffer before accessing the pixel data.  This may involve
    copying the contents around, so avoid mapping and unmapping unless required.

    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 \c QAbstractVideoBuffer::ReadOnly flag the
    mapped memory will be populated with the content of the buffer when initially mapped.  If the map
    mode includes the \c QAbstractVideoBuffer::WriteOnly flag the content of the possibly modified
    mapped memory will be written back to 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 and possibly update the buffer contents.

    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.

    \note Writing to memory that is mapped as read-only is undefined, and may result in changes
    to shared data or crashes.

    \sa unmap(), mapMode()
*/


/*!
    Independently maps the planes 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 \c QAbstractVideoBuffer::ReadOnly flag the
    mapped memory will be populated with the content of the buffer when initially mapped.  If the map
    mode includes the \c QAbstractVideoBuffer::WriteOnly flag the content of the possibly modified
    mapped memory will be written back to 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 and possibly update the buffer contents.

    Returns the number of planes in the mapped video data.  For each plane the line stride of that
    plane will be returned in \a bytesPerLine, and a pointer to the plane data will be returned in
    \a data.  The accumulative size of the mapped data is returned in \a numBytes.

    Not all buffer implementations will map more than the first plane, if this returns a single
    plane for a planar format the additional planes will have to be calculated from the line stride
    of the first plane and the frame height.  Mapping a buffer with QVideoFrame will do this for
    you.

    To implement this function create a derivative of QAbstractPlanarVideoBuffer and implement
    its map function instance instead.

    \since 5.4
*/
int QAbstractVideoBuffer::mapPlanes(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
{
    if (d_ptr) {
        return d_ptr->map(mode, numBytes, bytesPerLine, data);
    } else {
        data[0] = map(mode, numBytes, bytesPerLine);

        return data[0] ? 1 : 0;
    }
}

/*!
    \fn QAbstractVideoBuffer::unmap()

    Releases the memory mapped by the map() function.

    If the \l {QAbstractVideoBuffer::MapMode}{MapMode} included the \c QAbstractVideoBuffer::WriteOnly
    flag this will write the current content of the mapped memory back 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();
}


int QAbstractPlanarVideoBufferPrivate::map(
        QAbstractVideoBuffer::MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])
{
    return q_func()->map(mode, numBytes, bytesPerLine, data);
}

/*!
    \class QAbstractPlanarVideoBuffer
    \brief The QAbstractPlanarVideoBuffer class is an abstraction for planar video data.
    \inmodule QtMultimedia
    \ingroup QtMultimedia
    \ingroup multimedia
    \ingroup multimedia_video

    QAbstractPlanarVideoBuffer extends QAbstractVideoBuffer to support mapping
    non-continuous planar video data.  Implement this instead of QAbstractVideoBuffer when the
    abstracted video data stores planes in separate buffers or includes padding between planes
    which would interfere with calculating offsets from the bytes per line and frame height.

    \sa QAbstractVideoBuffer::mapPlanes()
    \since 5.4
*/

/*!
    Constructs an abstract planar video buffer of the given \a type.
*/
QAbstractPlanarVideoBuffer::QAbstractPlanarVideoBuffer(HandleType type)
    : QAbstractVideoBuffer(*new QAbstractPlanarVideoBufferPrivate, type)
{
}

/*!
    \internal
*/
QAbstractPlanarVideoBuffer::QAbstractPlanarVideoBuffer(
        QAbstractPlanarVideoBufferPrivate &dd, HandleType type)
    : QAbstractVideoBuffer(dd, type)
{
}
/*!
    Destroys an abstract planar video buffer.
*/
QAbstractPlanarVideoBuffer::~QAbstractPlanarVideoBuffer()
{
}

/*!
    \internal
*/
uchar *QAbstractPlanarVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine)
{
    uchar *data[4];
    int strides[4];
    if (map(mode, numBytes, strides, data) > 0) {
        if (bytesPerLine)
            *bytesPerLine = strides[0];
        return data[0];
    } else {
        return nullptr;
    }
}

/*!
    \fn int QAbstractPlanarVideoBuffer::map(MapMode mode, int *numBytes, int bytesPerLine[4], uchar *data[4])

    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 \c QAbstractVideoBuffer::ReadOnly flag the
    mapped memory will be populated with the content of the buffer when initially mapped.  If the map
    mode includes the \c QAbstractVideoBuffer::WriteOnly flag the content of the possibly modified
    mapped memory will be written back to 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 and possibly update the buffer contents.

    Returns the number of planes in the mapped video data.  For each plane the line stride of that
    plane will be returned in \a bytesPerLine, and a pointer to the plane data will be returned in
    \a data.  The accumulative size of the mapped data is returned in \a numBytes.

    \sa QAbstractVideoBuffer::map(), QAbstractVideoBuffer::unmap(), QAbstractVideoBuffer::mapMode()
*/

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, QAbstractVideoBuffer::HandleType type)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace();
    switch (type) {
    case QAbstractVideoBuffer::NoHandle:
        return dbg << "NoHandle";
    case QAbstractVideoBuffer::GLTextureHandle:
        return dbg << "GLTextureHandle";
    case QAbstractVideoBuffer::XvShmImageHandle:
        return dbg << "XvShmImageHandle";
    case QAbstractVideoBuffer::CoreImageHandle:
        return dbg << "CoreImageHandle";
    case QAbstractVideoBuffer::QPixmapHandle:
        return dbg << "QPixmapHandle";
    default:
        return dbg << "UserHandle(" << int(type) << ')';
    }
}

QDebug operator<<(QDebug dbg, QAbstractVideoBuffer::MapMode mode)
{
    QDebugStateSaver saver(dbg);
    dbg.nospace();
    switch (mode) {
    case QAbstractVideoBuffer::ReadOnly:
        return dbg << "ReadOnly";
    case QAbstractVideoBuffer::ReadWrite:
        return dbg << "ReadWrite";
    case QAbstractVideoBuffer::WriteOnly:
        return dbg << "WriteOnly";
    default:
        return dbg << "NotMapped";
    }
}
#endif

QT_END_NAMESPACE
