/****************************************************************************
**
** 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 <QtMultimedia/private/qtmultimediaglobal_p.h>
#include "qgstutils_p.h"

#include <QtCore/qdatetime.h>
#include <QtCore/qdir.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qvariant.h>
#include <QtCore/qregularexpression.h>
#include <QtCore/qsize.h>
#include <QtCore/qset.h>
#include <QtCore/qstringlist.h>
#include <QtGui/qimage.h>
#include <qaudioformat.h>
#include <QtCore/qelapsedtimer.h>
#include <QtMultimedia/qvideosurfaceformat.h>
#include <private/qmultimediautils_p.h>

#include <gst/audio/audio.h>
#include <gst/video/video.h>

template<typename T, int N> static int lengthOf(const T (&)[N]) { return N; }

#if QT_CONFIG(linux_v4l)
#  include <private/qcore_unix_p.h>
#  include <linux/videodev2.h>
#endif

#include "qgstreamervideoinputdevicecontrol_p.h"

QT_BEGIN_NAMESPACE

//internal
static void addTagToMap(const GstTagList *list,
                        const gchar *tag,
                        gpointer user_data)
{
    QMap<QByteArray, QVariant> *map = reinterpret_cast<QMap<QByteArray, QVariant>* >(user_data);

    GValue val;
    val.g_type = 0;
    gst_tag_list_copy_value(&val,list,tag);

    switch( G_VALUE_TYPE(&val) ) {
        case G_TYPE_STRING:
        {
            const gchar *str_value = g_value_get_string(&val);
            map->insert(QByteArray(tag), QString::fromUtf8(str_value));
            break;
        }
        case G_TYPE_INT:
            map->insert(QByteArray(tag), g_value_get_int(&val));
            break;
        case G_TYPE_UINT:
            map->insert(QByteArray(tag), g_value_get_uint(&val));
            break;
        case G_TYPE_LONG:
            map->insert(QByteArray(tag), qint64(g_value_get_long(&val)));
            break;
        case G_TYPE_BOOLEAN:
            map->insert(QByteArray(tag), g_value_get_boolean(&val));
            break;
        case G_TYPE_CHAR:
#if GLIB_CHECK_VERSION(2,32,0)
            map->insert(QByteArray(tag), g_value_get_schar(&val));
#else
            map->insert(QByteArray(tag), g_value_get_char(&val));
#endif
            break;
        case G_TYPE_DOUBLE:
            map->insert(QByteArray(tag), g_value_get_double(&val));
            break;
        default:
            // GST_TYPE_DATE is a function, not a constant, so pull it out of the switch
#if GST_CHECK_VERSION(1,0,0)
            if (G_VALUE_TYPE(&val) == G_TYPE_DATE) {
                const GDate *date = (const GDate *)g_value_get_boxed(&val);
#else
            if (G_VALUE_TYPE(&val) == GST_TYPE_DATE) {
                const GDate *date = gst_value_get_date(&val);
#endif
                if (g_date_valid(date)) {
                    int year = g_date_get_year(date);
                    int month = g_date_get_month(date);
                    int day = g_date_get_day(date);
                    map->insert(QByteArray(tag), QDate(year,month,day));
                    if (!map->contains("year"))
                        map->insert("year", year);
                }
#if GST_CHECK_VERSION(1,0,0)
            } else if (G_VALUE_TYPE(&val) == GST_TYPE_DATE_TIME) {
                const GstDateTime *dateTime = (const GstDateTime *)g_value_get_boxed(&val);
                int year = gst_date_time_has_year(dateTime) ? gst_date_time_get_year(dateTime) : 0;
                int month = gst_date_time_has_month(dateTime) ? gst_date_time_get_month(dateTime) : 0;
                int day = gst_date_time_has_day(dateTime) ? gst_date_time_get_day(dateTime) : 0;
                if (gst_date_time_has_time(dateTime)) {
                    int hour = gst_date_time_get_hour(dateTime);
                    int minute = gst_date_time_get_minute(dateTime);
                    int second = gst_date_time_get_second(dateTime);
                    float tz = gst_date_time_get_time_zone_offset(dateTime);
                    QDateTime dateTime(QDate(year, month, day), QTime(hour, minute, second),
                                       Qt::OffsetFromUTC, tz * 60 * 60);
                    map->insert(QByteArray(tag), dateTime);
                } else if (year > 0 && month > 0 && day > 0) {
                    map->insert(QByteArray(tag), QDate(year,month,day));
                }
                if (!map->contains("year") && year > 0)
                    map->insert("year", year);
            } else if (G_VALUE_TYPE(&val) == GST_TYPE_SAMPLE) {
                GstSample *sample = (GstSample *)g_value_get_boxed(&val);
                GstCaps* caps = gst_sample_get_caps(sample);
                if (caps && !gst_caps_is_empty(caps)) {
                    GstStructure *structure = gst_caps_get_structure(caps, 0);
                    const gchar *name = gst_structure_get_name(structure);
                    if (QByteArray(name).startsWith("image/")) {
                        GstBuffer *buffer = gst_sample_get_buffer(sample);
                        if (buffer) {
                            GstMapInfo info;
                            gst_buffer_map(buffer, &info, GST_MAP_READ);
                            map->insert(QByteArray(tag), QImage::fromData(info.data, info.size, name));
                            gst_buffer_unmap(buffer, &info);
                        }
                    }
                }
#endif
            } else if (G_VALUE_TYPE(&val) == GST_TYPE_FRACTION) {
                int nom = gst_value_get_fraction_numerator(&val);
                int denom = gst_value_get_fraction_denominator(&val);

                if (denom > 0) {
                    map->insert(QByteArray(tag), double(nom)/denom);
                }
            }
            break;
    }

    g_value_unset(&val);
}

/*!
    \class QGstUtils
    \internal
*/

/*!
  Convert GstTagList structure to QMap<QByteArray, QVariant>.

  Mapping to int, bool, char, string, fractions and date are supported.
  Fraction values are converted to doubles.
*/
QMap<QByteArray, QVariant> QGstUtils::gstTagListToMap(const GstTagList *tags)
{
    QMap<QByteArray, QVariant> res;
    gst_tag_list_foreach(tags, addTagToMap, &res);

    return res;
}

/*!
  Returns resolution of \a caps.
  If caps doesn't have a valid size, an empty QSize is returned.
*/
QSize QGstUtils::capsResolution(const GstCaps *caps)
{
    if (gst_caps_get_size(caps) == 0)
        return QSize();

    return structureResolution(gst_caps_get_structure(caps, 0));
}

/*!
  Returns aspect ratio corrected resolution of \a caps.
  If caps doesn't have a valid size, an empty QSize is returned.
*/
QSize QGstUtils::capsCorrectedResolution(const GstCaps *caps)
{
    QSize size;

    if (caps) {
        size = capsResolution(caps);

        gint aspectNum = 0;
        gint aspectDenum = 0;
        if (!size.isEmpty() && gst_structure_get_fraction(
                    gst_caps_get_structure(caps, 0), "pixel-aspect-ratio", &aspectNum, &aspectDenum)) {
            if (aspectDenum > 0)
                size.setWidth(size.width()*aspectNum/aspectDenum);
        }
    }

    return size;
}


