/****************************************************************************
**
** 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 "camerabinsession.h"
#include "camerabincontrol.h"
#include "camerabinrecorder.h"
#include "camerabincontainer.h"
#include "camerabinaudioencoder.h"
#include "camerabinvideoencoder.h"
#include "camerabinimageencoder.h"

#if QT_CONFIG(gstreamer_photography)
#include "camerabinexposure.h"
#include "camerabinflash.h"
#include "camerabinfocus.h"
#include "camerabinlocks.h"
#endif

#include "camerabinzoom.h"
#include "camerabinimageprocessing.h"
#include "camerabinviewfindersettings.h"

#include "camerabincapturedestination.h"
#include "camerabincapturebufferformat.h"
#include <private/qgstreamerbushelper_p.h>
#include <private/qgstreamervideorendererinterface_p.h>
#include <private/qgstutils_p.h>
#include <qmediarecorder.h>
#include <qvideosurfaceformat.h>

#if QT_CONFIG(gstreamer_photography)
#include <gst/interfaces/photography.h>
#endif

#include <gst/gsttagsetter.h>
#include <gst/gstversion.h>

#include <QtCore/qdebug.h>
#include <QCoreApplication>
#include <QtCore/qmetaobject.h>
#include <QtGui/qdesktopservices.h>

#include <QtGui/qimage.h>
#include <QtCore/qdatetime.h>

#include <algorithm>

//#define CAMERABIN_DEBUG 1
//#define CAMERABIN_DEBUG_DUMP_BIN 1
#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))

#define FILENAME_PROPERTY "location"
#define MODE_PROPERTY "mode"
#define MUTE_PROPERTY "mute"
#define IMAGE_PP_PROPERTY "image-post-processing"
#define IMAGE_ENCODER_PROPERTY "image-encoder"
#define VIDEO_PP_PROPERTY "video-post-processing"
#define VIEWFINDER_SINK_PROPERTY "viewfinder-sink"
#define CAMERA_SOURCE_PROPERTY "camera-source"
#define AUDIO_SOURCE_PROPERTY "audio-source"
#define SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-supported-caps"
#define SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY "video-capture-supported-caps"
#define SUPPORTED_VIEWFINDER_CAPS_PROPERTY "viewfinder-supported-caps"
#define AUDIO_CAPTURE_CAPS_PROPERTY "audio-capture-caps"
#define IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-caps"
#define VIDEO_CAPTURE_CAPS_PROPERTY "video-capture-caps"
#define VIEWFINDER_CAPS_PROPERTY "viewfinder-caps"
#define PREVIEW_CAPS_PROPERTY "preview-caps"
#define POST_PREVIEWS_PROPERTY "post-previews"


#define CAPTURE_START "start-capture"
#define CAPTURE_STOP "stop-capture"

#define FILESINK_BIN_NAME "videobin-filesink"

#define CAMERABIN_IMAGE_MODE 1
#define CAMERABIN_VIDEO_MODE 2

#define PREVIEW_CAPS_4_3 \
    "video/x-raw-rgb, width = (int) 640, height = (int) 480"

QT_BEGIN_NAMESPACE

CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *parent)
    :QObject(parent),
     m_recordingActive(false),
     m_status(QCamera::UnloadedStatus),
     m_pendingState(QCamera::UnloadedState),
     m_muted(false),
     m_busy(false),
     m_captureMode(QCamera::CaptureStillImage),
     m_audioInputFactory(0),
     m_videoInputFactory(0),
     m_viewfinder(0),
     m_viewfinderInterface(0),
#if QT_CONFIG(gstreamer_photography)
     m_cameraExposureControl(0),
     m_cameraFlashControl(0),
     m_cameraFocusControl(0),
     m_cameraLocksControl(0),
#endif
     m_cameraSrc(0),
     m_videoSrc(0),
     m_viewfinderElement(0),
     m_sourceFactory(sourceFactory),
     m_viewfinderHasChanged(true),
     m_inputDeviceHasChanged(true),
     m_usingWrapperCameraBinSrc(false),
     m_viewfinderProbe(this),
     m_audioSrc(0),
     m_audioConvert(0),
     m_capsFilter(0),
     m_fileSink(0),
     m_audioEncoder(0),
     m_videoEncoder(0),
     m_muxer(0)
{
    if (m_sourceFactory)
        gst_object_ref(GST_OBJECT(m_sourceFactory));
    m_camerabin = gst_element_factory_make(QT_GSTREAMER_CAMERABIN_ELEMENT_NAME, "camerabin");

    g_signal_connect(G_OBJECT(m_camerabin), "notify::idle", G_CALLBACK(updateBusyStatus), this);
    g_signal_connect(G_OBJECT(m_camerabin), "element-added",  G_CALLBACK(elementAdded), this);
    g_signal_connect(G_OBJECT(m_camerabin), "element-removed",  G_CALLBACK(elementRemoved), this);
    qt_gst_object_ref_sink(m_camerabin);

    m_bus = gst_element_get_bus(m_camerabin);

    m_busHelper = new QGstreamerBusHelper(m_bus, this);
    m_busHelper->installMessageFilter(this);

    m_cameraControl = new CameraBinControl(this);
    m_audioEncodeControl = new CameraBinAudioEncoder(this);
    m_videoEncodeControl = new CameraBinVideoEncoder(this);
    m_imageEncodeControl = new CameraBinImageEncoder(this);
    m_recorderControl = new CameraBinRecorder(this);
    m_mediaContainerControl = new CameraBinContainer(this);
    m_cameraZoomControl = new CameraBinZoom(this);
    m_imageProcessingControl = new CameraBinImageProcessing(this);
    m_captureDestinationControl = new CameraBinCaptureDestination(this);
    m_captureBufferFormatControl = new CameraBinCaptureBufferFormat(this);

    QByteArray envFlags = qgetenv("QT_GSTREAMER_CAMERABIN_FLAGS");
    if (!envFlags.isEmpty())
        g_object_set(G_OBJECT(m_camerabin), "flags", envFlags.toInt(), NULL);

    //post image preview in RGB format
    g_object_set(G_OBJECT(m_camerabin), POST_PREVIEWS_PROPERTY, TRUE, NULL);

#if GST_CHECK_VERSION(1,0,0)
    GstCaps *previewCaps = gst_caps_new_simple(
                "video/x-raw",
                "format", G_TYPE_STRING, "RGBx",
                NULL);
#else
    GstCaps *previewCaps = gst_caps_from_string("video/x-raw-rgb");
#endif

    g_object_set(G_OBJECT(m_camerabin), PREVIEW_CAPS_PROPERTY, previewCaps, NULL);
    gst_caps_unref(previewCaps);
}

CameraBinSession::~CameraBinSession()
{
    if (m_camerabin) {
        if (m_viewfinderInterface)
            m_viewfinderInterface->stopRenderer();

        gst_element_set_state(m_camerabin, GST_STATE_NULL);
        gst_element_get_state(m_camerabin, NULL, NULL, GST_CLOCK_TIME_NONE);
        gst_object_unref(GST_OBJECT(m_bus));
        gst_object_unref(GST_OBJECT(m_camerabin));
    }
    if (m_viewfinderElement)
        gst_object_unref(GST_OBJECT(m_viewfinderElement));

    if (m_sourceFactory)
        gst_object_unref(GST_OBJECT(m_sourceFactory));

    if (m_cameraSrc)
        gst_object_unref(GST_OBJECT(m_cameraSrc));

    if (m_videoSrc)
        gst_object_unref(GST_OBJECT(m_videoSrc));
}

#if QT_CONFIG(gstreamer_photography)
GstPhotography *CameraBinSession::photography()
{
    if (GST_IS_PHOTOGRAPHY(m_camerabin)) {
        return GST_PHOTOGRAPHY(m_camerabin);
    }

    GstElement * const source = buildCameraSource();

    if (source && GST_IS_PHOTOGRAPHY(source))
        return GST_PHOTOGRAPHY(source);

    return 0;
}

CameraBinExposure *CameraBinSession::cameraExposureControl()
{
    if (!m_cameraExposureControl && photography())
        m_cameraExposureControl = new CameraBinExposure(this);
    return m_cameraExposureControl;
}

CameraBinFlash *CameraBinSession::cameraFlashControl()
{
    if (!m_cameraFlashControl && photography())
        m_cameraFlashControl = new CameraBinFlash(this);
    return m_cameraFlashControl;
}

CameraBinFocus *CameraBinSession::cameraFocusControl()
{
    if (!m_cameraFocusControl && photography())
        m_cameraFocusControl = new CameraBinFocus(this);
    return m_cameraFocusControl;
}

CameraBinLocks *CameraBinSession::cameraLocksControl()
{
    if (!m_cameraLocksControl && photography())
        m_cameraLocksControl = new CameraBinLocks(this);
    return m_cameraLocksControl;
}
#endif

bool CameraBinSession::setupCameraBin()
{
    if (!buildCameraSource())
        return false;

    if (m_viewfinderHasChanged) {
        if (m_viewfinderElement) {
            GstPad *pad = gst_element_get_static_pad(m_viewfinderElement, "sink");
            m_viewfinderProbe.removeProbeFromPad(pad);
            gst_object_unref(GST_OBJECT(pad));
            gst_object_unref(GST_OBJECT(m_viewfinderElement));
        }

        m_viewfinderElement = m_viewfinderInterface ? m_viewfinderInterface->videoSink() : 0;
#if CAMERABIN_DEBUG
        qDebug() << Q_FUNC_INFO << "Viewfinder changed, reconfigure.";
#endif
        m_viewfinderHasChanged = false;
        if (!m_viewfinderElement) {
            if (m_pendingState == QCamera::ActiveState)
                qWarning() << "Starting camera without viewfinder available";
            m_viewfinderElement = gst_element_factory_make("fakesink", NULL);
        }

        GstPad *pad = gst_element_get_static_pad(m_viewfinderElement, "sink");
        m_viewfinderProbe.addProbeToPad(pad);
        gst_object_unref(GST_OBJECT(pad));

        g_object_set(G_OBJECT(m_viewfinderElement), "sync", FALSE, NULL);
        qt_gst_object_ref_sink(GST_OBJECT(m_viewfinderElement));
        gst_element_set_state(m_camerabin, GST_STATE_NULL);
        g_object_set(G_OBJECT(m_camerabin), VIEWFINDER_SINK_PROPERTY, m_viewfinderElement, NULL);
    }

    return true;
}

static GstCaps *resolutionToCaps(const QSize &resolution,
                                 qreal frameRate = 0.0,
                                 QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_Invalid)
{
    GstCaps *caps = 0;
    if (pixelFormat == QVideoFrame::Format_Invalid)
        caps = QGstUtils::videoFilterCaps();
    else
        caps = QGstUtils::capsForFormats(QList<QVideoFrame::PixelFormat>() << pixelFormat);

    if (!resolution.isEmpty()) {
        gst_caps_set_simple(
                    caps,
                    "width", G_TYPE_INT, resolution.width(),
                    "height", G_TYPE_INT, resolution.height(),
                     NULL);
    }

    if (frameRate > 0.0) {
        gint numerator;
        gint denominator;
        qt_gst_util_double_to_fraction(frameRate, &numerator, &denominator);

        gst_caps_set_simple(
                    caps,
                    "framerate", GST_TYPE_FRACTION, numerator, denominator,
                    NULL);
    }

    return caps;
}

void CameraBinSession::setupCaptureResolution()
{
    QSize viewfinderResolution = m_viewfinderSettings.resolution();
    qreal viewfinderFrameRate = m_viewfinderSettings.maximumFrameRate();
    QVideoFrame::PixelFormat viewfinderPixelFormat = m_viewfinderSettings.pixelFormat();
    const QSize imageResolution = m_imageEncodeControl->imageSettings().resolution();
    const QSize videoResolution = m_videoEncodeControl->actualVideoSettings().resolution();

    // WrapperCameraBinSrc cannot have different caps on its imgsrc, vidsrc and vfsrc pads.
    // If capture resolution is specified, use it also for the viewfinder to avoid caps negotiation
    // to fail.
    if (m_usingWrapperCameraBinSrc) {
        if (m_captureMode == QCamera::CaptureStillImage && !imageResolution.isEmpty())
            viewfinderResolution = imageResolution;
        else if (m_captureMode == QCamera::CaptureVideo && !videoResolution.isEmpty())
            viewfinderResolution = videoResolution;

        // Make sure we don't use incompatible frame rate and pixel format with the new resolution
        if (viewfinderResolution != m_viewfinderSettings.resolution() &&
                (!qFuzzyIsNull(viewfinderFrameRate) || viewfinderPixelFormat != QVideoFrame::Format_Invalid)) {

            enum {
                Nothing = 0x0,
                OnlyFrameRate = 0x1,
                OnlyPixelFormat = 0x2,
                Both = 0x4
            };
            quint8 found = Nothing;
            auto viewfinderSettings = supportedViewfinderSettings();
            for (int i = 0; i < viewfinderSettings.count() && !(found & Both); ++i) {
                const QCameraViewfinderSettings &s = viewfinderSettings.at(i);
                if (s.resolution() == viewfinderResolution) {
                    if ((qFuzzyIsNull(viewfinderFrameRate) || s.maximumFrameRate() == viewfinderFrameRate)
                            && (viewfinderPixelFormat == QVideoFrame::Format_Invalid || s.pixelFormat() == viewfinderPixelFormat))
                        found |= Both;
                    else if (s.maximumFrameRate() == viewfinderFrameRate)
                        found |= OnlyFrameRate;
                    else if (s.pixelFormat() == viewfinderPixelFormat)
                        found |= OnlyPixelFormat;
                }
            }

            if (found & Both) {
                // no-op
            } else if (found & OnlyPixelFormat) {
                viewfinderFrameRate = qreal(0);
            } else if (found & OnlyFrameRate) {
                viewfinderPixelFormat = QVideoFrame::Format_Invalid;
            } else {
                viewfinderPixelFormat = QVideoFrame::Format_Invalid;
                viewfinderFrameRate = qreal(0);
            }
        }
    }

    GstCaps *caps = resolutionToCaps(imageResolution);
    g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, caps, NULL);
    gst_caps_unref(caps);

    qreal framerate = m_videoEncodeControl->videoSettings().frameRate();
    caps = resolutionToCaps(videoResolution, framerate);
    g_object_set(m_camerabin, VIDEO_CAPTURE_CAPS_PROPERTY, caps, NULL);
    gst_caps_unref(caps);

    caps = resolutionToCaps(viewfinderResolution, viewfinderFrameRate, viewfinderPixelFormat);
    g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, caps, NULL);
    gst_caps_unref(caps);

    // Special case when using mfw_v4lsrc
    if (m_videoSrc && qstrcmp(qt_gst_element_get_factory_name(m_videoSrc), "mfw_v4lsrc") == 0) {
        int capMode = 0;
        if (viewfinderResolution == QSize(320, 240))
            capMode = 1;
        else if (viewfinderResolution == QSize(720, 480))
            capMode = 2;
        else if (viewfinderResolution == QSize(720, 576))
            capMode = 3;
        else if (viewfinderResolution == QSize(1280, 720))
            capMode = 4;
        else if (viewfinderResolution == QSize(1920, 1080))
            capMode = 5;
        g_object_set(G_OBJECT(m_videoSrc), "capture-mode", capMode, NULL);

        if (!qFuzzyIsNull(viewfinderFrameRate)) {
            int n, d;
            qt_gst_util_double_to_fraction(viewfinderFrameRate, &n, &d);
            g_object_set(G_OBJECT(m_videoSrc), "fps-n", n, NULL);
            g_object_set(G_OBJECT(m_videoSrc), "fps-d", d, NULL);
        }
    }

    if (m_videoEncoder)
        m_videoEncodeControl->applySettings(m_videoEncoder);
}

void CameraBinSession::setAudioCaptureCaps()
{
    QAudioEncoderSettings settings = m_audioEncodeControl->audioSettings();
    const int sampleRate = settings.sampleRate();
    const int channelCount = settings.channelCount();

    if (sampleRate <= 0 && channelCount <=0)
        return;

#if GST_CHECK_VERSION(1,0,0)
    GstStructure *structure = gst_structure_new_empty(QT_GSTREAMER_RAW_AUDIO_MIME);
#else
    GstStructure *structure = gst_structure_new(
                QT_GSTREAMER_RAW_AUDIO_MIME,
                "endianness", G_TYPE_INT, 1234,
                "signed", G_TYPE_BOOLEAN, TRUE,
                "width", G_TYPE_INT, 16,
                "depth", G_TYPE_INT, 16,
                NULL);
#endif
    if (sampleRate > 0)
        gst_structure_set(structure, "rate", G_TYPE_INT, sampleRate, NULL);
    if (channelCount > 0)
        gst_structure_set(structure, "channels", G_TYPE_INT, channelCount, NULL);

    GstCaps *caps = gst_caps_new_full(structure, NULL);
    g_object_set(G_OBJECT(m_camerabin), AUDIO_CAPTURE_CAPS_PROPERTY, caps, NULL);
    gst_caps_unref(caps);

    if (m_audioEncoder)
        m_audioEncodeControl->applySettings(m_audioEncoder);
}

GstElement *CameraBinSession::buildCameraSource()
{
#if CAMERABIN_DEBUG
    qDebug() << Q_FUNC_INFO;
#endif
    if (m_inputDevice.isEmpty())
        return nullptr;

    if (!m_inputDeviceHasChanged)
        return m_cameraSrc;

    m_inputDeviceHasChanged = false;
    m_usingWrapperCameraBinSrc = false;

    GstElement *camSrc = 0;
    g_object_get(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, &camSrc, NULL);

    if (!m_cameraSrc && m_sourceFactory)
        m_cameraSrc = gst_element_factory_create(m_sourceFactory, "camera_source");

    // If gstreamer has set a default source use it.
    if (!m_cameraSrc)
        m_cameraSrc = camSrc;

    if (m_cameraSrc) {
#if CAMERABIN_DEBUG
        qDebug() << "set camera device" << m_inputDevice;
#endif
        m_usingWrapperCameraBinSrc = qstrcmp(qt_gst_element_get_factory_name(m_cameraSrc), "wrappercamerabinsrc") == 0;

        if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_cameraSrc), "video-source")) {
            if (!m_videoSrc) {
                /* QT_GSTREAMER_CAMERABIN_VIDEOSRC can be used to set the video source element.

                   --- Usage

                     QT_GSTREAMER_CAMERABIN_VIDEOSRC=[drivername=elementname[,drivername2=elementname2 ...],][elementname]

                   --- Examples

                     Always use 'somevideosrc':
                     QT_GSTREAMER_CAMERABIN_VIDEOSRC="somevideosrc"

                     Use 'somevideosrc' when the device driver is 'somedriver', otherwise use default:
                     QT_GSTREAMER_CAMERABIN_VIDEOSRC="somedriver=somevideosrc"

                     Use 'somevideosrc' when the device driver is 'somedriver', otherwise use 'somevideosrc2'
                     QT_GSTREAMER_CAMERABIN_VIDEOSRC="somedriver=somevideosrc,somevideosrc2"
                */
                const QByteArray envVideoSource = qgetenv("QT_GSTREAMER_CAMERABIN_VIDEOSRC");

                if (!envVideoSource.isEmpty()) {
                    const QList<QByteArray> sources = envVideoSource.split(',');
                    for (const QByteArray &source : sources) {
                        QList<QByteArray> keyValue = source.split('=');
                        QByteArray name = keyValue.at(0);
                        if (keyValue.count() > 1 && keyValue.at(0) == QGstUtils::cameraDriver(m_inputDevice, m_sourceFactory))
                            name = keyValue.at(1);

                        GError *error = NULL;
                        GstElement *element = gst_parse_launch(name, &error);

                        if (error) {
                            g_printerr("ERROR: %s: %s\n", name.constData(), GST_STR_NULL(error->message));
                            g_clear_error(&error);
                        }
                        if (element) {
                            m_videoSrc = element;
                            break;
                        }
                    }
                } else if (m_videoInputFactory) {
                    m_videoSrc = m_videoInputFactory->buildElement();
                }

                if (!m_videoSrc)
                    m_videoSrc = gst_element_factory_make("v4l2src", "camera_source");

                if (!m_videoSrc)
                    m_videoSrc = gst_element_factory_make("ksvideosrc", "camera_source");

                if (!m_videoSrc)
                    m_videoSrc = gst_element_factory_make("avfvideosrc", "camera_source");

                if (m_videoSrc)
                    g_object_set(G_OBJECT(m_cameraSrc), "video-source", m_videoSrc, NULL);
            }

            if (m_videoSrc) {
                if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSrc), "device"))
                    g_object_set(G_OBJECT(m_videoSrc), "device", m_inputDevice.toUtf8().constData(), NULL);

                if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSrc), "device-path"))
                    g_object_set(G_OBJECT(m_videoSrc), "device-path", m_inputDevice.toUtf8().constData(), NULL);

                if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSrc), "device-index"))
                    g_object_set(G_OBJECT(m_videoSrc), "device-index", m_inputDevice.toInt(), NULL);
            }
        } else if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_cameraSrc), "camera-device")) {
            if (m_inputDevice == QLatin1String("secondary")) {
                g_object_set(G_OBJECT(m_cameraSrc), "camera-device", 1, NULL);
            } else {
                g_object_set(G_OBJECT(m_cameraSrc), "camera-device", 0, NULL);
            }
        }
    }

    if (m_cameraSrc != camSrc) {
        g_object_set(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, m_cameraSrc, NULL);
        // Unref only if camSrc is not m_cameraSrc to prevent double unrefing.
        if (camSrc)
            gst_object_unref(GST_OBJECT(camSrc));
    }

    return m_cameraSrc;
}

void CameraBinSession::captureImage(int requestId, const QString &fileName)
{
    const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName,
                                                                           QMediaStorageLocation::Pictures,
                                                                           QLatin1String("IMG_"),
                                                                           QLatin1String("jpg"));

    m_requestId = requestId;

#if CAMERABIN_DEBUG
    qDebug() << Q_FUNC_INFO << m_requestId << fileName << "actual file name:" << actualFileName;
#endif

    g_object_set(G_OBJECT(m_camerabin), FILENAME_PROPERTY, actualFileName.toLocal8Bit().constData(), NULL);

    g_signal_emit_by_name(G_OBJECT(m_camerabin), CAPTURE_START, NULL);

    m_imageFileName = actualFileName;
}

void CameraBinSession::setCaptureMode(QCamera::CaptureModes mode)
{
    m_captureMode = mode;

    switch (m_captureMode) {
    case QCamera::CaptureStillImage:
        g_object_set(m_camerabin, MODE_PROPERTY, CAMERABIN_IMAGE_MODE, NULL);
        break;
    case QCamera::CaptureVideo:
        g_object_set(m_camerabin, MODE_PROPERTY, CAMERABIN_VIDEO_MODE, NULL);
        break;
    }

    m_recorderControl->updateStatus();
}

QUrl CameraBinSession::outputLocation() const
{
    //return the location service wrote data to, not one set by user, it can be empty.
    return m_actualSink;
}