#if GST_CHECK_VERSION(1,0,0)
namespace {

struct AudioFormat
{
    GstAudioFormat format;
    QAudioFormat::SampleType sampleType;
    QAudioFormat::Endian byteOrder;
    int sampleSize;
};
static const AudioFormat qt_audioLookup[] =
{
    { GST_AUDIO_FORMAT_S8   , QAudioFormat::SignedInt  , QAudioFormat::LittleEndian, 8  },
    { GST_AUDIO_FORMAT_U8   , QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 8  },
    { GST_AUDIO_FORMAT_S16LE, QAudioFormat::SignedInt  , QAudioFormat::LittleEndian, 16 },
    { GST_AUDIO_FORMAT_S16BE, QAudioFormat::SignedInt  , QAudioFormat::BigEndian   , 16 },
    { GST_AUDIO_FORMAT_U16LE, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 16 },
    { GST_AUDIO_FORMAT_U16BE, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian   , 16 },
    { GST_AUDIO_FORMAT_S32LE, QAudioFormat::SignedInt  , QAudioFormat::LittleEndian, 32 },
    { GST_AUDIO_FORMAT_S32BE, QAudioFormat::SignedInt  , QAudioFormat::BigEndian   , 32 },
    { GST_AUDIO_FORMAT_U32LE, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 32 },
    { GST_AUDIO_FORMAT_U32BE, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian   , 32 },
    { GST_AUDIO_FORMAT_S24LE, QAudioFormat::SignedInt  , QAudioFormat::LittleEndian, 24 },
    { GST_AUDIO_FORMAT_S24BE, QAudioFormat::SignedInt  , QAudioFormat::BigEndian   , 24 },
    { GST_AUDIO_FORMAT_U24LE, QAudioFormat::UnSignedInt, QAudioFormat::LittleEndian, 24 },
    { GST_AUDIO_FORMAT_U24BE, QAudioFormat::UnSignedInt, QAudioFormat::BigEndian   , 24 },
    { GST_AUDIO_FORMAT_F32LE, QAudioFormat::Float      , QAudioFormat::LittleEndian, 32 },
    { GST_AUDIO_FORMAT_F32BE, QAudioFormat::Float      , QAudioFormat::BigEndian   , 32 },
    { GST_AUDIO_FORMAT_F64LE, QAudioFormat::Float      , QAudioFormat::LittleEndian, 64 },
    { GST_AUDIO_FORMAT_F64BE, QAudioFormat::Float      , QAudioFormat::BigEndian   , 64 }
};

}
#endif

/*!
  Returns audio format for caps.
  If caps doesn't have a valid audio format, an empty QAudioFormat is returned.
*/

QAudioFormat QGstUtils::audioFormatForCaps(const GstCaps *caps)
{
    QAudioFormat format;
#if GST_CHECK_VERSION(1,0,0)
    GstAudioInfo info;
    if (gst_audio_info_from_caps(&info, caps)) {
        for (int i = 0; i < lengthOf(qt_audioLookup); ++i) {
            if (qt_audioLookup[i].format != info.finfo->format)
                continue;

            format.setSampleType(qt_audioLookup[i].sampleType);
            format.setByteOrder(qt_audioLookup[i].byteOrder);
            format.setSampleSize(qt_audioLookup[i].sampleSize);
            format.setSampleRate(info.rate);
            format.setChannelCount(info.channels);
            format.setCodec(QStringLiteral("audio/pcm"));

            return format;
        }
    }
#else
    const GstStructure *structure = gst_caps_get_structure(caps, 0);

    if (qstrcmp(gst_structure_get_name(structure), "audio/x-raw-int") == 0) {

        format.setCodec("audio/pcm");

        int endianness = 0;
        gst_structure_get_int(structure, "endianness", &endianness);
        if (endianness == 1234)
            format.setByteOrder(QAudioFormat::LittleEndian);
        else if (endianness == 4321)
            format.setByteOrder(QAudioFormat::BigEndian);

        gboolean isSigned = FALSE;
        gst_structure_get_boolean(structure, "signed", &isSigned);
        if (isSigned)
            format.setSampleType(QAudioFormat::SignedInt);
        else
            format.setSampleType(QAudioFormat::UnSignedInt);

        // Number of bits allocated per sample.
        int width = 0;
        gst_structure_get_int(structure, "width", &width);

        // The number of bits used per sample. This must be less than or equal to the width.
        int depth = 0;
        gst_structure_get_int(structure, "depth", &depth);

        if (width != depth) {
            // Unsupported sample layout.
            return QAudioFormat();
        }
        format.setSampleSize(width);

        int rate = 0;
        gst_structure_get_int(structure, "rate", &rate);
        format.setSampleRate(rate);

        int channels = 0;
        gst_structure_get_int(structure, "channels", &channels);
        format.setChannelCount(channels);

    } else if (qstrcmp(gst_structure_get_name(structure), "audio/x-raw-float") == 0) {

        format.setCodec("audio/pcm");

        int endianness = 0;
        gst_structure_get_int(structure, "endianness", &endianness);
        if (endianness == 1234)
            format.setByteOrder(QAudioFormat::LittleEndian);
        else if (endianness == 4321)
            format.setByteOrder(QAudioFormat::BigEndian);

        format.setSampleType(QAudioFormat::Float);

        int width = 0;
        gst_structure_get_int(structure, "width", &width);

        format.setSampleSize(width);

        int rate = 0;
        gst_structure_get_int(structure, "rate", &rate);
        format.setSampleRate(rate);

        int channels = 0;
        gst_structure_get_int(structure, "channels", &channels);
        format.setChannelCount(channels);

    } else {
        return QAudioFormat();
    }
#endif
    return format;
}

#if GST_CHECK_VERSION(1,0,0)
/*
  Returns audio format for a sample.
  If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned.
*/
QAudioFormat QGstUtils::audioFormatForSample(GstSample *sample)
{
    GstCaps* caps = gst_sample_get_caps(sample);
    if (!caps)
        return QAudioFormat();

    return QGstUtils::audioFormatForCaps(caps);
}
#else
/*!
  Returns audio format for a buffer.
  If the buffer doesn't have a valid audio format, an empty QAudioFormat is returned.
*/
QAudioFormat QGstUtils::audioFormatForBuffer(GstBuffer *buffer)
{
    GstCaps* caps = gst_buffer_get_caps(buffer);
    if (!caps)
        return QAudioFormat();

    QAudioFormat format = QGstUtils::audioFormatForCaps(caps);
    gst_caps_unref(caps);
    return format;
}
#endif

/*!
  Builds GstCaps for an audio format.
  Returns 0 if the audio format is not valid.
  Caller must unref GstCaps.
*/