bool CameraBinSession::setOutputLocation(const QUrl& sink)
{
    if (!sink.isRelative() && !sink.isLocalFile()) {
        qWarning("Output location must be a local file");
        return false;
    }

    m_sink = m_actualSink = sink;
    return true;
}

void CameraBinSession::setDevice(const QString &device)
{
    if (m_inputDevice != device) {
        m_inputDevice = device;
        m_inputDeviceHasChanged = true;
    }
}

void CameraBinSession::setAudioInput(QGstreamerElementFactory *audioInput)
{
    m_audioInputFactory = audioInput;
}

void CameraBinSession::setVideoInput(QGstreamerElementFactory *videoInput)
{
    m_videoInputFactory = videoInput;
    m_inputDeviceHasChanged = true;
}

bool CameraBinSession::isReady() const
{
    //it's possible to use QCamera without any viewfinder attached
    return !m_viewfinderInterface || m_viewfinderInterface->isReady();
}

void CameraBinSession::setViewfinder(QObject *viewfinder)
{
    if (m_viewfinderInterface)
        m_viewfinderInterface->stopRenderer();

    m_viewfinderInterface = qobject_cast<QGstreamerVideoRendererInterface*>(viewfinder);
    if (!m_viewfinderInterface)
        viewfinder = 0;

    if (m_viewfinder != viewfinder) {
        bool oldReady = isReady();

        if (m_viewfinder) {
            disconnect(m_viewfinder, SIGNAL(sinkChanged()),
                       this, SLOT(handleViewfinderChange()));
            disconnect(m_viewfinder, SIGNAL(readyChanged(bool)),
                       this, SIGNAL(readyChanged(bool)));

            m_busHelper->removeMessageFilter(m_viewfinder);
        }

        m_viewfinder = viewfinder;
        m_viewfinderHasChanged = true;

        if (m_viewfinder) {
            connect(m_viewfinder, SIGNAL(sinkChanged()),
                       this, SLOT(handleViewfinderChange()));
            connect(m_viewfinder, SIGNAL(readyChanged(bool)),
                    this, SIGNAL(readyChanged(bool)));

            m_busHelper->installMessageFilter(m_viewfinder);
        }

        emit viewfinderChanged();
        if (oldReady != isReady())
            emit readyChanged(isReady());
    }
}

static QList<QCameraViewfinderSettings> capsToViewfinderSettings(GstCaps *supportedCaps)
{
    QList<QCameraViewfinderSettings> settings;

    if (!supportedCaps)
        return settings;

    supportedCaps = qt_gst_caps_normalize(supportedCaps);

    // Convert caps to QCameraViewfinderSettings
    for (uint i = 0; i < gst_caps_get_size(supportedCaps); ++i) {
        const GstStructure *structure = gst_caps_get_structure(supportedCaps, i);

        QCameraViewfinderSettings s;
        s.setResolution(QGstUtils::structureResolution(structure));
        s.setPixelFormat(QGstUtils::structurePixelFormat(structure));
        s.setPixelAspectRatio(QGstUtils::structurePixelAspectRatio(structure));

        QPair<qreal, qreal> frameRateRange = QGstUtils::structureFrameRateRange(structure);
        s.setMinimumFrameRate(frameRateRange.first);
        s.setMaximumFrameRate(frameRateRange.second);

        if (!s.resolution().isEmpty()
            && s.pixelFormat() != QVideoFrame::Format_Invalid
            && !settings.contains(s)) {
            settings.append(s);
        }
    }

    gst_caps_unref(supportedCaps);
    return settings;
}

QList<QCameraViewfinderSettings> CameraBinSession::supportedViewfinderSettings() const
{
    if (m_status >= QCamera::LoadedStatus && m_supportedViewfinderSettings.isEmpty()) {
        m_supportedViewfinderSettings =
            capsToViewfinderSettings(supportedCaps(QCamera::CaptureViewfinder));
    }

    return m_supportedViewfinderSettings;
}