GstCaps *QGstUtils::capsForAudioFormat(const QAudioFormat &format)
{
    if (!format.isValid())
        return 0;

#if GST_CHECK_VERSION(1,0,0)
    const QAudioFormat::SampleType sampleType = format.sampleType();
    const QAudioFormat::Endian byteOrder = format.byteOrder();
    const int sampleSize = format.sampleSize();

    for (int i = 0; i < lengthOf(qt_audioLookup); ++i) {
        if (qt_audioLookup[i].sampleType != sampleType
                || qt_audioLookup[i].byteOrder != byteOrder
                || qt_audioLookup[i].sampleSize != sampleSize) {
            continue;
        }

        return gst_caps_new_simple(
                    "audio/x-raw",
                    "format"  , G_TYPE_STRING, gst_audio_format_to_string(qt_audioLookup[i].format),
                    "rate"    , G_TYPE_INT   , format.sampleRate(),
                    "channels", G_TYPE_INT   , format.channelCount(),
                    NULL);
    }
    return 0;
#else
    GstStructure *structure = 0;

    if (format.isValid()) {
        if (format.sampleType() == QAudioFormat::SignedInt || format.sampleType() == QAudioFormat::UnSignedInt) {
            structure = gst_structure_new("audio/x-raw-int", NULL);
        } else if (format.sampleType() == QAudioFormat::Float) {
            structure = gst_structure_new("audio/x-raw-float", NULL);
        }
    }

    GstCaps *caps = 0;

    if (structure) {
        gst_structure_set(structure, "rate", G_TYPE_INT, format.sampleRate(), NULL);
        gst_structure_set(structure, "channels", G_TYPE_INT, format.channelCount(), NULL);
        gst_structure_set(structure, "width", G_TYPE_INT, format.sampleSize(), NULL);
        gst_structure_set(structure, "depth", G_TYPE_INT, format.sampleSize(), NULL);

        if (format.byteOrder() == QAudioFormat::LittleEndian)
            gst_structure_set(structure, "endianness", G_TYPE_INT, 1234, NULL);
        else if (format.byteOrder() == QAudioFormat::BigEndian)
            gst_structure_set(structure, "endianness", G_TYPE_INT, 4321, NULL);

        if (format.sampleType() == QAudioFormat::SignedInt)
            gst_structure_set(structure, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
        else if (format.sampleType() == QAudioFormat::UnSignedInt)
            gst_structure_set(structure, "signed", G_TYPE_BOOLEAN, FALSE, NULL);

        caps = gst_caps_new_empty();
        Q_ASSERT(caps);
        gst_caps_append_structure(caps, structure);
    }

    return caps;
#endif
}

void QGstUtils::initializeGst()
{
    static bool initialized = false;
    if (!initialized) {
        initialized = true;
        gst_init(NULL, NULL);
    }
}

namespace {
    const char* getCodecAlias(const QString &codec)
    {
        if (codec.startsWith(QLatin1String("avc1.")))
            return "video/x-h264";

        if (codec.startsWith(QLatin1String("mp4a.")))
            return "audio/mpeg4";

        if (codec.startsWith(QLatin1String("mp4v.20.")))
            return "video/mpeg4";

        if (codec == QLatin1String("samr"))
            return "audio/amr";

        return 0;
    }

    const char* getMimeTypeAlias(const QString &mimeType)
    {
        if (mimeType == QLatin1String("video/mp4"))
            return "video/mpeg4";

        if (mimeType == QLatin1String("audio/mp4"))
            return "audio/mpeg4";

        if (mimeType == QLatin1String("video/ogg")
            || mimeType == QLatin1String("audio/ogg"))
            return "application/ogg";

        return 0;
    }
}

QMultimedia::SupportEstimate QGstUtils::hasSupport(const QString &mimeType,
                                                    const QStringList &codecs,
                                                    const QSet<QString> &supportedMimeTypeSet)
{
    if (supportedMimeTypeSet.isEmpty())
        return QMultimedia::NotSupported;

    QString mimeTypeLowcase = mimeType.toLower();
    bool containsMimeType = supportedMimeTypeSet.contains(mimeTypeLowcase);
    if (!containsMimeType) {
        const char* mimeTypeAlias = getMimeTypeAlias(mimeTypeLowcase);
        containsMimeType = supportedMimeTypeSet.contains(QLatin1String(mimeTypeAlias));
        if (!containsMimeType) {
            containsMimeType = supportedMimeTypeSet.contains(QLatin1String("video/") + mimeTypeLowcase)
                               || supportedMimeTypeSet.contains(QLatin1String("video/x-") + mimeTypeLowcase)
                               || supportedMimeTypeSet.contains(QLatin1String("audio/") + mimeTypeLowcase)
                               || supportedMimeTypeSet.contains(QLatin1String("audio/x-") + mimeTypeLowcase);
        }
    }

    int supportedCodecCount = 0;
    for (const QString &codec : codecs) {
        QString codecLowcase = codec.toLower();
        const char* codecAlias = getCodecAlias(codecLowcase);
        if (codecAlias) {
            if (supportedMimeTypeSet.contains(QLatin1String(codecAlias)))
                supportedCodecCount++;
        } else if (supportedMimeTypeSet.contains(QLatin1String("video/") + codecLowcase)
                   || supportedMimeTypeSet.contains(QLatin1String("video/x-") + codecLowcase)
                   || supportedMimeTypeSet.contains(QLatin1String("audio/") + codecLowcase)
                   || supportedMimeTypeSet.contains(QLatin1String("audio/x-") + codecLowcase)) {
            supportedCodecCount++;
        }
    }
    if (supportedCodecCount > 0 && supportedCodecCount == codecs.size())
        return QMultimedia::ProbablySupported;

    if (supportedCodecCount == 0 && !containsMimeType)
        return QMultimedia::NotSupported;

    return QMultimedia::MaybeSupported;
}

namespace {

typedef QHash<GstElementFactory *, QVector<QGstUtils::CameraInfo> > FactoryCameraInfoMap;

Q_GLOBAL_STATIC(FactoryCameraInfoMap, qt_camera_device_info);

}

QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *factory)
{
    static QElapsedTimer camerasCacheAgeTimer;
    if (camerasCacheAgeTimer.isValid() && camerasCacheAgeTimer.elapsed() > 500) // ms
        qt_camera_device_info()->clear();

    FactoryCameraInfoMap::const_iterator it = qt_camera_device_info()->constFind(factory);
    if (it != qt_camera_device_info()->constEnd())
        return *it;

    QVector<CameraInfo> &devices = (*qt_camera_device_info())[factory];

    if (factory) {
        bool hasVideoSource = false;

        const GType type = gst_element_factory_get_element_type(factory);
        GObjectClass * const objectClass = type
                ? static_cast<GObjectClass *>(g_type_class_ref(type))
                : 0;
        if (objectClass) {
            if (g_object_class_find_property(objectClass, "camera-device")) {
                const CameraInfo primary = {
                    QStringLiteral("primary"),
                    QGstreamerVideoInputDeviceControl::primaryCamera(),
                    0,
                    QCamera::BackFace,
                    QByteArray()
                };
                const CameraInfo secondary = {
                    QStringLiteral("secondary"),
                    QGstreamerVideoInputDeviceControl::secondaryCamera(),
                    0,
                    QCamera::FrontFace,
                    QByteArray()
                };

                devices.append(primary);
                devices.append(secondary);

                GstElement *camera = g_object_class_find_property(objectClass, "sensor-mount-angle")
                        ? gst_element_factory_create(factory, 0)
                        : 0;
                if (camera) {
                    if (gst_element_set_state(camera, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) {
                        // no-op
                    } else for (int i = 0; i < 2; ++i) {
                        gint orientation = 0;
                        g_object_set(G_OBJECT(camera), "camera-device", i, NULL);
                        g_object_get(G_OBJECT(camera), "sensor-mount-angle", &orientation, NULL);

                        devices[i].orientation = (720 - orientation) % 360;
                    }
                    gst_element_set_state(camera, GST_STATE_NULL);
                    gst_object_unref(GST_OBJECT(camera));

                }
            } else if (g_object_class_find_property(objectClass, "video-source")) {
                hasVideoSource = true;
            }

            g_type_class_unref(objectClass);
        }

        if (!devices.isEmpty() || !hasVideoSource) {
            camerasCacheAgeTimer.restart();
            return devices;
        }
    }

#if QT_CONFIG(linux_v4l)
    QDir devDir(QStringLiteral("/dev"));
    devDir.setFilter(QDir::System);

    const QFileInfoList entries = devDir.entryInfoList(QStringList()
                << QStringLiteral("video*"));

    for (const QFileInfo &entryInfo : entries) {
        //qDebug() << "Try" << entryInfo.filePath();

        int fd = qt_safe_open(entryInfo.filePath().toLatin1().constData(), O_RDWR );
        if (fd == -1)
            continue;

        bool isCamera = false;

        v4l2_input input;
        memset(&input, 0, sizeof(input));
        for (; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; ++input.index) {
            if (input.type == V4L2_INPUT_TYPE_CAMERA || input.type == 0) {
                const int ret = ::ioctl(fd, VIDIOC_S_INPUT, &input.index);
                isCamera = (ret == 0 || errno == ENOTTY || errno == EBUSY);
                break;
            }
        }

        if (isCamera) {
            // find out its driver "name"
            QByteArray driver;
            QString name;
            struct v4l2_capability vcap;
            memset(&vcap, 0, sizeof(struct v4l2_capability));

            if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0) {
                name = entryInfo.fileName();
            } else {
                driver = QByteArray((const char*)vcap.driver);
                name = QString::fromUtf8((const char*)vcap.card);
                if (name.isEmpty())
                    name = entryInfo.fileName();
            }
            //qDebug() << "found camera: " << name;


            CameraInfo device = {
                entryInfo.absoluteFilePath(),
                name,
                0,
                QCamera::UnspecifiedPosition,
                driver
            };
            devices.append(device);
        }
        qt_safe_close(fd);
    }
    camerasCacheAgeTimer.restart();
#endif // linux_v4l

#if GST_CHECK_VERSION(1,4,0) && (defined(Q_OS_WIN) || defined(Q_OS_MACOS))
    if (!devices.isEmpty())
        return devices;

#if defined(Q_OS_WIN)
    const char *propName = "device-path";
    auto deviceDesc = [](GValue *value) {
        gchar *desc = g_value_dup_string(value);
        const QString id = QLatin1String(desc);
        g_free(desc);
        return id;
    };
#elif defined(Q_OS_MACOS)
    const char *propName = "device-index";
    auto deviceDesc = [](GValue *value) {
        return QString::number(g_value_get_int(value));
    };
#endif

    QGstUtils::initializeGst();
    GstDeviceMonitor *monitor = gst_device_monitor_new();
    auto caps = gst_caps_new_empty_simple("video/x-raw");
    gst_device_monitor_add_filter(monitor, "Video/Source", caps);
    gst_caps_unref(caps);

    GList *devs = gst_device_monitor_get_devices(monitor);
    while (devs) {
        GstDevice *dev = reinterpret_cast<GstDevice*>(devs->data);
        GstElement *element = gst_device_create_element(dev, nullptr);
        if (element) {
            gchar *name = gst_device_get_display_name(dev);
            const QString deviceName = QLatin1String(name);
            g_free(name);
            GParamSpec *prop = g_object_class_find_property(G_OBJECT_GET_CLASS(element), propName);
            if (prop) {
                GValue value = G_VALUE_INIT;
                g_value_init(&value, prop->value_type);
                g_object_get_property(G_OBJECT(element), prop->name, &value);
                const QString deviceId = deviceDesc(&value);
                g_value_unset(&value);

                CameraInfo device = {
                    deviceId,
                    deviceName,
                    0,
                    QCamera::UnspecifiedPosition,
                    QByteArray()
                };

                devices.append(device);
            }

            gst_object_unref(element);
        }

        gst_object_unref(dev);
        devs = g_list_delete_link(devs, devs);
    }
    gst_object_unref(monitor);
#endif // GST_CHECK_VERSION(1,4,0) && (defined(Q_OS_WIN) || defined(Q_OS_MACOS))

    return devices;
}