QCameraViewfinderSettings CameraBinSession::viewfinderSettings() const
{
    return m_status == QCamera::ActiveStatus ? m_actualViewfinderSettings : m_viewfinderSettings;
}

void CameraBinSession::ViewfinderProbe::probeCaps(GstCaps *caps)
{
    QGstreamerVideoProbeControl::probeCaps(caps);

    // Update actual viewfinder settings on viewfinder caps change
    const GstStructure *s = gst_caps_get_structure(caps, 0);
    const QPair<qreal, qreal> frameRate = QGstUtils::structureFrameRateRange(s);
    session->m_actualViewfinderSettings.setResolution(QGstUtils::structureResolution(s));
    session->m_actualViewfinderSettings.setMinimumFrameRate(frameRate.first);
    session->m_actualViewfinderSettings.setMaximumFrameRate(frameRate.second);
    session->m_actualViewfinderSettings.setPixelFormat(QGstUtils::structurePixelFormat(s));
    session->m_actualViewfinderSettings.setPixelAspectRatio(QGstUtils::structurePixelAspectRatio(s));
}

void CameraBinSession::handleViewfinderChange()
{
    //the viewfinder will be reloaded
    //shortly when the pipeline is started
    m_viewfinderHasChanged = true;
    emit viewfinderChanged();
}

void CameraBinSession::setStatus(QCamera::Status status)
{
    if (m_status == status)
        return;

    m_status = status;
    emit statusChanged(m_status);

    setStateHelper(m_pendingState);
}

QCamera::Status CameraBinSession::status() const
{
    return m_status;
}

QCamera::State CameraBinSession::pendingState() const
{
    return m_pendingState;
}

void CameraBinSession::setState(QCamera::State newState)
{
    if (newState == m_pendingState)
        return;

    m_pendingState = newState;
    emit pendingStateChanged(m_pendingState);

#if CAMERABIN_DEBUG
    qDebug() << Q_FUNC_INFO << newState;
#endif

    setStateHelper(newState);
}

void CameraBinSession::setStateHelper(QCamera::State state)
{
    switch (state) {
    case QCamera::UnloadedState:
        unload();
        break;
    case QCamera::LoadedState:
        if (m_status == QCamera::ActiveStatus)
            stop();
        else if (m_status == QCamera::UnloadedStatus)
            load();
        break;
    case QCamera::ActiveState:
        // If the viewfinder changed while in the loaded state, we need to reload the pipeline
        if (m_status == QCamera::LoadedStatus && !m_viewfinderHasChanged)
            start();
        else if (m_status == QCamera::UnloadedStatus || m_viewfinderHasChanged)
            load();
    }
}

void CameraBinSession::setError(int err, const QString &errorString)
{
    // Emit only first error
    if (m_pendingState == QCamera::UnloadedState)
        return;

    setState(QCamera::UnloadedState);
    emit error(err, errorString);
    setStatus(QCamera::UnloadedStatus);
}

void CameraBinSession::load()
{
    if (m_status != QCamera::UnloadedStatus && !m_viewfinderHasChanged)
        return;

    setStatus(QCamera::LoadingStatus);

    gst_element_set_state(m_camerabin, GST_STATE_NULL);

    if (!setupCameraBin()) {
        setError(QCamera::CameraError, QStringLiteral("No camera source available"));
        return;
    }

    m_recorderControl->applySettings();

#if QT_CONFIG(gstreamer_encodingprofiles)
    GstEncodingContainerProfile *profile = m_recorderControl->videoProfile();
    if (profile) {
        g_object_set (G_OBJECT(m_camerabin),
                      "video-profile",
                      profile,
                      NULL);
        gst_encoding_profile_unref(profile);
    }
#endif

    gst_element_set_state(m_camerabin, GST_STATE_READY);
}

void CameraBinSession::unload()
{
    if (m_status == QCamera::UnloadedStatus || m_status == QCamera::UnloadingStatus)
        return;

    setStatus(QCamera::UnloadingStatus);

    if (m_recordingActive)
        stopVideoRecording();

    if (m_viewfinderInterface)
        m_viewfinderInterface->stopRenderer();

    gst_element_set_state(m_camerabin, GST_STATE_NULL);

    if (m_busy)
        emit busyChanged(m_busy = false);

    m_supportedViewfinderSettings.clear();

    setStatus(QCamera::UnloadedStatus);
}

void CameraBinSession::start()
{
    if (m_status != QCamera::LoadedStatus)
        return;

    setStatus(QCamera::StartingStatus);

    setAudioCaptureCaps();

    setupCaptureResolution();

    gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
}

void CameraBinSession::stop()
{
    if (m_status != QCamera::ActiveStatus)
        return;

    setStatus(QCamera::StoppingStatus);

    if (m_recordingActive)
        stopVideoRecording();

    if (m_viewfinderInterface)
        m_viewfinderInterface->stopRenderer();

    gst_element_set_state(m_camerabin, GST_STATE_READY);
}

bool CameraBinSession::isBusy() const
{
    return m_busy;
}

void CameraBinSession::updateBusyStatus(GObject *o, GParamSpec *p, gpointer d)
{
    Q_UNUSED(p);
    CameraBinSession *session = reinterpret_cast<CameraBinSession *>(d);

    gboolean idle = false;
    g_object_get(o, "idle", &idle, NULL);
    bool busy = !idle;

    if (session->m_busy != busy) {
        session->m_busy = busy;
        QMetaObject::invokeMethod(session, "busyChanged",
                                  Qt::QueuedConnection,
                                  Q_ARG(bool, busy));
    }
}

qint64 CameraBinSession::duration() const
{
    if (m_camerabin) {
        GstElement *fileSink = gst_bin_get_by_name(GST_BIN(m_camerabin), FILESINK_BIN_NAME);
        if (fileSink) {
            GstFormat format = GST_FORMAT_TIME;
            gint64 duration = 0;
            bool ret = qt_gst_element_query_position(fileSink, format, &duration);
            gst_object_unref(GST_OBJECT(fileSink));
            if (ret)
                return duration / 1000000;
        }
    }

    return 0;
}