QList<QByteArray> QGstUtils::cameraDevices(GstElementFactory * factory)
{
    QList<QByteArray> devices;

    const auto cameras = enumerateCameras(factory);
    devices.reserve(cameras.size());
    for (const CameraInfo &camera : cameras)
        devices.append(camera.name.toUtf8());

    return devices;
}

QString QGstUtils::cameraDescription(const QString &device, GstElementFactory * factory)
{
    const auto cameras = enumerateCameras(factory);
    for (const CameraInfo &camera : cameras) {
        if (camera.name == device)
            return camera.description;
    }
    return QString();
}

QCamera::Position QGstUtils::cameraPosition(const QString &device, GstElementFactory * factory)
{
    const auto cameras = enumerateCameras(factory);
    for (const CameraInfo &camera : cameras) {
        if (camera.name == device)
            return camera.position;
    }
    return QCamera::UnspecifiedPosition;
}

int QGstUtils::cameraOrientation(const QString &device, GstElementFactory * factory)
{
    const auto cameras = enumerateCameras(factory);
    for (const CameraInfo &camera : cameras) {
        if (camera.name == device)
            return camera.orientation;
    }
    return 0;
}

QByteArray QGstUtils::cameraDriver(const QString &device, GstElementFactory *factory)
{
    const auto cameras = enumerateCameras(factory);
    for (const CameraInfo &camera : cameras) {
        if (camera.name == device)
            return camera.driver;
    }
    return QByteArray();
}

QSet<QString> QGstUtils::supportedMimeTypes(bool (*isValidFactory)(GstElementFactory *factory))
{
    QSet<QString> supportedMimeTypes;

    //enumerate supported mime types
    gst_init(NULL, NULL);

#if GST_CHECK_VERSION(1,0,0)
    GstRegistry *registry = gst_registry_get();
    GList *orig_plugins = gst_registry_get_plugin_list(registry);
#else
    GstRegistry *registry = gst_registry_get_default();
    GList *orig_plugins = gst_default_registry_get_plugin_list ();
#endif
    for (GList *plugins = orig_plugins; plugins; plugins = g_list_next(plugins)) {
        GstPlugin *plugin = (GstPlugin *) (plugins->data);
#if GST_CHECK_VERSION(1,0,0)
        if (GST_OBJECT_FLAG_IS_SET(GST_OBJECT(plugin), GST_PLUGIN_FLAG_BLACKLISTED))
            continue;
#else
        if (plugin->flags & (1<<1)) //GST_PLUGIN_FLAG_BLACKLISTED
            continue;
#endif

        GList *orig_features = gst_registry_get_feature_list_by_plugin(
                    registry, gst_plugin_get_name(plugin));
        for (GList *features = orig_features; features; features = g_list_next(features)) {
            if (G_UNLIKELY(features->data == NULL))
                continue;

            GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);
            GstElementFactory *factory;

            if (GST_IS_TYPE_FIND_FACTORY(feature)) {
                QString name(QLatin1String(gst_plugin_feature_get_name(feature)));
                if (name.contains(QLatin1Char('/'))) //filter out any string without '/' which is obviously not a mime type
                    supportedMimeTypes.insert(name.toLower());
                continue;
            } else if (!GST_IS_ELEMENT_FACTORY (feature)
                        || !(factory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(feature)))) {
                continue;
            } else if (!isValidFactory(factory)) {
                // Do nothing
            } else for (const GList *pads = gst_element_factory_get_static_pad_templates(factory);
                        pads;
                        pads = g_list_next(pads)) {
                GstStaticPadTemplate *padtemplate = static_cast<GstStaticPadTemplate *>(pads->data);

                if (padtemplate->direction == GST_PAD_SINK && padtemplate->static_caps.string) {
                    GstCaps *caps = gst_static_caps_get(&padtemplate->static_caps);
                    if (gst_caps_is_any(caps) || gst_caps_is_empty(caps)) {
                    } else for (guint i = 0; i < gst_caps_get_size(caps); i++) {
                        GstStructure *structure = gst_caps_get_structure(caps, i);
                        QString nameLowcase = QString::fromLatin1(gst_structure_get_name(structure)).toLower();

                        supportedMimeTypes.insert(nameLowcase);
                        if (nameLowcase.contains(QLatin1String("mpeg"))) {
                            //Because mpeg version number is only included in the detail
                            //description,  it is necessary to manually extract this information
                            //in order to match the mime type of mpeg4.
                            const GValue *value = gst_structure_get_value(structure, "mpegversion");
                            if (value) {
                                gchar *str = gst_value_serialize(value);
                                QString versions = QLatin1String(str);
                                const QStringList elements = versions.split(QRegularExpression(QLatin1String("\\D+")), QString::SkipEmptyParts);
                                for (const QString &e : elements)
                                    supportedMimeTypes.insert(nameLowcase + e);
                                g_free(str);
                            }
                        }
                    }
                }
            }
            gst_object_unref(factory);
        }
        gst_plugin_feature_list_free(orig_features);
    }
    gst_plugin_list_free (orig_plugins);

#if defined QT_SUPPORTEDMIMETYPES_DEBUG
    QStringList list = supportedMimeTypes.toList();
    list.sort();
    if (qgetenv("QT_DEBUG_PLUGINS").toInt() > 0) {
        for (const QString &type : qAsConst(list))
            qDebug() << type;
    }
#endif
    return supportedMimeTypes;
}

#if GST_CHECK_VERSION(1, 0, 0)
namespace {

struct ColorFormat { QImage::Format imageFormat; GstVideoFormat gstFormat; };
static const ColorFormat qt_colorLookup[] =
{
    { QImage::Format_RGBX8888, GST_VIDEO_FORMAT_RGBx  },
    { QImage::Format_RGBA8888, GST_VIDEO_FORMAT_RGBA  },
    { QImage::Format_RGB888  , GST_VIDEO_FORMAT_RGB   },
    { QImage::Format_RGB16   , GST_VIDEO_FORMAT_RGB16 }
};

}
#endif

#if GST_CHECK_VERSION(1,0,0)
QImage QGstUtils::bufferToImage(GstBuffer *buffer, const GstVideoInfo &videoInfo)
#else
QImage QGstUtils::bufferToImage(GstBuffer *buffer)
#endif
{
    QImage img;

#if GST_CHECK_VERSION(1,0,0)
    GstVideoInfo info = videoInfo;
    GstVideoFrame frame;
    if (!gst_video_frame_map(&frame, &info, buffer, GST_MAP_READ))
        return img;
#else
    GstCaps *caps = gst_buffer_get_caps(buffer);
    if (!caps)
        return img;

    GstStructure *structure = gst_caps_get_structure (caps, 0);
    gint width = 0;
    gint height = 0;

    if (!structure
            || !gst_structure_get_int(structure, "width", &width)
            || !gst_structure_get_int(structure, "height", &height)
            || width <= 0
            || height <= 0) {
        gst_caps_unref(caps);
        return img;
    }
    gst_caps_unref(caps);
#endif

#if GST_CHECK_VERSION(1,0,0)
    if (videoInfo.finfo->format == GST_VIDEO_FORMAT_I420) {
        const int width = videoInfo.width;
        const int height = videoInfo.height;

        const int stride[] = { frame.info.stride[0], frame.info.stride[1], frame.info.stride[2] };
        const uchar *data[] = {
            static_cast<const uchar *>(frame.data[0]),
            static_cast<const uchar *>(frame.data[1]),
            static_cast<const uchar *>(frame.data[2])
        };
#else
    if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
        const int stride[] = { width, width / 2, width / 2 };
        const uchar *data[] = {
            (const uchar *)buffer->data,
            (const uchar *)buffer->data + width * height,
            (const uchar *)buffer->data + width * height * 5 / 4
        };
#endif
        img = QImage(width/2, height/2, QImage::Format_RGB32);

        for (int y=0; y<height; y+=2) {
            const uchar *yLine = data[0] + (y * stride[0]);
            const uchar *uLine = data[1] + (y * stride[1] / 2);
            const uchar *vLine = data[2] + (y * stride[2] / 2);

            for (int x=0; x<width; x+=2) {
                const qreal Y = 1.164*(yLine[x]-16);
                const int U = uLine[x/2]-128;
                const int V = vLine[x/2]-128;

                int b = qBound(0, int(Y + 2.018*U), 255);
                int g = qBound(0, int(Y - 0.813*V - 0.391*U), 255);
                int r = qBound(0, int(Y + 1.596*V), 255);

                img.setPixel(x/2,y/2,qRgb(r,g,b));
            }
        }
#if GST_CHECK_VERSION(1,0,0)
    } else for (int i = 0; i < lengthOf(qt_colorLookup); ++i) {
        if (qt_colorLookup[i].gstFormat != videoInfo.finfo->format)
            continue;

        const QImage image(
                    static_cast<const uchar *>(frame.data[0]),
                    videoInfo.width,
                    videoInfo.height,
                    frame.info.stride[0],
                    qt_colorLookup[i].imageFormat);
        img = image;
        img.detach();

        break;
    }

    gst_video_frame_unmap(&frame);
#else
    } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
        QImage::Format format = QImage::Format_Invalid;
        int bpp = 0;
        gst_structure_get_int(structure, "bpp", &bpp);

        if (bpp == 24)
            format = QImage::Format_RGB888;
        else if (bpp == 32)
            format = QImage::Format_RGB32;

        if (format != QImage::Format_Invalid) {
            img = QImage((const uchar *)buffer->data,
                         width,
                         height,
                         format);
            img.bits(); //detach
        }
    }
#endif
    return img;
}


namespace {

#if GST_CHECK_VERSION(1,0,0)

struct VideoFormat
{
    QVideoFrame::PixelFormat pixelFormat;
    GstVideoFormat gstFormat;
};

static const VideoFormat qt_videoFormatLookup[] =
{
    { QVideoFrame::Format_YUV420P, GST_VIDEO_FORMAT_I420 },
    { QVideoFrame::Format_YUV422P, GST_VIDEO_FORMAT_Y42B },
    { QVideoFrame::Format_YV12   , GST_VIDEO_FORMAT_YV12 },
    { QVideoFrame::Format_UYVY   , GST_VIDEO_FORMAT_UYVY },
    { QVideoFrame::Format_YUYV   , GST_VIDEO_FORMAT_YUY2 },
    { QVideoFrame::Format_NV12   , GST_VIDEO_FORMAT_NV12 },
    { QVideoFrame::Format_NV21   , GST_VIDEO_FORMAT_NV21 },
    { QVideoFrame::Format_AYUV444, GST_VIDEO_FORMAT_AYUV },
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
    { QVideoFrame::Format_RGB32 ,  GST_VIDEO_FORMAT_BGRx },
    { QVideoFrame::Format_BGR32 ,  GST_VIDEO_FORMAT_RGBx },
    { QVideoFrame::Format_ARGB32,  GST_VIDEO_FORMAT_BGRA },
    { QVideoFrame::Format_ABGR32,  GST_VIDEO_FORMAT_RGBA },
    { QVideoFrame::Format_BGRA32,  GST_VIDEO_FORMAT_ARGB },
#else
    { QVideoFrame::Format_RGB32 ,  GST_VIDEO_FORMAT_xRGB },
    { QVideoFrame::Format_BGR32 ,  GST_VIDEO_FORMAT_xBGR },
    { QVideoFrame::Format_ARGB32,  GST_VIDEO_FORMAT_ARGB },
    { QVideoFrame::Format_ABGR32,  GST_VIDEO_FORMAT_ABGR },
    { QVideoFrame::Format_BGRA32,  GST_VIDEO_FORMAT_BGRA },
#endif
    { QVideoFrame::Format_RGB24 ,  GST_VIDEO_FORMAT_RGB },
    { QVideoFrame::Format_BGR24 ,  GST_VIDEO_FORMAT_BGR },
    { QVideoFrame::Format_RGB565,  GST_VIDEO_FORMAT_RGB16 }
};

static int indexOfVideoFormat(QVideoFrame::PixelFormat format)
{
    for (int i = 0; i < lengthOf(qt_videoFormatLookup); ++i)
        if (qt_videoFormatLookup[i].pixelFormat == format)
            return i;

    return -1;
}

static int indexOfVideoFormat(GstVideoFormat format)
{
    for (int i = 0; i < lengthOf(qt_videoFormatLookup); ++i)
        if (qt_videoFormatLookup[i].gstFormat == format)
            return i;

    return -1;
}

#else

struct YuvFormat
{
    QVideoFrame::PixelFormat pixelFormat;
    guint32 fourcc;
    int bitsPerPixel;
};

static const YuvFormat qt_yuvColorLookup[] =
{
    { QVideoFrame::Format_YUV420P, GST_MAKE_FOURCC('I','4','2','0'), 8 },
    { QVideoFrame::Format_YUV422P, GST_MAKE_FOURCC('Y','4','2','B'), 8 },
    { QVideoFrame::Format_YV12,    GST_MAKE_FOURCC('Y','V','1','2'), 8 },
    { QVideoFrame::Format_UYVY,    GST_MAKE_FOURCC('U','Y','V','Y'), 16 },
    { QVideoFrame::Format_YUYV,    GST_MAKE_FOURCC('Y','U','Y','2'), 16 },
    { QVideoFrame::Format_NV12,    GST_MAKE_FOURCC('N','V','1','2'), 8 },
    { QVideoFrame::Format_NV21,    GST_MAKE_FOURCC('N','V','2','1'), 8 },
    { QVideoFrame::Format_AYUV444, GST_MAKE_FOURCC('A','Y','U','V'), 32 }
};

static int indexOfYuvColor(QVideoFrame::PixelFormat format)
{
    const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);