bool CameraBinSession::isMuted() const
{
    return m_muted;
}

void CameraBinSession::setMuted(bool muted)
{
    if (m_muted != muted) {
        m_muted = muted;

        if (m_camerabin)
            g_object_set(G_OBJECT(m_camerabin), MUTE_PROPERTY, m_muted, NULL);
        emit mutedChanged(m_muted);
    }
}

void CameraBinSession::setCaptureDevice(const QString &deviceName)
{
    m_captureDevice = deviceName;
}

void CameraBinSession::setMetaData(const QMap<QByteArray, QVariant> &data)
{
    m_metaData = data;

    if (m_camerabin)
        QGstUtils::setMetaData(m_camerabin, data);
}

bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message)
{
    GstMessage* gm = message.rawMessage();

    if (gm && GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ELEMENT) {
        const GstStructure *st = gst_message_get_structure(gm);
        const GValue *sampleValue = 0;
        if (m_captureMode == QCamera::CaptureStillImage
                    && gst_structure_has_name(st, "preview-image")
#if GST_CHECK_VERSION(1,0,0)
                    && gst_structure_has_field_typed(st, "sample", GST_TYPE_SAMPLE)
                    && (sampleValue = gst_structure_get_value(st, "sample"))) {
            GstSample * const sample = gst_value_get_sample(sampleValue);
            GstCaps * const previewCaps = gst_sample_get_caps(sample);
            GstBuffer * const buffer = gst_sample_get_buffer(sample);
#else
                    && gst_structure_has_field_typed(st, "buffer", GST_TYPE_BUFFER)
                    && (sampleValue = gst_structure_get_value(st, "buffer"))) {
            GstBuffer * const buffer = gst_value_get_buffer(sampleValue);
#endif

            QImage image;
#if GST_CHECK_VERSION(1,0,0)
            GstVideoInfo previewInfo;
            if (gst_video_info_from_caps(&previewInfo, previewCaps))
                image = QGstUtils::bufferToImage(buffer, previewInfo);
#else
            image = QGstUtils::bufferToImage(buffer);
            gst_buffer_unref(buffer);
#endif
            if (!image.isNull()) {
                static QMetaMethod exposedSignal = QMetaMethod::fromSignal(&CameraBinSession::imageExposed);
                exposedSignal.invoke(this,
                                     Qt::QueuedConnection,
                                     Q_ARG(int,m_requestId));

                static QMetaMethod capturedSignal = QMetaMethod::fromSignal(&CameraBinSession::imageCaptured);
                capturedSignal.invoke(this,
                                      Qt::QueuedConnection,
                                      Q_ARG(int,m_requestId),
                                      Q_ARG(QImage,image));
            }
            return true;
        }
#if QT_CONFIG(gstreamer_photography)
        if (gst_structure_has_name(st, GST_PHOTOGRAPHY_AUTOFOCUS_DONE))
            m_cameraFocusControl->handleFocusMessage(gm);
#endif
    }

    return false;
}

bool CameraBinSession::processBusMessage(const QGstreamerMessage &message)
{
    GstMessage* gm = message.rawMessage();

    if (gm) {
        if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_ERROR) {
            GError *err;
            gchar *debug;
            gst_message_parse_error (gm, &err, &debug);

            QString message;

            if (err && err->message) {
                message = QString::fromUtf8(err->message);
                qWarning() << "CameraBin error:" << message;
#if CAMERABIN_DEBUG
                qWarning() << QString::fromUtf8(debug);
#endif
            }

            // Only report error messages from camerabin or video source
            if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_camerabin)
                || GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSrc)) {
                if (message.isEmpty())
                    message = tr("Camera error");

                setError(int(QMediaRecorder::ResourceError), message);
            }

#ifdef CAMERABIN_DEBUG_DUMP_BIN
            _gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_camerabin),
                                  GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/),
                                  "camerabin_error");