    for (int i = 0; i < count; ++i)
        if (qt_yuvColorLookup[i].pixelFormat == format)
            return i;

    return -1;
}

static int indexOfYuvColor(guint32 fourcc)
{
    const int count = sizeof(qt_yuvColorLookup) / sizeof(YuvFormat);

    for (int i = 0; i < count; ++i)
        if (qt_yuvColorLookup[i].fourcc == fourcc)
            return i;

    return -1;
}

struct RgbFormat
{
    QVideoFrame::PixelFormat pixelFormat;
    int bitsPerPixel;
    int depth;
    int endianness;
    int red;
    int green;
    int blue;
    int alpha;
};

static const RgbFormat qt_rgbColorLookup[] =
{
    { QVideoFrame::Format_RGB32 , 32, 24, 4321, 0x0000FF00, 0x00FF0000, int(0xFF000000), 0x00000000 },
    { QVideoFrame::Format_RGB32 , 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
    { QVideoFrame::Format_BGR32 , 32, 24, 4321, int(0xFF000000), 0x00FF0000, 0x0000FF00, 0x00000000 },
    { QVideoFrame::Format_BGR32 , 32, 24, 1234, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
    { QVideoFrame::Format_ARGB32, 32, 24, 4321, 0x0000FF00, 0x00FF0000, int(0xFF000000), 0x000000FF },
    { QVideoFrame::Format_ARGB32, 32, 24, 1234, 0x00FF0000, 0x0000FF00, 0x000000FF, int(0xFF000000) },
    { QVideoFrame::Format_RGB24 , 24, 24, 4321, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 },
    { QVideoFrame::Format_BGR24 , 24, 24, 4321, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 },
    { QVideoFrame::Format_RGB565, 16, 16, 1234, 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }
};

static int indexOfRgbColor(
        int bits, int depth, int endianness, int red, int green, int blue, int alpha)
{
    const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat);

    for (int i = 0; i < count; ++i) {
        if (qt_rgbColorLookup[i].bitsPerPixel == bits
            && qt_rgbColorLookup[i].depth == depth
            && qt_rgbColorLookup[i].endianness == endianness
            && qt_rgbColorLookup[i].red == red
            && qt_rgbColorLookup[i].green == green
            && qt_rgbColorLookup[i].blue == blue
            && qt_rgbColorLookup[i].alpha == alpha) {
            return i;
        }
    }
    return -1;
}
#endif

}

#if GST_CHECK_VERSION(1,0,0)

QVideoSurfaceFormat QGstUtils::formatForCaps(
        GstCaps *caps, GstVideoInfo *info, QAbstractVideoBuffer::HandleType handleType)
{
    GstVideoInfo vidInfo;
    GstVideoInfo *infoPtr = info ? info : &vidInfo;

    if (gst_video_info_from_caps(infoPtr, caps)) {
        int index = indexOfVideoFormat(infoPtr->finfo->format);

        if (index != -1) {
            QVideoSurfaceFormat format(
                        QSize(infoPtr->width, infoPtr->height),
                        qt_videoFormatLookup[index].pixelFormat,
                        handleType);

            if (infoPtr->fps_d > 0)
                format.setFrameRate(qreal(infoPtr->fps_n) / infoPtr->fps_d);

            if (infoPtr->par_d > 0)
                format.setPixelAspectRatio(infoPtr->par_n, infoPtr->par_d);

            return format;
        }
    }
    return QVideoSurfaceFormat();
}

#else

QVideoSurfaceFormat QGstUtils::formatForCaps(
        GstCaps *caps, int *bytesPerLine, QAbstractVideoBuffer::HandleType handleType)
{
    const GstStructure *structure = gst_caps_get_structure(caps, 0);

    int bitsPerPixel = 0;
    QSize size = structureResolution(structure);
    QVideoFrame::PixelFormat pixelFormat = structurePixelFormat(structure, &bitsPerPixel);

    if (pixelFormat != QVideoFrame::Format_Invalid) {
        QVideoSurfaceFormat format(size, pixelFormat, handleType);

        QPair<qreal, qreal> rate = structureFrameRateRange(structure);
        if (rate.second)
            format.setFrameRate(rate.second);

        format.setPixelAspectRatio(structurePixelAspectRatio(structure));

        if (bytesPerLine)
            *bytesPerLine = ((size.width() * bitsPerPixel / 8) + 3) & ~3;

        return format;
    }
    return QVideoSurfaceFormat();
}

#endif

GstCaps *QGstUtils::capsForFormats(const QList<QVideoFrame::PixelFormat> &formats)
{
    GstCaps *caps = gst_caps_new_empty();

#if GST_CHECK_VERSION(1,0,0)
    for (QVideoFrame::PixelFormat format : formats) {
        int index = indexOfVideoFormat(format);

        if (index != -1) {
            gst_caps_append_structure(caps, gst_structure_new(
                    "video/x-raw",
                    "format"   , G_TYPE_STRING, gst_video_format_to_string(qt_videoFormatLookup[index].gstFormat),
                    NULL));
        }
    }
#else
    for (QVideoFrame::PixelFormat format : formats) {
        int index = indexOfYuvColor(format);

        if (index != -1) {
            gst_caps_append_structure(caps, gst_structure_new(
                    "video/x-raw-yuv",
                    "format", GST_TYPE_FOURCC, qt_yuvColorLookup[index].fourcc,
                    NULL));
            continue;
        }

        const int count = sizeof(qt_rgbColorLookup) / sizeof(RgbFormat);

        for (int i = 0; i < count; ++i) {
            if (qt_rgbColorLookup[i].pixelFormat == format) {
                GstStructure *structure = gst_structure_new(
                        "video/x-raw-rgb",
                        "bpp"       , G_TYPE_INT, qt_rgbColorLookup[i].bitsPerPixel,
                        "depth"     , G_TYPE_INT, qt_rgbColorLookup[i].depth,
                        "endianness", G_TYPE_INT, qt_rgbColorLookup[i].endianness,
                        "red_mask"  , G_TYPE_INT, qt_rgbColorLookup[i].red,
                        "green_mask", G_TYPE_INT, qt_rgbColorLookup[i].green,
                        "blue_mask" , G_TYPE_INT, qt_rgbColorLookup[i].blue,
                        NULL);

                if (qt_rgbColorLookup[i].alpha != 0) {
                    gst_structure_set(
                            structure, "alpha_mask", G_TYPE_INT, qt_rgbColorLookup[i].alpha, NULL);
                }
                gst_caps_append_structure(caps, structure);
            }
        }
    }
#endif

    gst_caps_set_simple(
                caps,
                "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
                "width"    , GST_TYPE_INT_RANGE, 1, INT_MAX,
                "height"   , GST_TYPE_INT_RANGE, 1, INT_MAX,
                NULL);

    return caps;
}

void QGstUtils::setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer)
{
    // GStreamer uses nanoseconds, Qt uses microseconds
    qint64 startTime = GST_BUFFER_TIMESTAMP(buffer);
    if (startTime >= 0) {
        frame->setStartTime(startTime/G_GINT64_CONSTANT (1000));

        qint64 duration = GST_BUFFER_DURATION(buffer);
        if (duration >= 0)
            frame->setEndTime((startTime + duration)/G_GINT64_CONSTANT (1000));
    }
}

void QGstUtils::setMetaData(GstElement *element, const QMap<QByteArray, QVariant> &data)
{
    if (!GST_IS_TAG_SETTER(element))
        return;

    gst_tag_setter_reset_tags(GST_TAG_SETTER(element));

    for (auto it = data.cbegin(), end = data.cend(); it != end; ++it) {
        const QString tagName = QString::fromLatin1(it.key());
        const QVariant &tagValue = it.value();

        switch (tagValue.type()) {
            case QVariant::String:
                gst_tag_setter_add_tags(GST_TAG_SETTER(element),
                    GST_TAG_MERGE_REPLACE,
                    tagName.toUtf8().constData(),
                    tagValue.toString().toUtf8().constData(),
                    NULL);
                break;
            case QVariant::Int:
            case QVariant::LongLong:
                gst_tag_setter_add_tags(GST_TAG_SETTER(element),
                    GST_TAG_MERGE_REPLACE,
                    tagName.toUtf8().constData(),
                    tagValue.toInt(),
                    NULL);
                break;
            case QVariant::Double:
                gst_tag_setter_add_tags(GST_TAG_SETTER(element),
                    GST_TAG_MERGE_REPLACE,
                    tagName.toUtf8().constData(),
                    tagValue.toDouble(),
                    NULL);
                break;
#if GST_CHECK_VERSION(0, 10, 31)
            case QVariant::DateTime: {
                QDateTime date = tagValue.toDateTime().toLocalTime();
                gst_tag_setter_add_tags(GST_TAG_SETTER(element),
                    GST_TAG_MERGE_REPLACE,
                    tagName.toUtf8().constData(),
                    gst_date_time_new_local_time(
                                date.date().year(), date.date().month(), date.date().day(),
                                date.time().hour(), date.time().minute(), date.time().second()),
                    NULL);
                break;
            }
#endif
            default:
                break;
        }
    }
}

void QGstUtils::setMetaData(GstBin *bin, const QMap<QByteArray, QVariant> &data)
{
    GstIterator *elements = gst_bin_iterate_all_by_interface(bin, GST_TYPE_TAG_SETTER);
#if GST_CHECK_VERSION(1,0,0)
    GValue item = G_VALUE_INIT;
    while (gst_iterator_next(elements, &item) == GST_ITERATOR_OK) {
        GstElement * const element = GST_ELEMENT(g_value_get_object(&item));
#else
    GstElement *element = 0;
    while (gst_iterator_next(elements, (void**)&element) == GST_ITERATOR_OK) {
#endif
        setMetaData(element, data);
    }
    gst_iterator_free(elements);
}


GstCaps *QGstUtils::videoFilterCaps()
{
    const char *caps =
#if GST_CHECK_VERSION(1,2,0)
        "video/x-raw(ANY);"
#elif GST_CHECK_VERSION(1,0,0)
        "video/x-raw;"
#else
        "video/x-raw-yuv;"
        "video/x-raw-rgb;"
        "video/x-raw-data;"
        "video/x-android-buffer;"
#endif
        "image/jpeg;"
        "video/x-h264";
    static GstStaticCaps staticCaps = GST_STATIC_CAPS(caps);

    return gst_caps_make_writable(gst_static_caps_get(&staticCaps));
}

QSize QGstUtils::structureResolution(const GstStructure *s)
{
    QSize size;

    int w, h;
    if (s && gst_structure_get_int(s, "width", &w) && gst_structure_get_int(s, "height", &h)) {
        size.rwidth() = w;
        size.rheight() = h;
    }

    return size;
}

QVideoFrame::PixelFormat QGstUtils::structurePixelFormat(const GstStructure *structure, int *bpp)
{
    QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_Invalid;

    if (!structure)
        return pixelFormat;

#if GST_CHECK_VERSION(1,0,0)
    Q_UNUSED(bpp);

    if (gst_structure_has_name(structure, "video/x-raw")) {
        const gchar *s = gst_structure_get_string(structure, "format");
        if (s) {
            GstVideoFormat format = gst_video_format_from_string(s);
            int index = indexOfVideoFormat(format);

            if (index != -1)
                pixelFormat = qt_videoFormatLookup[index].pixelFormat;
        }
    }
#else
    if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-yuv") == 0) {
        guint32 fourcc = 0;
        gst_structure_get_fourcc(structure, "format", &fourcc);

        int index = indexOfYuvColor(fourcc);
        if (index != -1) {
            pixelFormat = qt_yuvColorLookup[index].pixelFormat;
            if (bpp)
                *bpp = qt_yuvColorLookup[index].bitsPerPixel;
        }
    } else if (qstrcmp(gst_structure_get_name(structure), "video/x-raw-rgb") == 0) {
        int bitsPerPixel = 0;
        int depth = 0;
        int endianness = 0;
        int red = 0;
        int green = 0;
        int blue = 0;
        int alpha = 0;

        gst_structure_get_int(structure, "bpp", &bitsPerPixel);
        gst_structure_get_int(structure, "depth", &depth);
        gst_structure_get_int(structure, "endianness", &endianness);
        gst_structure_get_int(structure, "red_mask", &red);
        gst_structure_get_int(structure, "green_mask", &green);
        gst_structure_get_int(structure, "blue_mask", &blue);
        gst_structure_get_int(structure, "alpha_mask", &alpha);

        int index = indexOfRgbColor(bitsPerPixel, depth, endianness, red, green, blue, alpha);

        if (index != -1) {
            pixelFormat = qt_rgbColorLookup[index].pixelFormat;
            if (bpp)
                *bpp = qt_rgbColorLookup[index].bitsPerPixel;
        }
    }
#endif

    return pixelFormat;
}