#endif


            if (err)
                g_error_free (err);

            if (debug)
                g_free (debug);
        }

        if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_WARNING) {
            GError *err;
            gchar *debug;
            gst_message_parse_warning (gm, &err, &debug);

            if (err && err->message)
                qWarning() << "CameraBin warning:" << QString::fromUtf8(err->message);

            if (err)
                g_error_free (err);
            if (debug)
                g_free (debug);
        }

        if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_camerabin)) {
            switch (GST_MESSAGE_TYPE(gm))  {
            case GST_MESSAGE_DURATION:
                break;

            case GST_MESSAGE_STATE_CHANGED:
                {

                    GstState    oldState;
                    GstState    newState;
                    GstState    pending;

                    gst_message_parse_state_changed(gm, &oldState, &newState, &pending);


#if CAMERABIN_DEBUG
                    QStringList states;
                    states << "GST_STATE_VOID_PENDING" <<  "GST_STATE_NULL" << "GST_STATE_READY" << "GST_STATE_PAUSED" << "GST_STATE_PLAYING";


                    qDebug() << QString("state changed: old: %1  new: %2  pending: %3") \
                            .arg(states[oldState]) \
                           .arg(states[newState]) \
                            .arg(states[pending]);
#endif

#ifdef CAMERABIN_DEBUG_DUMP_BIN
                    _gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_camerabin),
                                  GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /*GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/),
                                  "camerabin");
#endif

                    switch (newState) {
                    case GST_STATE_VOID_PENDING:
                    case GST_STATE_NULL:
                        setStatus(QCamera::UnloadedStatus);
                        break;
                    case GST_STATE_READY:
                        if (oldState == GST_STATE_NULL)
                            m_supportedViewfinderSettings.clear();

                        setMetaData(m_metaData);
                        setStatus(QCamera::LoadedStatus);
                        break;
                    case GST_STATE_PLAYING:
                        setStatus(QCamera::ActiveStatus);
                        break;
                    case GST_STATE_PAUSED:
                    default:
                        break;
                    }
                }
                break;
            default:
                break;
            }
        }
    }

    return false;
}

QGstreamerVideoProbeControl *CameraBinSession::videoProbe()
{
    return &m_viewfinderProbe;
}

QString CameraBinSession::currentContainerFormat() const
{
    if (!m_muxer)
        return QString();

    QString format;

    if (GstPad *srcPad = gst_element_get_static_pad(m_muxer, "src")) {
        if (GstCaps *caps = qt_gst_pad_get_caps(srcPad)) {
            gchar *capsString = gst_caps_to_string(caps);
            format = QString::fromLatin1(capsString);
            if (capsString)
                g_free(capsString);
            gst_caps_unref(caps);
        }
        gst_object_unref(GST_OBJECT(srcPad));
    }

    return format;
}

void CameraBinSession::recordVideo()
{
    QString format = currentContainerFormat();
    if (format.isEmpty())
        format = m_mediaContainerControl->actualContainerFormat();

    const QString fileName = m_sink.isLocalFile() ? m_sink.toLocalFile() : m_sink.toString();
    const QFileInfo fileInfo(fileName);
    const QString extension = fileInfo.suffix().isEmpty()
                            ? QGstUtils::fileExtensionForMimeType(format)
                            : fileInfo.suffix();

    const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName,
                                      QMediaStorageLocation::Movies,
                                      QLatin1String("clip_"),
                                      extension);

    m_recordingActive = true;
    m_actualSink = QUrl::fromLocalFile(actualFileName);

    g_object_set(G_OBJECT(m_camerabin), FILENAME_PROPERTY, QFile::encodeName(actualFileName).constData(), NULL);

    g_signal_emit_by_name(G_OBJECT(m_camerabin), CAPTURE_START, NULL);
}

void CameraBinSession::stopVideoRecording()
{
    m_recordingActive = false;
    g_signal_emit_by_name(G_OBJECT(m_camerabin), CAPTURE_STOP, NULL);
}

//internal, only used by CameraBinSession::supportedFrameRates.
//recursively fills the list of framerates res from value data.
static void readValue(const GValue *value, QList< QPair<int,int> > *res, bool *continuous)
{
    if (GST_VALUE_HOLDS_FRACTION(value)) {
        int num = gst_value_get_fraction_numerator(value);
        int denum = gst_value_get_fraction_denominator(value);

        *res << QPair<int,int>(num, denum);
    } else if (GST_VALUE_HOLDS_FRACTION_RANGE(value)) {
        const GValue *rateValueMin = gst_value_get_fraction_range_min(value);
        const GValue *rateValueMax = gst_value_get_fraction_range_max(value);

        if (continuous)
            *continuous = true;

        readValue(rateValueMin, res, continuous);
        readValue(rateValueMax, res, continuous);
    } else if (GST_VALUE_HOLDS_LIST(value)) {
        for (uint i=0; i<gst_value_list_get_size(value); i++) {
            readValue(gst_value_list_get_value(value, i), res, continuous);
        }
    }
}

static bool rateLessThan(const QPair<int,int> &r1, const QPair<int,int> &r2)
{
     return r1.first*r2.second < r2.first*r1.second;
}

GstCaps *CameraBinSession::supportedCaps(QCamera::CaptureModes mode) const
{
    GstCaps *supportedCaps = 0;

    // When using wrappercamerabinsrc, get the supported caps directly from the video source element.
    // This makes sure we only get the caps actually supported by the video source element.
    if (m_videoSrc) {
        GstPad *pad = gst_element_get_static_pad(m_videoSrc, "src");
        if (pad) {
            supportedCaps = qt_gst_pad_get_caps(pad);
            gst_object_unref(GST_OBJECT(pad));
        }
    }

    // Otherwise, let the camerabin handle this.
    if (!supportedCaps) {
        const gchar *prop;
        switch (mode) {
        case QCamera::CaptureStillImage:
            prop = SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY;
            break;
        case QCamera::CaptureVideo:
            prop = SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY;
            break;
        case QCamera::CaptureViewfinder:
        default:
            prop = SUPPORTED_VIEWFINDER_CAPS_PROPERTY;
            break;
        }

        g_object_get(G_OBJECT(m_camerabin), prop, &supportedCaps, NULL);
    }

    return supportedCaps;
}

QList< QPair<int,int> > CameraBinSession::supportedFrameRates(const QSize &frameSize, bool *continuous) const
{
    QList< QPair<int,int> > res;

    GstCaps *supportedCaps = this->supportedCaps(QCamera::CaptureVideo);

    if (!supportedCaps)
        return res;

    GstCaps *caps = 0;

    if (frameSize.isEmpty()) {
        caps = gst_caps_copy(supportedCaps);
    } else {
        GstCaps *filter = QGstUtils::videoFilterCaps();
        gst_caps_set_simple(
                    filter,
                    "width", G_TYPE_INT, frameSize.width(),
                    "height", G_TYPE_INT, frameSize.height(),
                     NULL);

        caps = gst_caps_intersect(supportedCaps, filter);
        gst_caps_unref(filter);
    }
    gst_caps_unref(supportedCaps);

    //simplify to the list of rates only:
    caps = gst_caps_make_writable(caps);
    for (uint i=0; i<gst_caps_get_size(caps); i++) {
        GstStructure *structure = gst_caps_get_structure(caps, i);
        gst_structure_set_name(structure, "video/x-raw");
#if GST_CHECK_VERSION(1,2,0)
        gst_caps_set_features(caps, i, NULL);
#endif
        const GValue *oldRate = gst_structure_get_value(structure, "framerate");
        if (!oldRate)
            continue;

        GValue rate;
        memset(&rate, 0, sizeof(rate));
        g_value_init(&rate, G_VALUE_TYPE(oldRate));
        g_value_copy(oldRate, &rate);
        gst_structure_remove_all_fields(structure);
        gst_structure_set_value(structure, "framerate", &rate);
    }
#if GST_CHECK_VERSION(1,0,0)
    caps = gst_caps_simplify(caps);
#else
    gst_caps_do_simplify(caps);
#endif

    for (uint i=0; i<gst_caps_get_size(caps); i++) {
        GstStructure *structure = gst_caps_get_structure(caps, i);
        const GValue *rateValue = gst_structure_get_value(structure, "framerate");
        if (!rateValue)
            continue;

        readValue(rateValue, &res, continuous);
    }

    std::sort(res.begin(), res.end(), rateLessThan);

#if CAMERABIN_DEBUG
    qDebug() << "Supported rates:" << caps;
    qDebug() << res;
#endif

    gst_caps_unref(caps);

    return res;
}

//internal, only used by CameraBinSession::supportedResolutions
//recursively find the supported resolutions range.
static QPair<int,int> valueRange(const GValue *value, bool *continuous)
{
    int minValue = 0;
    int maxValue = 0;

    if (g_value_type_compatible(G_VALUE_TYPE(value), G_TYPE_INT)) {
        minValue = maxValue = g_value_get_int(value);
    } else if (GST_VALUE_HOLDS_INT_RANGE(value)) {
        minValue = gst_value_get_int_range_min(value);
        maxValue = gst_value_get_int_range_max(value);
        *continuous = true;
    } else if (GST_VALUE_HOLDS_LIST(value)) {
        for (uint i=0; i<gst_value_list_get_size(value); i++) {
            QPair<int,int> res = valueRange(gst_value_list_get_value(value, i), continuous);

            if (res.first > 0 && minValue > 0)
                minValue = qMin(minValue, res.first);
            else //select non 0 valid value
                minValue = qMax(minValue, res.first);

            maxValue = qMax(maxValue, res.second);
        }
    }

    return QPair<int,int>(minValue, maxValue);
}

static bool resolutionLessThan(const QSize &r1, const QSize &r2)
{
     return qlonglong(r1.width()) * r1.height() < qlonglong(r2.width()) * r2.height();
}


QList<QSize> CameraBinSession::supportedResolutions(QPair<int,int> rate,
                                                    bool *continuous,
                                                    QCamera::CaptureModes mode) const
{
    QList<QSize> res;

    if (continuous)
        *continuous = false;

    GstCaps *supportedCaps = this->supportedCaps(mode);

#if CAMERABIN_DEBUG
    qDebug() << "Source caps:" << supportedCaps;
#endif

    if (!supportedCaps)
        return res;

    GstCaps *caps = 0;
    bool isContinuous = false;

    if (rate.first <= 0 || rate.second <= 0) {
        caps = gst_caps_copy(supportedCaps);
    } else {
        GstCaps *filter = QGstUtils::videoFilterCaps();
        gst_caps_set_simple(
                    filter,
                    "framerate"     , GST_TYPE_FRACTION , rate.first, rate.second,
                     NULL);
        caps = gst_caps_intersect(supportedCaps, filter);
        gst_caps_unref(filter);
    }
    gst_caps_unref(supportedCaps);

    //simplify to the list of resolutions only:
    caps = gst_caps_make_writable(caps);
    for (uint i=0; i<gst_caps_get_size(caps); i++) {
        GstStructure *structure = gst_caps_get_structure(caps, i);
        gst_structure_set_name(structure, "video/x-raw");
#if GST_CHECK_VERSION(1,2,0)
        gst_caps_set_features(caps, i, NULL);
#endif
        const GValue *oldW = gst_structure_get_value(structure, "width");
        const GValue *oldH = gst_structure_get_value(structure, "height");
        if (!oldW || !oldH)
            continue;

        GValue w;
        memset(&w, 0, sizeof(GValue));
        GValue h;
        memset(&h, 0, sizeof(GValue));
        g_value_init(&w, G_VALUE_TYPE(oldW));
        g_value_init(&h, G_VALUE_TYPE(oldH));
        g_value_copy(oldW, &w);
        g_value_copy(oldH, &h);
        gst_structure_remove_all_fields(structure);
        gst_structure_set_value(structure, "width", &w);
        gst_structure_set_value(structure, "height", &h);
    }

#if GST_CHECK_VERSION(1,0,0)
    caps = gst_caps_simplify(caps);
#else
    gst_caps_do_simplify(caps);
#endif


    for (uint i=0; i<gst_caps_get_size(caps); i++) {
        GstStructure *structure = gst_caps_get_structure(caps, i);
        const GValue *wValue = gst_structure_get_value(structure, "width");
        const GValue *hValue = gst_structure_get_value(structure, "height");
        if (!wValue || !hValue)
            continue;

        QPair<int,int> wRange = valueRange(wValue, &isContinuous);
        QPair<int,int> hRange = valueRange(hValue, &isContinuous);

        QSize minSize(wRange.first, hRange.first);
        QSize maxSize(wRange.second, hRange.second);

        if (!minSize.isEmpty())
            res << minSize;

        if (minSize != maxSize && !maxSize.isEmpty())
            res << maxSize;
    }


    std::sort(res.begin(), res.end(), resolutionLessThan);

    //if the range is continuos, populate is with the common rates
    if (isContinuous && res.size() >= 2) {
        //fill the ragne with common value
        static const QList<QSize> commonSizes =
                QList<QSize>() << QSize(128, 96)
                               << QSize(160,120)
                               << QSize(176, 144)
                               << QSize(320, 240)
                               << QSize(352, 288)
                               << QSize(640, 480)
                               << QSize(848, 480)
                               << QSize(854, 480)
                               << QSize(1024, 768)
                               << QSize(1280, 720) // HD 720
                               << QSize(1280, 1024)
                               << QSize(1600, 1200)
                               << QSize(1920, 1080) // HD
                               << QSize(1920, 1200)
                               << QSize(2048, 1536)
                               << QSize(2560, 1600)
                               << QSize(2580, 1936);
        QSize minSize = res.first();
        QSize maxSize = res.last();
        res.clear();

        for (const QSize &candidate : commonSizes) {
            int w = candidate.width();
            int h = candidate.height();

            if (w > maxSize.width() && h > maxSize.height())
                break;

            if (w >= minSize.width() && h >= minSize.height() &&
                w <= maxSize.width() && h <= maxSize.height())
                res << candidate;
        }

        if (res.isEmpty() || res.first() != minSize)
            res.prepend(minSize);

        if (res.last() != maxSize)
            res.append(maxSize);
    }

#if CAMERABIN_DEBUG
    qDebug() << "Supported resolutions:" << gst_caps_to_string(caps);
    qDebug() << res;
#endif

    gst_caps_unref(caps);

    if (continuous)
        *continuous = isContinuous;

    return res;
}

void CameraBinSession::elementAdded(GstBin *, GstElement *element, CameraBinSession *session)
{
    GstElementFactory *factory = gst_element_get_factory(element);

    if (GST_IS_BIN(element)) {
        g_signal_connect(G_OBJECT(element), "element-added",  G_CALLBACK(elementAdded), session);
        g_signal_connect(G_OBJECT(element), "element-removed",  G_CALLBACK(elementRemoved), session);
    } else if (!factory) {
        // no-op
#if GST_CHECK_VERSION(0,10,31)
    } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER)) {
#else
    } else if (strstr(gst_element_factory_get_klass(factory), "Encoder/Audio") != NULL) {
#endif
        session->m_audioEncoder = element;

        session->m_audioEncodeControl->applySettings(element);
#if GST_CHECK_VERSION(0,10,31)
    } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER)) {
#else
    } else if (strstr(gst_element_factory_get_klass(factory), "Encoder/Video") != NULL) {
#endif
        session->m_videoEncoder = element;

        session->m_videoEncodeControl->applySettings(element);
#if GST_CHECK_VERSION(0,10,31)
    } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_MUXER)) {
#else
    } else if (strstr(gst_element_factory_get_klass(factory), "Muxer") != NULL) {
#endif
        session->m_muxer = element;
    }
}

void CameraBinSession::elementRemoved(GstBin *, GstElement *element, CameraBinSession *session)
{
    if (element == session->m_audioEncoder)
        session->m_audioEncoder = 0;
    else if (element == session->m_videoEncoder)
        session->m_videoEncoder = 0;
    else if (element == session->m_muxer)
        session->m_muxer = 0;
}

QT_END_NAMESPACE