QSize QGstUtils::structurePixelAspectRatio(const GstStructure *s)
{
    QSize ratio(1, 1);

    gint aspectNum = 0;
    gint aspectDenum = 0;
    if (s && gst_structure_get_fraction(s, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) {
        if (aspectDenum > 0) {
            ratio.rwidth() = aspectNum;
            ratio.rheight() = aspectDenum;
        }
    }

    return ratio;
}

QPair<qreal, qreal> QGstUtils::structureFrameRateRange(const GstStructure *s)
{
    QPair<qreal, qreal> rate;

    if (!s)
        return rate;

    int n, d;
    if (gst_structure_get_fraction(s, "framerate", &n, &d)) {
        rate.second = qreal(n) / d;
        rate.first = rate.second;
    } else if (gst_structure_get_fraction(s, "max-framerate", &n, &d)) {
        rate.second = qreal(n) / d;
        if (gst_structure_get_fraction(s, "min-framerate", &n, &d))
            rate.first = qreal(n) / d;
        else
            rate.first = qreal(1);
    }

    return rate;
}

typedef QMap<QString, QString> FileExtensionMap;
Q_GLOBAL_STATIC(FileExtensionMap, fileExtensionMap)

QString QGstUtils::fileExtensionForMimeType(const QString &mimeType)
{
    if (fileExtensionMap->isEmpty()) {
        //extension for containers hard to guess from mimetype
        fileExtensionMap->insert(QStringLiteral("video/x-matroska"), QLatin1String("mkv"));
        fileExtensionMap->insert(QStringLiteral("video/quicktime"), QLatin1String("mov"));
        fileExtensionMap->insert(QStringLiteral("video/x-msvideo"), QLatin1String("avi"));
        fileExtensionMap->insert(QStringLiteral("video/msvideo"), QLatin1String("avi"));
        fileExtensionMap->insert(QStringLiteral("audio/mpeg"), QLatin1String("mp3"));
        fileExtensionMap->insert(QStringLiteral("application/x-shockwave-flash"), QLatin1String("swf"));
        fileExtensionMap->insert(QStringLiteral("application/x-pn-realmedia"), QLatin1String("rm"));
    }

    //for container names like avi instead of video/x-msvideo, use it as extension
    if (!mimeType.contains(QLatin1Char('/')))
        return mimeType;

    QString format = mimeType.left(mimeType.indexOf(QLatin1Char(',')));
    QString extension = fileExtensionMap->value(format);

    if (!extension.isEmpty() || format.isEmpty())
        return extension;

    QRegularExpression rx(QStringLiteral("[-/]([\\w]+)$"));
    QRegularExpressionMatch match = rx.match(format);

    if (match.hasMatch())
        extension = match.captured(1);

    return extension;
}

#if GST_CHECK_VERSION(0,10,30)
QVariant QGstUtils::fromGStreamerOrientation(const QVariant &value)
{
    // Note gstreamer tokens either describe the counter clockwise rotation of the
    // image or the clockwise transform to apply to correct the image.  The orientation
    // value returned is the clockwise rotation of the image.
    const QString token = value.toString();
    if (token == QStringLiteral("rotate-90"))
        return 270;
    if (token == QStringLiteral("rotate-180"))
        return 180;
    if (token == QStringLiteral("rotate-270"))
        return 90;
    return 0;
}

QVariant QGstUtils::toGStreamerOrientation(const QVariant &value)
{
    switch (value.toInt()) {
    case 90:
        return QStringLiteral("rotate-270");
    case 180:
        return QStringLiteral("rotate-180");
    case 270:
        return QStringLiteral("rotate-90");
    default:
        return QStringLiteral("rotate-0");
    }
}
#endif

bool QGstUtils::useOpenGL()
{
    static bool result = qEnvironmentVariableIntValue("QT_GSTREAMER_USE_OPENGL_PLUGIN");
    return result;
}

void qt_gst_object_ref_sink(gpointer object)
{
#if GST_CHECK_VERSION(0,10,24)
    gst_object_ref_sink(object);
#else
    g_return_if_fail (GST_IS_OBJECT(object));

    GST_OBJECT_LOCK(object);
    if (G_LIKELY(GST_OBJECT_IS_FLOATING(object))) {
        GST_OBJECT_FLAG_UNSET(object, GST_OBJECT_FLOATING);
        GST_OBJECT_UNLOCK(object);
    } else {
        GST_OBJECT_UNLOCK(object);
        gst_object_ref(object);
    }
#endif
}

GstCaps *qt_gst_pad_get_current_caps(GstPad *pad)
{
#if GST_CHECK_VERSION(1,0,0)
    return gst_pad_get_current_caps(pad);
#else
    return gst_pad_get_negotiated_caps(pad);
#endif
}

GstCaps *qt_gst_pad_get_caps(GstPad *pad)
{
#if GST_CHECK_VERSION(1,0,0)
    return gst_pad_query_caps(pad, NULL);
#elif GST_CHECK_VERSION(0, 10, 26)
    return gst_pad_get_caps_reffed(pad);
#else
    return gst_pad_get_caps(pad);
#endif
}

GstStructure *qt_gst_structure_new_empty(const char *name)
{
#if GST_CHECK_VERSION(1,0,0)
    return gst_structure_new_empty(name);
#else
    return gst_structure_new(name, NULL);
#endif
}

gboolean qt_gst_element_query_position(GstElement *element, GstFormat format, gint64 *cur)
{
#if GST_CHECK_VERSION(1,0,0)
    return gst_element_query_position(element, format, cur);
#else
    return gst_element_query_position(element, &format, cur);
#endif
}

gboolean qt_gst_element_query_duration(GstElement *element, GstFormat format, gint64 *cur)
{
#if GST_CHECK_VERSION(1,0,0)
    return gst_element_query_duration(element, format, cur);
#else
    return gst_element_query_duration(element, &format, cur);
#endif
}

GstCaps *qt_gst_caps_normalize(GstCaps *caps)
{
#if GST_CHECK_VERSION(1,0,0)
    // gst_caps_normalize() takes ownership of the argument in 1.0
    return gst_caps_normalize(caps);
#else
    // in 0.10, it doesn't. Unref the argument to mimic the 1.0 behavior
    GstCaps *res = gst_caps_normalize(caps);
    gst_caps_unref(caps);
    return res;
#endif
}

const gchar *qt_gst_element_get_factory_name(GstElement *element)
{
    const gchar *name = 0;
    const GstElementFactory *factory = 0;

    if (element && (factory = gst_element_get_factory(element)))
        name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));

    return name;
}

gboolean qt_gst_caps_can_intersect(const GstCaps * caps1, const GstCaps * caps2)
{
#if GST_CHECK_VERSION(0, 10, 25)
    return gst_caps_can_intersect(caps1, caps2);
#else
    GstCaps *intersection = gst_caps_intersect(caps1, caps2);
    gboolean res = !gst_caps_is_empty(intersection);
    gst_caps_unref(intersection);
    return res;
#endif
}

#if !GST_CHECK_VERSION(0, 10, 31)
static gboolean qt_gst_videosink_factory_filter(GstPluginFeature *feature, gpointer)
{
  guint rank;
  const gchar *klass;

  if (!GST_IS_ELEMENT_FACTORY(feature))
    return FALSE;

  klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(feature));
  if (!(strstr(klass, "Sink") && strstr(klass, "Video")))
    return FALSE;

  rank = gst_plugin_feature_get_rank(feature);
  if (rank < GST_RANK_MARGINAL)
    return FALSE;

  return TRUE;
}

static gint qt_gst_compare_ranks(GstPluginFeature *f1, GstPluginFeature *f2)
{
  gint diff;

  diff = gst_plugin_feature_get_rank(f2) - gst_plugin_feature_get_rank(f1);
  if (diff != 0)
    return diff;

  return strcmp(gst_plugin_feature_get_name(f2), gst_plugin_feature_get_name (f1));
}
#endif

GList *qt_gst_video_sinks()
{
    GList *list = NULL;

#if GST_CHECK_VERSION(0, 10, 31)
    list = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_SINK | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO,
                                                 GST_RANK_MARGINAL);
#else
    list = gst_registry_feature_filter(gst_registry_get_default(),
                                       (GstPluginFeatureFilter)qt_gst_videosink_factory_filter,
                                       FALSE, NULL);
    list = g_list_sort(list, (GCompareFunc)qt_gst_compare_ranks);
#endif

    return list;
}

void qt_gst_util_double_to_fraction(gdouble src, gint *dest_n, gint *dest_d)
{
#if GST_CHECK_VERSION(0, 10, 26)
    gst_util_double_to_fraction(src, dest_n, dest_d);
#else
    qt_real_to_fraction(src, dest_n, dest_d);
#endif
}

QDebug operator <<(QDebug debug, GstCaps *caps)
{
    if (caps) {
        gchar *string = gst_caps_to_string(caps);
        debug = debug << string;
        g_free(string);
    }
    return debug;
}

QT_END_NAMESPACE
