Home_greyBuild Service > Projects > devel:performance > qt-mobility > Files > Moorestown_Camera_Support.patch
Login

View File Moorestown_Camera_Support.patch for package qt-mobility (Project devel:performance)

--- a/plugins/multimedia/gstreamer/mediacapture/mediacapture.pri
+++ b/plugins/multimedia/gstreamer/mediacapture/mediacapture.pri
@@ -12,7 +12,12 @@ HEADERS += $$PWD/qgstreamercaptureservice.h \
     $$PWD/qgstreamerv4l2input.h \
     $$PWD/qgstreamercapturemetadatacontrol.h \
     $$PWD/qgstreamerimagecapturecontrol.h \
-    $$PWD/qgstreamerimageencode.h
+    $$PWD/qgstreamerimageencode.h \
+    $$PWD/qgstreamerfocus.h \
+    $$PWD/qgstreamerflash.h \
+    $$PWD/qgstreamerlocks.h \
+    $$PWD/qgstreamerexposure.h \
+    $$PWD/qgstreamerimageprocessing.h
 
 SOURCES += $$PWD/qgstreamercaptureservice.cpp \
     $$PWD/qgstreamercapturesession.cpp \
@@ -24,4 +29,9 @@ SOURCES += $$PWD/qgstreamercaptureservice.cpp \
     $$PWD/qgstreamerv4l2input.cpp \
     $$PWD/qgstreamercapturemetadatacontrol.cpp \
     $$PWD/qgstreamerimagecapturecontrol.cpp \
-    $$PWD/qgstreamerimageencode.cpp
+    $$PWD/qgstreamerimageencode.cpp \
+    $$PWD/qgstreamerfocus.cpp \
+    $$PWD/qgstreamerflash.cpp \
+    $$PWD/qgstreamerlocks.cpp \
+    $$PWD/qgstreamerexposure.cpp \
+    $$PWD/qgstreamerimageprocessing.cpp
--- a/plugins/multimedia/gstreamer/mediacapture/qgstreameraudioencode.cpp
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreameraudioencode.cpp
@@ -67,7 +67,12 @@ QGstreamerAudioEncode::QGstreamerAudioEncode(QObject *parent)
     m_elementNames["audio/AMR-WB"] = "nokiaamrwbenc";
     m_elementNames["audio/AAC"] = "nokiaaacenc";
 #else
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    m_elementNames["audio/mpeg"] = "flumcaacenc";
+#else
     m_elementNames["audio/mpeg"] = "lamemp3enc";
+#endif
     m_elementNames["audio/AMR"] = "amrnbenc";
     m_elementNames["audio/AMR-WB"] = "amrwbenc";
 #endif
@@ -79,7 +84,9 @@ QGstreamerAudioEncode::QGstreamerAudioEncode(QObject *parent)
     m_elementNames["audio/GSM"] = "gsmenc";
 
     m_codecOptions["audio/vorbis"] = QStringList() << "min-bitrate" << "max-bitrate";
+#ifndef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
     m_codecOptions["audio/mpeg"] = QStringList() << "mode";
+#endif
     m_codecOptions["audio/speex"] = QStringList() << "mode" << "vbr" << "vad" << "dtx";
     m_codecOptions["audio/GSM"] = QStringList();
     m_codecOptions["audio/PCM"] = QStringList();
@@ -214,6 +221,7 @@ GstElement *QGstreamerAudioEncode::createEncoder()
                 };
                 g_object_set(G_OBJECT(encoderElement), "quality", qualityTable[qualityValue], NULL);
             } else if (codec == QLatin1String("audio/mpeg")) {
+#ifndef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
                 g_object_set(G_OBJECT(encoderElement), "target", 0, NULL); //constant quality mode
                 qreal quality[] = {
                     1, //VeryLow
@@ -222,6 +230,15 @@ GstElement *QGstreamerAudioEncode::createEncoder()
                     7, //High
                     9 //VeryHigh
                 };
+#else
+                int quality[] = {
+                    1, //VeryLow
+                    3, //Low
+                    5, //Normal
+                    7, //High
+                    9 //VeryHigh
+                };
+#endif
                 g_object_set(G_OBJECT(encoderElement), "quality", quality[qualityValue], NULL);
             } else if (codec == QLatin1String("audio/speex")) {
                 //0-10 range with default 8
@@ -247,9 +264,11 @@ GstElement *QGstreamerAudioEncode::createEncoder()
         } else {
             int bitrate = m_audioSettings.bitRate();
             if (bitrate > 0) {
+#ifndef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
                 if (codec == QLatin1String("audio/mpeg")) {
                     g_object_set(G_OBJECT(encoderElement), "target", 1, NULL); //constant bitrate mode
                 }
+#endif
                 g_object_set(G_OBJECT(encoderElement), "bitrate", bitrate, NULL);
             }
         }
--- a/plugins/multimedia/gstreamer/mediacapture/qgstreamercaptureservice.cpp
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamercaptureservice.cpp
@@ -157,6 +157,23 @@ QMediaControl *QGstreamerCaptureService::requestControl(const char *name)
     if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0)
         return m_imageCaptureControl;
     
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    if (qstrcmp(name, QCameraExposureControl_iid) == 0)
+        return m_captureSession->cameraExposureControl();
+
+    if (qstrcmp(name, QCameraFlashControl_iid) == 0)
+        return m_captureSession->cameraFlashControl();
+
+    if (qstrcmp(name, QCameraFocusControl_iid) == 0)
+        return m_captureSession->cameraFocusControl();
+
+    if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0)
+        return m_captureSession->imageProcessingControl();
+
+    if (qstrcmp(name, QCameraLocksControl_iid) == 0)
+        return m_captureSession->cameraLocksControl();
+#endif
+
     if (!m_videoOutput) {
         if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
             m_videoOutput = m_videoRenderer;
--- a/plugins/multimedia/gstreamer/mediacapture/qgstreamercapturesession.cpp
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamercapturesession.cpp
@@ -88,9 +88,26 @@ QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::Cap
      m_videoPreview(0),
      m_imageCaptureBin(0),
      m_encodeBin(0),
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+     m_capsFilter(0),
+     m_videoRecordQueue(0),
+#endif
      m_passImage(false),
      m_passPrerollImage(false)
 {
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    GstElementFactory * mrstcamsrc =  gst_element_factory_find ("mrstcamsrc");
+    if(mrstcamsrc)
+    {
+        gst_object_unref(GST_OBJECT(mrstcamsrc));
+        m_isMoorestown = true;
+    }
+    else
+    {
+        m_isMoorestown = false;
+    }
+#endif
+
     m_pipeline = gst_pipeline_new("media-capture-pipeline");
     gstRef(m_pipeline);
 
@@ -104,6 +121,14 @@ QGstreamerCaptureSession::QGstreamerCaptureSession(QGstreamerCaptureSession::Cap
     m_recorderControl = new QGstreamerRecorderControl(this);
     m_mediaContainerControl = new QGstreamerMediaContainerControl(this);
 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    m_cameraExposureControl = new QGstreamerExposure(this);
+    m_cameraFlashControl = new QGstreamerFlash(this);
+    m_cameraFocusControl = new QGstreamerFocus(this);
+    m_imageProcessingControl = new QGstreamerImageProcessing(this);
+    m_cameraLocksControl = new QGstreamerLocks(this);
+#endif
+
     setState(StoppedState);
 }
 
@@ -119,6 +144,14 @@ void QGstreamerCaptureSession::setCaptureMode(CaptureMode mode)
     m_captureMode = mode;
 }
 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+static void DynamicLink (GstPadTemplate * templ, GstPad * newpad, gpointer target)
+{
+    Q_UNUSED(templ);
+    gst_pad_link (newpad, (GstPad *)target);
+}
+#endif
+
 GstElement *QGstreamerCaptureSession::buildEncodeBin()
 {
     GstElement *encodeBin = gst_bin_new("encode-bin");
@@ -169,24 +202,44 @@ GstElement *QGstreamerCaptureSession::buildEncodeBin()
 
     if (m_captureMode & Video) {
         GstElement *videoQueue = gst_element_factory_make("queue", "video-encode-queue");
-        GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-encoder");
-        GstElement *videoscale = gst_element_factory_make("videoscale","videoscale-encoder");
-        gst_bin_add_many(GST_BIN(encodeBin), videoQueue, colorspace, videoscale, NULL);
-
-        GstElement *videoEncoder = m_videoEncodeControl->createEncoder();
-        if (!videoEncoder) {
-            gst_object_unref(encodeBin);
-            qWarning() << "Could not create a video encoder element:" << m_videoEncodeControl->videoSettings().codec();
-            return 0;
-        }
 
-        gst_bin_add(GST_BIN(encodeBin), videoEncoder);
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+        if(m_isMoorestown)
+        {
+            GstElement *capsFilter = gst_element_factory_make("capsfilter", "video-encode-capsfilter");
+            QString codec = m_videoEncodeControl->videoSettings().codec();
+            GstCaps *caps = gst_caps_new_simple(codec.toUtf8().constData(), NULL);
+            g_object_set(G_OBJECT(capsFilter), "caps", caps, NULL);
+            gst_caps_unref(caps);
 
-        if (!gst_element_link_many(videoQueue, colorspace, videoscale, videoEncoder, muxer, NULL)) {
-            gst_object_unref(encodeBin);
-            return 0;
+            gst_bin_add_many(GST_BIN(encodeBin), videoQueue, capsFilter, NULL);
+            if (!gst_element_link_many(videoQueue, capsFilter, muxer, NULL))
+			{
+		        gst_object_unref(encodeBin);
+		        return 0;
+			}
         }
-
+        else
+#endif
+		{
+		    GstElement *colorspace = gst_element_factory_make("ffmpegcolorspace", "ffmpegcolorspace-encoder");
+		    GstElement *videoscale = gst_element_factory_make("videoscale","videoscale-encoder");
+		    gst_bin_add_many(GST_BIN(encodeBin), videoQueue, colorspace, videoscale, NULL);
+
+		    GstElement *videoEncoder = m_videoEncodeControl->createEncoder();
+		    if (!videoEncoder) {
+		        gst_object_unref(encodeBin);
+		        qWarning() << "Could not create a video encoder element:" << m_videoEncodeControl->videoSettings().codec();
+		        return 0;
+		    }
+
+		    gst_bin_add(GST_BIN(encodeBin), videoEncoder);
+
+		    if (!gst_element_link_many(videoQueue, colorspace, videoscale, videoEncoder, muxer, NULL)) {
+		        gst_object_unref(encodeBin);
+		        return 0;
+		    }
+		}
         // add ghostpads
         GstPad *pad = gst_element_get_static_pad(videoQueue, "sink");
         gst_element_add_pad(GST_ELEMENT(encodeBin), gst_ghost_pad_new("videosink", pad));
@@ -273,6 +326,16 @@ GstElement *QGstreamerCaptureSession::buildVideoSrc()
     GstElement *videoSrc = 0;
     if (m_videoInputFactory) {
         videoSrc = m_videoInputFactory->buildElement();
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+        if(m_isMoorestown)
+        {
+            m_videoSrc = videoSrc;
+            m_cameraExposureControl->setExposureMode(m_cameraExposureControl->exposureMode());
+            m_cameraFocusControl->setFocusMode(m_cameraFocusControl->focusMode());
+            m_imageProcessingControl->setWhiteBalanceMode(m_imageProcessingControl->whiteBalanceMode());
+            m_cameraFlashControl->setFlashMode(m_cameraFlashControl->flashMode());
+        }
+#endif
     } else {
         videoSrc = gst_element_factory_make("videotestsrc", "video_test_src");
         //videoSrc = gst_element_factory_make("v4l2src", "video_test_src");
@@ -534,6 +597,12 @@ void QGstreamerCaptureSession::captureImage(int requestId, const QString &fileNa
     m_imageRequestId = requestId;
     m_imageFileName = fileName;
     m_passImage = true;
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    if(m_isMoorestown)
+    {
+        setState(CaptureState);
+    }
+#endif
 }
 
 
@@ -549,6 +618,10 @@ bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMo
     REMOVE_ELEMENT(m_videoPreview);
     REMOVE_ELEMENT(m_videoPreviewQueue);
     REMOVE_ELEMENT(m_videoTee);
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    REMOVE_ELEMENT(m_capsFilter);
+    REMOVE_ELEMENT(m_videoRecordQueue);
+#endif
     REMOVE_ELEMENT(m_encodeBin);
     REMOVE_ELEMENT(m_imageCaptureBin);
     m_audioVolume = 0;
@@ -558,7 +631,113 @@ bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMo
     switch (newMode) {
         case EmptyPipeline:
             break;
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+        case ImageCapturePipeline:
+            m_videoSrc = buildVideoSrc();
+            m_capsFilter = gst_element_factory_make ("capsfilter", "capsfilter");
+            m_imageCaptureBin = gst_element_factory_make("fakesink", "fakesink");
+
+            ok &= m_videoSrc && m_capsFilter && m_imageCaptureBin;
+
+            if (ok) {
+                //src setting
+                QtMultimediaKit::EncodingQuality quality = m_imageEncodeControl->imageSettings().quality();
+                int qualityTable[] = {
+                    11, //VeryLow
+                    8, //Low
+                    5, //Normal
+                    2, //High
+                    0 //VeryHigh
+                };
+                g_object_set(G_OBJECT(m_videoSrc), "jpeg-ratio", qualityTable[quality], NULL);
+                g_object_set(G_OBJECT(m_videoSrc), "video_mode", 0, NULL);
+                g_object_set(G_OBJECT(m_videoSrc), "num-buffers", 1, NULL);
+
+                //format
+                QString codec = m_imageEncodeControl->imageSettings().codec();
+                if(codec.isEmpty())
+                {
+                    codec = "jpeg";
+                }
+
+                //caps setting
+                GstCaps *caps = gst_caps_new_simple(QString("image/" + codec).toAscii().constData(), NULL);
+                QSize resolution = m_imageEncodeControl->imageSettings().resolution();
+                if(resolution.isValid())
+                {
+                    gst_caps_set_simple( caps, "width", G_TYPE_INT, resolution.width()
+                                             , "height", G_TYPE_INT, resolution.height()
+                                             , NULL);
+                }
+                g_object_set(G_OBJECT(m_capsFilter), "caps", caps, NULL);
+                gst_caps_unref(caps);
+
+                //target setting
+                g_object_set(G_OBJECT(m_imageCaptureBin), "signal-handoffs", TRUE, NULL);
+                g_signal_connect(G_OBJECT(m_imageCaptureBin), "handoff", G_CALLBACK(saveImageFilter), this);
+
+                //add and link
+                gst_bin_add_many(GST_BIN(m_pipeline), m_videoSrc, m_capsFilter, m_imageCaptureBin, NULL);
+
+                ok &= gst_element_link(m_videoSrc, m_capsFilter);
+                ok &= gst_element_link(m_capsFilter, m_imageCaptureBin);
+
+                //auto switching to preview after image captured
+                m_waitingForEos = true;
+                m_pendingState = PreviewState;
+
+            }
+            break;
+#endif
         case PreviewPipeline:
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+            if(m_isMoorestown)
+            {
+                if (m_captureMode & Video || m_captureMode & Image) {
+
+                    m_videoSrc = buildVideoSrc();
+                    m_videoTee = gst_element_factory_make("MixVideoEncoderPreview", "MixVideoEncoderPreview");
+                    m_videoPreviewQueue = gst_element_factory_make("queue", "video-preview-queue");
+                    m_videoRecordQueue = gst_element_factory_make("queue", "video-record-queue");
+                    m_videoPreview = m_viewfinderInterface->videoSink();
+                    m_imageCaptureBin = gst_element_factory_make("fakesink", "image-capture-bin");
+                    ok &= m_videoSrc && m_videoTee && m_videoPreviewQueue && m_videoRecordQueue && m_videoPreview && m_imageCaptureBin;
+
+                    if (ok) {
+                        g_object_set(G_OBJECT(m_videoSrc), "video_mode", 1, NULL);
+
+                        gst_bin_add_many(GST_BIN(m_pipeline), m_videoSrc, m_videoTee,
+                                         m_videoPreview, m_videoPreviewQueue, m_videoRecordQueue,
+                                         m_imageCaptureBin, NULL);
+
+                        //caps setting
+                        GstCaps *caps = gst_caps_new_simple("video/x-raw-va", NULL);
+                        QSize resolution = m_videoEncodeControl->videoSettings().resolution();
+                        if(resolution.isValid())
+                        {
+                            gst_caps_set_simple( caps, "width", G_TYPE_INT, resolution.width()
+                                                     , "height", G_TYPE_INT, resolution.height()
+                                                     , NULL);
+                        }
+                        if( m_videoEncodeControl->videoSettings().frameRate() > 0)
+                        {
+                            QPair<int,int> rate = m_videoEncodeControl->rateAsRational();
+                            gst_caps_set_simple( caps, "framerate", GST_TYPE_FRACTION, rate.first, rate.second, NULL);
+                        }
+                        ok &= gst_element_link_filtered(m_videoSrc, m_videoTee, caps);
+                        gst_caps_unref(caps);
+
+                        ok &= gst_element_link(m_videoTee, m_videoRecordQueue);
+                        ok &= gst_element_link(m_videoRecordQueue, m_imageCaptureBin);
+                        ok &= gst_element_link(m_videoPreviewQueue, m_videoPreview);
+
+                        g_object_set(G_OBJECT(m_videoPreview), "sync", true, NULL);
+                        g_signal_connect( G_OBJECT (m_videoTee), "pad-added", G_CALLBACK (DynamicLink), gst_element_get_static_pad(m_videoPreviewQueue, "sink"));
+                    }
+                }
+                break;
+            }
+#endif
             if (m_captureMode & Audio) {
                 m_audioSrc = buildAudioSrc();
                 m_audioPreview = buildAudioPreview();
@@ -642,8 +821,18 @@ bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMo
 
             if (ok && (m_captureMode & Video || m_captureMode & Image)) {
                 m_videoSrc = buildVideoSrc();
-                m_videoPreview = buildVideoPreview();
-                m_videoTee = gst_element_factory_make("tee", NULL);
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+                if(m_isMoorestown)
+                {
+                    m_videoPreview = m_viewfinderInterface->videoSink();
+                    m_videoTee = m_videoEncodeControl->createEncoder();
+                }
+                else
+#endif
+                {
+                    m_videoPreview = buildVideoPreview();
+                    m_videoTee = gst_element_factory_make("tee", NULL);
+                }
                 m_videoPreviewQueue = gst_element_factory_make("queue", NULL);
 
                 ok &= m_videoSrc && m_videoPreview && m_videoTee && m_videoPreviewQueue;
@@ -651,9 +840,38 @@ bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMo
                 if (ok) {
                     gst_bin_add_many(GST_BIN(m_pipeline), m_videoSrc, m_videoTee,
                                  m_videoPreviewQueue, m_videoPreview, NULL);
-                    ok &= gst_element_link(m_videoSrc, m_videoTee);
-                    ok &= gst_element_link(m_videoTee, m_videoPreviewQueue);
-                    ok &= gst_element_link(m_videoPreviewQueue, m_videoPreview);
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+                    if(m_isMoorestown)
+                    {
+                        //caps setting
+                        GstCaps *caps = gst_caps_new_simple("video/x-raw-va", NULL);
+                        QSize resolution = m_videoEncodeControl->videoSettings().resolution();
+                        if(resolution.isValid())
+                        {
+                            gst_caps_set_simple( caps, "width", G_TYPE_INT, resolution.width()
+                                                     , "height", G_TYPE_INT, resolution.height()
+                                                     , NULL);
+                        }
+                        if( m_videoEncodeControl->videoSettings().frameRate() > 0)
+                        {
+                            QPair<int,int> rate = m_videoEncodeControl->rateAsRational();
+                            gst_caps_set_simple( caps, "framerate", GST_TYPE_FRACTION, rate.first, rate.second, NULL);
+                        }
+                        ok &= gst_element_link_filtered(m_videoSrc, m_videoTee, caps);
+                        ok &= gst_element_link(m_videoPreviewQueue, m_videoPreview);
+                        gst_caps_unref(caps);
+
+                        g_object_set(G_OBJECT(m_videoSrc), "video_mode", 1, NULL);
+                        g_object_set(G_OBJECT(m_videoPreview), "sync", true, NULL);
+                        g_signal_connect( G_OBJECT (m_videoTee), "pad-added", G_CALLBACK (DynamicLink), gst_element_get_static_pad(m_videoPreviewQueue, "sink"));
+                    }
+                    else
+#endif
+                    {
+                        ok &= gst_element_link(m_videoSrc, m_videoTee);
+                        ok &= gst_element_link(m_videoTee, m_videoPreviewQueue);
+                        ok &= gst_element_link(m_videoPreviewQueue, m_videoPreview);
+                    }
                 }
 
                 if (ok && (m_captureMode & Video))
@@ -692,6 +910,10 @@ bool QGstreamerCaptureSession::rebuildGraph(QGstreamerCaptureSession::PipelineMo
         REMOVE_ELEMENT(m_videoPreview);
         REMOVE_ELEMENT(m_videoPreviewQueue);
         REMOVE_ELEMENT(m_videoTee);
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+        REMOVE_ELEMENT(m_capsFilter);
+        REMOVE_ELEMENT(m_videoRecordQueue);
+#endif
         REMOVE_ELEMENT(m_encodeBin);
     }
 
@@ -800,6 +1022,11 @@ void QGstreamerCaptureSession::setState(QGstreamerCaptureSession::State newState
         case RecordingState:
             newMode = PreviewAndRecordingPipeline;
             break;
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+        case CaptureState:
+            newMode = ImageCapturePipeline;
+            break;
+#endif
         case PreviewState:
             newMode = PreviewPipeline;
             break;
@@ -847,6 +1074,9 @@ void QGstreamerCaptureSession::setState(QGstreamerCaptureSession::State newState
         case PausedState:
             gst_element_set_state(m_pipeline, GST_STATE_PAUSED);
             break;
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+        case CaptureState:
+#endif
         case RecordingState:
         case PreviewState:
             gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
@@ -876,6 +1106,13 @@ qint64 QGstreamerCaptureSession::duration() const
 
 void QGstreamerCaptureSession::setCaptureDevice(const QString &deviceName)
 {
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    if(m_isMoorestown)
+    {
+        m_captureDevice = "alsa:default";//"pulseaudio:";
+        return;
+    }
+#endif
     m_captureDevice = deviceName;
 }
 
@@ -1018,8 +1255,13 @@ void QGstreamerCaptureSession::busMessage(const QGstreamerMessage &message)
                         break;
                     case GST_STATE_PLAYING:
                         {
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+                            if ((m_pendingState == CaptureState || m_pendingState == PreviewState || m_pendingState == RecordingState) && 
+                                m_state != m_pendingState)
+#else
                             if ((m_pendingState == PreviewState || m_pendingState == RecordingState) &&
                                 m_state != m_pendingState)
+#endif
                             {
                                 m_state = m_pendingState;
                                 emit stateChanged(m_state);
--- a/plugins/multimedia/gstreamer/mediacapture/qgstreamercapturesession.h
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamercapturesession.h
@@ -50,6 +50,12 @@
 #include <gst/gst.h>
 
 #include "qgstreamerbushelper.h"
+#include "qgstreamerfocus.h"
+#include "qgstreamerflash.h"
+#include "qgstreamerlocks.h"
+#include "qgstreamerexposure.h"
+#include "qgstreamerimageprocessing.h"
+
 
 QT_USE_NAMESPACE
 
@@ -84,7 +90,16 @@ class QGstreamerCaptureSession : public QObject, public QGstreamerSyncEventFilte
     Q_ENUMS(CaptureMode)
 public:
     enum CaptureMode { Audio = 1, Video = 2, Image=4, AudioAndVideo = Audio | Video };
-    enum State { StoppedState, PreviewState, PausedState, RecordingState };
+    enum State 
+	{ 
+		StoppedState, 
+		PreviewState, 
+		PausedState, 
+		RecordingState, 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+		CaptureState,
+#endif
+	};
 
     QGstreamerCaptureSession(CaptureMode captureMode, QObject *parent);
     ~QGstreamerCaptureSession();
@@ -101,6 +116,15 @@ public:
 
     QGstreamerRecorderControl *recorderControl() const { return m_recorderControl; }
     QGstreamerMediaContainerControl *mediaContainerControl() const { return m_mediaContainerControl; }
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    QGstreamerExposure *cameraExposureControl() const  { return m_cameraExposureControl; }
+    QGstreamerFlash *cameraFlashControl() const  { return m_cameraFlashControl; }
+    QGstreamerFocus *cameraFocusControl() const  { return m_cameraFocusControl; }
+    QGstreamerImageProcessing *imageProcessingControl() const { return m_imageProcessingControl; }
+    QGstreamerLocks *cameraLocksControl() const { return m_cameraLocksControl; }
+    GstElement * getVideoSource() const {return m_videoSrc;}
+    bool isMoorestown() {return m_isMoorestown;}
+#endif
 
     QGstreamerElementFactory *audioInput() const { return m_audioInputFactory; }
     void setAudioInput(QGstreamerElementFactory *audioInput);
@@ -148,7 +172,16 @@ private slots:
     void busMessage(const QGstreamerMessage &message);
 
 private:
-    enum PipelineMode { EmptyPipeline, PreviewPipeline, RecordingPipeline, PreviewAndRecordingPipeline };
+    enum PipelineMode 
+	{ 
+		EmptyPipeline, 
+		PreviewPipeline, 
+		RecordingPipeline, 
+		PreviewAndRecordingPipeline, 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+		ImageCapturePipeline,
+#endif
+	 };
 
     GstElement *buildEncodeBin();
     GstElement *buildAudioSrc();
@@ -178,6 +211,13 @@ private:
     QGstreamerAudioEncode *m_audioEncodeControl;
     QGstreamerVideoEncode *m_videoEncodeControl;
     QGstreamerImageEncode *m_imageEncodeControl;
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    QGstreamerExposure *m_cameraExposureControl;
+    QGstreamerFlash *m_cameraFlashControl;
+    QGstreamerFocus *m_cameraFocusControl;
+    QGstreamerImageProcessing *m_imageProcessingControl;
+    QGstreamerLocks *m_cameraLocksControl;
+#endif
     QGstreamerRecorderControl *m_recorderControl;
     QGstreamerMediaContainerControl *m_mediaContainerControl;
 
@@ -201,6 +241,12 @@ private:
 
     GstElement *m_encodeBin;
 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    GstElement *m_capsFilter;
+    GstElement *m_videoRecordQueue;
+    bool m_isMoorestown;
+#endif
+
 public:
     bool m_passImage;
     bool m_passPrerollImage;
--- /dev/null
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerexposure.cpp
@@ -0,0 +1,83 @@
+#include "qgstreamerexposure.h"
+#include "qgstreamercapturesession.h"
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+QGstreamerExposure::QGstreamerExposure(QGstreamerCaptureSession *session)
+{
+    m_session = session;
+    m_exposureMode = QCameraExposure::ExposureAuto;
+}
+
+QCameraExposure::ExposureMode QGstreamerExposure::exposureMode() const
+{
+    return m_exposureMode;
+}
+void QGstreamerExposure::setExposureMode(QCameraExposure::ExposureMode mode)
+{
+    if(isExposureModeSupported(mode))
+    {
+        m_exposureMode = mode;	
+	if(m_session->isMoorestown() && m_session->getVideoSource())
+	{
+	        g_object_set(G_OBJECT(m_session->getVideoSource()), "ae-on", mode == QCameraExposure::ExposureAuto, NULL);
+	}
+    }
+}
+bool QGstreamerExposure::isExposureModeSupported(QCameraExposure::ExposureMode mode) const
+{
+    return  mode == QCameraExposure::ExposureAuto || mode == QCameraExposure::ExposureManual;
+}
+
+QCameraExposure::MeteringMode QGstreamerExposure::meteringMode() const
+{
+    return QCameraExposure::MeteringMatrix;
+}
+
+void QGstreamerExposure::setMeteringMode(QCameraExposure::MeteringMode mode)
+{
+    Q_UNUSED(mode);
+}
+
+bool QGstreamerExposure::isMeteringModeSupported(QCameraExposure::MeteringMode mode) const
+{
+    Q_UNUSED(mode);
+    return false;
+}
+
+bool QGstreamerExposure::isParameterSupported(ExposureParameter parameter) const
+{
+    Q_UNUSED(parameter);
+    return false;
+}
+
+QVariant QGstreamerExposure::exposureParameter(ExposureParameter parameter) const
+{
+    Q_UNUSED(parameter);
+    return QVariant();
+}
+
+QCameraExposureControl::ParameterFlags QGstreamerExposure::exposureParameterFlags(ExposureParameter parameter) const
+{
+    Q_UNUSED(parameter);
+    return 0;
+}
+
+QVariantList QGstreamerExposure::supportedParameterRange(ExposureParameter parameter) const
+{
+    Q_UNUSED(parameter);
+    return QVariantList();
+}
+
+bool QGstreamerExposure::setExposureParameter(ExposureParameter parameter, const QVariant& value)
+{
+    Q_UNUSED(parameter);
+    Q_UNUSED(value);
+    return false;
+}
+
+QString QGstreamerExposure::extendedParameterName(ExposureParameter parameter)
+{
+    Q_UNUSED(parameter);
+    return QString();
+}
+#endif
--- /dev/null
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerexposure.h
@@ -0,0 +1,38 @@
+#ifndef QGSTREAMEREXPOSURE_H
+#define QGSTREAMEREXPOSURE_H
+ 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+
+#include <gst/gst.h> 
+#include <qcameraexposurecontrol.h> 
+
+class QGstreamerCaptureSession;
+class QGstreamerExposure : public QCameraExposureControl
+{
+public:
+    QGstreamerExposure(QGstreamerCaptureSession *session);
+
+    virtual QCameraExposure::ExposureMode exposureMode() const;
+    virtual void setExposureMode(QCameraExposure::ExposureMode mode);
+    virtual bool isExposureModeSupported(QCameraExposure::ExposureMode mode) const;
+
+    virtual QCameraExposure::MeteringMode meteringMode() const;
+    virtual void setMeteringMode(QCameraExposure::MeteringMode mode);
+    virtual bool isMeteringModeSupported(QCameraExposure::MeteringMode mode) const;
+
+    virtual bool isParameterSupported(ExposureParameter parameter) const;
+    virtual QVariant exposureParameter(ExposureParameter parameter) const;
+    virtual ParameterFlags exposureParameterFlags(ExposureParameter parameter) const;
+    virtual QVariantList supportedParameterRange(ExposureParameter parameter) const;
+    virtual bool setExposureParameter(ExposureParameter parameter, const QVariant& value);
+
+    virtual QString extendedParameterName(ExposureParameter parameter);
+
+private:
+    QGstreamerCaptureSession *m_session;
+    QCameraExposure::ExposureMode m_exposureMode;
+
+};
+#endif
+
+#endif
--- /dev/null
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerflash.cpp
@@ -0,0 +1,48 @@
+#include "qgstreamerflash.h"
+#include "qgstreamercapturesession.h"
+#include "qgstreamerv4l2input.h"
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+QGstreamerFlash::QGstreamerFlash(QGstreamerCaptureSession *session)
+{
+    m_session = session;
+    m_mode = QCameraExposure::FlashOff;
+}
+
+QCameraExposure::FlashModes QGstreamerFlash::flashMode() const
+{
+    return m_mode;
+}
+
+void QGstreamerFlash::setFlashMode(QCameraExposure::FlashModes mode)
+{
+    if(isFlashModeSupported(mode))
+    {
+        m_mode = mode;	
+	if(m_session->isMoorestown() && m_session->getVideoSource())
+	{
+	        g_object_set(G_OBJECT(m_session->getVideoSource()), "flash-mode-on", mode == QCameraExposure::FlashOn, NULL);
+	}	
+    }
+}
+
+bool QGstreamerFlash::isFlashModeSupported(QCameraExposure::FlashModes mode) const
+{
+    if(m_session->isMoorestown())
+    {
+        QGstreamerV4L2Input* videoInput = static_cast<QGstreamerV4L2Input*>(m_session->videoInput());
+
+        if((videoInput != NULL) && (videoInput->device() == "/dev/video0"))
+        {
+            return  mode == QCameraExposure::FlashOn || mode == QCameraExposure::FlashOff;
+        }
+    }
+
+    return false;
+}
+
+bool QGstreamerFlash::isFlashReady() const
+{
+    return true;
+}
+#endif
--- /dev/null
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerflash.h
@@ -0,0 +1,25 @@
+#ifndef QGSTREAMERFLASH_H
+#define QGSTREAMERFLASH_H
+ 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+
+#include <gst/gst.h> 
+#include <qcameraflashcontrol.h> 
+
+class QGstreamerCaptureSession;
+class QGstreamerFlash : public QCameraFlashControl
+{
+public:
+    QGstreamerFlash(QGstreamerCaptureSession *session);
+
+    virtual QCameraExposure::FlashModes flashMode() const;
+    virtual void setFlashMode(QCameraExposure::FlashModes mode);
+    virtual bool isFlashModeSupported(QCameraExposure::FlashModes mode) const;
+    virtual bool isFlashReady() const;
+private:
+    QGstreamerCaptureSession *m_session;
+    QCameraExposure::FlashModes m_mode;
+};
+#endif
+
+#endif
--- /dev/null
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerfocus.cpp
@@ -0,0 +1,87 @@
+#include "qgstreamerfocus.h"
+#include "qgstreamercapturesession.h"
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+QGstreamerFocus::QGstreamerFocus(QGstreamerCaptureSession *session)
+{
+    m_session = session;
+    m_focusMode = QCameraFocus::AutoFocus;
+}
+
+QCameraFocus::FocusMode QGstreamerFocus::focusMode() const
+{
+    return m_focusMode;
+}
+
+void QGstreamerFocus::setFocusMode(QCameraFocus::FocusMode mode)
+{
+    if(isFocusModeSupported(mode))
+    {
+        m_focusMode = mode;
+	if(m_session->isMoorestown() && m_session->getVideoSource())
+	{
+	        g_object_set(G_OBJECT(m_session->getVideoSource()), "af-on", mode == QCameraFocus::AutoFocus, NULL);
+	}
+    }
+}
+
+bool QGstreamerFocus::isFocusModeSupported(QCameraFocus::FocusMode mode) const
+{
+    return  mode == QCameraFocus::AutoFocus || mode == QCameraFocus::ManualFocus;
+}
+
+qreal QGstreamerFocus::maximumOpticalZoom() const
+{
+    return 1.0;
+}
+
+qreal QGstreamerFocus::maximumDigitalZoom() const
+{
+    return 1.0;
+}
+
+qreal QGstreamerFocus::opticalZoom() const
+{
+    return 1.0;
+}
+
+qreal QGstreamerFocus::digitalZoom() const
+{
+    return 1.0;
+}
+
+void QGstreamerFocus::zoomTo(qreal optical, qreal digital)
+{
+    Q_UNUSED(optical);
+    Q_UNUSED(digital);
+}
+QCameraFocus::FocusPointMode QGstreamerFocus::focusPointMode() const
+{
+    return QCameraFocus::FocusPointAuto;
+}
+void QGstreamerFocus::setFocusPointMode(QCameraFocus::FocusPointMode mode)
+{
+    Q_UNUSED(mode);
+}
+
+bool QGstreamerFocus::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const
+{
+    Q_UNUSED(mode);
+    return false;
+}
+
+QPointF QGstreamerFocus::customFocusPoint() const
+{
+    return QPointF(0.5, 0.5);
+}
+
+void QGstreamerFocus::setCustomFocusPoint(const QPointF &point)
+{
+    Q_UNUSED(point);
+}
+
+QCameraFocusZoneList QGstreamerFocus::focusZones() const
+{
+    return QCameraFocusZoneList();
+}
+#endif
--- /dev/null
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerfocus.h
@@ -0,0 +1,39 @@
+#ifndef QGSTREAMERFOCUS_H
+#define QGSTREAMERFOCUS_H
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+
+#include <gst/gst.h>
+#include <qcamerafocuscontrol.h>
+
+class QGstreamerCaptureSession;
+class QGstreamerFocus : public QCameraFocusControl
+{
+public:
+    QGstreamerFocus(QGstreamerCaptureSession *session);
+
+    virtual QCameraFocus::FocusMode focusMode() const;
+    virtual void setFocusMode(QCameraFocus::FocusMode mode);
+    virtual bool isFocusModeSupported(QCameraFocus::FocusMode mode) const;
+
+    virtual qreal maximumOpticalZoom() const;
+    virtual qreal maximumDigitalZoom() const;
+    virtual qreal opticalZoom() const;
+    virtual qreal digitalZoom() const;
+
+    virtual void zoomTo(qreal optical, qreal digital);
+
+    virtual QCameraFocus::FocusPointMode focusPointMode() const;
+    virtual void setFocusPointMode(QCameraFocus::FocusPointMode mode);
+    virtual bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const;
+    virtual QPointF customFocusPoint() const;
+    virtual void setCustomFocusPoint(const QPointF &point);
+
+    virtual QCameraFocusZoneList focusZones() const;
+private:
+    QGstreamerCaptureSession *m_session;
+    QCameraFocus::FocusMode m_focusMode;
+};
+#endif
+
+#endif
--- /dev/null
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerimageprocessing.cpp
@@ -0,0 +1,50 @@
+#include "qgstreamerimageprocessing.h"
+#include "qgstreamercapturesession.h"
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+
+QGstreamerImageProcessing::QGstreamerImageProcessing(QGstreamerCaptureSession *session)
+{
+    m_session = session;
+    m_whiteBalanceMode = QCameraImageProcessing::WhiteBalanceAuto;
+}
+
+QCameraImageProcessing::WhiteBalanceMode QGstreamerImageProcessing::whiteBalanceMode() const
+{
+    return m_whiteBalanceMode;
+}
+
+void QGstreamerImageProcessing::setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode)
+{
+    if(isWhiteBalanceModeSupported(mode))
+    {
+        m_whiteBalanceMode = mode;
+	if(m_session->isMoorestown() && m_session->getVideoSource())
+	{
+        	g_object_set(G_OBJECT(m_session->getVideoSource()), "awb-on", m_whiteBalanceMode == QCameraImageProcessing::WhiteBalanceAuto, NULL);
+	}
+    }
+}
+
+bool QGstreamerImageProcessing::isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const
+{
+    return  mode == QCameraImageProcessing::WhiteBalanceAuto || mode == QCameraImageProcessing::WhiteBalanceManual;
+}
+
+bool QGstreamerImageProcessing::isProcessingParameterSupported(ProcessingParameter) const
+{
+    return false;
+}
+
+QVariant QGstreamerImageProcessing::processingParameter(ProcessingParameter parameter) const
+{
+    Q_UNUSED(parameter);
+    return QVariant();
+}
+
+void QGstreamerImageProcessing::setProcessingParameter(ProcessingParameter parameter, QVariant value)
+{
+    Q_UNUSED(parameter);
+    Q_UNUSED(value);
+}
+#endif
--- /dev/null
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerimageprocessing.h
@@ -0,0 +1,28 @@
+#ifndef QGSTREAMERIMAGEPROCESSING_H
+#define QGSTREAMERIMAGEPROCESSING_H 
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+
+#include <gst/gst.h>
+#include <qcameraimageprocessingcontrol.h>
+
+class QGstreamerCaptureSession;
+class QGstreamerImageProcessing : public QCameraImageProcessingControl
+{
+public:
+    QGstreamerImageProcessing(QGstreamerCaptureSession *session);
+
+    virtual QCameraImageProcessing::WhiteBalanceMode whiteBalanceMode() const;
+    virtual void setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode);
+    virtual bool isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const;
+
+    virtual bool isProcessingParameterSupported(ProcessingParameter) const;
+    virtual QVariant processingParameter(ProcessingParameter parameter) const;
+    virtual void setProcessingParameter(ProcessingParameter parameter, QVariant value);
+private:
+    QGstreamerCaptureSession *m_session;
+    QCameraImageProcessing::WhiteBalanceMode m_whiteBalanceMode;
+};
+#endif
+
+#endif
--- /dev/null
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerlocks.cpp
@@ -0,0 +1,47 @@
+#include "qgstreamerlocks.h"
+#include "qgstreamercapturesession.h"
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+
+QGstreamerLocks::QGstreamerLocks(QGstreamerCaptureSession *session)
+{
+    m_session = session;
+    m_focusStatus = QCamera::Unlocked;
+}
+
+QCamera::LockTypes QGstreamerLocks::supportedLocks() const
+{
+    return QCamera::LockFocus;
+}
+
+QCamera::LockStatus QGstreamerLocks::lockStatus(QCamera::LockType lock) const
+{
+    return (lock == QCamera::LockFocus) ? m_focusStatus : QCamera::Unlocked;
+}
+
+void QGstreamerLocks::searchAndLock(QCamera::LockTypes locks)
+{
+    if ((locks & QCamera::LockFocus) && (m_focusStatus == QCamera::Unlocked))
+    {
+        m_focusStatus = QCamera::Locked;
+	if(m_session->isMoorestown() && m_session->getVideoSource())
+	{
+        	g_object_set(G_OBJECT(m_session->getVideoSource()), "half-pressed", true, NULL);
+	}
+        emit lockStatusChanged(QCamera::LockFocus, m_focusStatus, QCamera::LockAcquired);
+    }
+}
+
+void QGstreamerLocks::unlock(QCamera::LockTypes locks)
+{
+    if ((locks & QCamera::LockFocus) && (m_focusStatus == QCamera::Locked))
+    {
+        m_focusStatus = QCamera::Unlocked;
+	if(m_session->isMoorestown() && m_session->getVideoSource())
+	{
+        	g_object_set(G_OBJECT(m_session->getVideoSource()), "half-pressed", false, NULL);
+	}
+        emit lockStatusChanged(QCamera::LockFocus, m_focusStatus, QCamera::UserRequest);
+    }
+}
+#endif
--- /dev/null
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerlocks.h
@@ -0,0 +1,27 @@
+#ifndef QGSTREAMERLOCKS_H
+#define QGSTREAMERLOCKS_H
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+
+#include <gst/gst.h>
+#include <qcameralockscontrol.h>
+
+class QGstreamerCaptureSession;
+class QGstreamerLocks : public QCameraLocksControl
+{
+public:
+    QGstreamerLocks(QGstreamerCaptureSession *session);
+
+    virtual QCamera::LockTypes supportedLocks() const;
+
+    virtual QCamera::LockStatus lockStatus(QCamera::LockType lock) const;
+
+    virtual void searchAndLock(QCamera::LockTypes locks);
+    virtual void unlock(QCamera::LockTypes locks);
+private:
+    QGstreamerCaptureSession *m_session;
+    QCamera::LockStatus m_focusStatus;
+};
+#endif
+
+#endif
--- a/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacontainercontrol.cpp
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacontainercontrol.cpp
@@ -48,6 +48,9 @@ QGstreamerMediaContainerControl::QGstreamerMediaContainerControl(QObject *parent
     :QMediaContainerControl(parent)
 {
     QList<QByteArray> formatCandidates;
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    formatCandidates << "mp4";
+#endif
     formatCandidates << "matroska" << "ogg" << "mp4" << "wav" << "quicktime" << "avi" << "3gpp";
     formatCandidates << "flv" << "amr" << "asf" << "dv" << "gif";
     formatCandidates << "mpeg" << "vob" << "mpegts" << "3g2" << "3gp";
@@ -55,7 +58,11 @@ QGstreamerMediaContainerControl::QGstreamerMediaContainerControl(QObject *parent
 
     m_elementNames["matroska"] = "matroskamux";
     m_elementNames["ogg"] = "oggmux";
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    m_elementNames["mp4"] = "qtmux";
+#else
     m_elementNames["mp4"] = "ffmux_mp4";
+#endif
     m_elementNames["quicktime"] = "ffmux_mov";
     m_elementNames["avi"] = "avimux";
     m_elementNames["3gpp"] = "gppmux";
--- a/plugins/multimedia/gstreamer/mediacapture/qgstreamerv4l2input.cpp
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerv4l2input.cpp
@@ -74,8 +74,64 @@ QGstreamerV4L2Input::~QGstreamerV4L2Input()
 {
 }
 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+void QGstreamerV4L2Input::setFlip(bool horizontalFlip, bool verticalFlip)
+{
+    QFile f(m_device);
+
+    GstElementFactory * mrstcamsrc =  gst_element_factory_find ("mrstcamsrc");
+    if(mrstcamsrc)
+    {
+        //Moorestown uses only one device node
+        f.setFileName("/dev/video0");
+        gst_object_unref(GST_OBJECT(mrstcamsrc));
+    }
+
+    if (!f.open(QFile::ReadOnly))
+    {
+       return;
+    }
+
+    int fd = f.handle();
+    struct v4l2_control ctrl;
+
+    ctrl.id = V4L2_CID_HFLIP;
+    ctrl.value = horizontalFlip;
+    ::ioctl(fd, VIDIOC_S_CTRL, &ctrl);
+
+
+    ctrl.id = V4L2_CID_VFLIP;
+    ctrl.value = verticalFlip;
+    ::ioctl(fd, VIDIOC_S_CTRL, &ctrl);
+}
+#endif
+
 GstElement *QGstreamerV4L2Input::buildElement()
 {
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    GstElement *mrstcamsrc = gst_element_factory_make("mrstcamsrc", "camera_source");
+    if(mrstcamsrc)
+    {
+        int sensor_id = m_device.at(QString("/dev/video").size()) - '0';
+
+        g_object_set(G_OBJECT(mrstcamsrc), "ae-on", true, NULL);
+        g_object_set(G_OBJECT(mrstcamsrc), "af-on", true, NULL);
+        g_object_set(G_OBJECT(mrstcamsrc), "awb-on", true, NULL);
+        g_object_set(G_OBJECT(mrstcamsrc), "sensor-num", sensor_id, NULL);
+
+        if(sensor_id == 0)
+        {
+            setFlip(1, 0); //horizontally flip main camera
+        }
+        else
+        {
+            setFlip(0, 0); //no flipping for user-facing camera
+        }
+
+        return mrstcamsrc;
+    }
+#endif
+
 #ifndef Q_WS_MAEMO_5
     GstElement *camera = gst_element_factory_make("v4l2src", "camera_source");
 #else
@@ -111,11 +167,31 @@ void QGstreamerV4L2Input::updateSupportedResolutions(const QByteArray &device)
 
     QFile f(device);
 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    bool isMoorestown = false;
+    GstElementFactory * mrstcamsrc =  gst_element_factory_find ("mrstcamsrc");
+    if(mrstcamsrc)
+    {
+        //Moorestown uses only one device node
+        f.setFileName("/dev/video0");
+        isMoorestown = true;
+        gst_object_unref(GST_OBJECT(mrstcamsrc));
+    }
+#endif
+
     if (!f.open(QFile::ReadOnly))
         return;
 
     int fd = f.handle();
 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    if(isMoorestown)
+    {
+        int sensor_id = device.at(QString("/dev/video").size()) - '0';
+        ::ioctl(fd, VIDIOC_S_INPUT, &sensor_id);
+    }
+#endif
+
     //get the list of formats:
     QList<quint32> supportedFormats;
 
--- a/plugins/multimedia/gstreamer/mediacapture/qgstreamerv4l2input.h
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamerv4l2input.h
@@ -63,12 +63,16 @@ public:
     QList<qreal> supportedFrameRates(const QSize &frameSize = QSize()) const;
     QList<QSize> supportedResolutions(qreal frameRate = -1) const;
 
-    QByteArray device() const;
+    QByteArray device() const {return m_device;}
 
 public slots:
     void setDevice(const QByteArray &device);
     void setDevice(const QString &device);
 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    void setFlip(bool horizontalFlip, bool verticalFlip);
+#endif
+
 private:
     void updateSupportedResolutions(const QByteArray &device);
 
--- a/plugins/multimedia/gstreamer/mediacapture/qgstreamervideoencode.cpp
+++ b/plugins/multimedia/gstreamer/mediacapture/qgstreamervideoencode.cpp
@@ -51,21 +51,36 @@ QGstreamerVideoEncode::QGstreamerVideoEncode(QGstreamerCaptureSession *session)
     :QVideoEncoderControl(session), m_session(session)
 {
     QList<QByteArray> codecCandidates;
-    codecCandidates << "video/h264" << "video/xvid" << "video/mpeg4" << "video/mpeg1" << "video/mpeg2" << "video/theora";
-
-    m_elementNames["video/h264"] = "x264enc";
-    m_elementNames["video/xvid"] = "xvidenc";
-    m_elementNames["video/mpeg4"] = "ffenc_mpeg4";
-    m_elementNames["video/mpeg1"] = "ffenc_mpeg1video";
-    m_elementNames["video/mpeg2"] = "ffenc_mpeg2video";
-    m_elementNames["video/theora"] = "theoraenc";
-
-    m_codecOptions["video/h264"] = QStringList() << "quantizer";
-    m_codecOptions["video/xvid"] = QStringList() << "quantizer" << "profile";
-    m_codecOptions["video/mpeg4"] = QStringList() << "quantizer";
-    m_codecOptions["video/mpeg1"] = QStringList() << "quantizer";
-    m_codecOptions["video/mpeg2"] = QStringList() << "quantizer";
-    m_codecOptions["video/theora"] = QStringList();
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    GstElementFactory * mixvideo =  gst_element_factory_find ("MixVideoEncoderPreview");
+    if(mixvideo)
+    {
+        gst_object_unref(GST_OBJECT(mixvideo));
+        codecCandidates << "video/x-h264" << "video/x-h263" << "video/mpeg";
+        m_elementNames["video/x-h264"] = "MixVideoEncoderH264";
+        m_elementNames["video/x-h263"] = "MixVideoEncoderH263";
+        m_elementNames["video/mpeg"] = "MixVideoEncoderMPEG4";
+    }
+    else
+#endif
+    {
+		codecCandidates << "video/h264" << "video/xvid" << "video/mpeg4" << "video/mpeg1" << "video/mpeg2" << "video/theora";
+
+		m_elementNames["video/h264"] = "x264enc";
+		m_elementNames["video/xvid"] = "xvidenc";
+		m_elementNames["video/mpeg4"] = "ffenc_mpeg4";
+		m_elementNames["video/mpeg1"] = "ffenc_mpeg1video";
+		m_elementNames["video/mpeg2"] = "ffenc_mpeg2video";
+		m_elementNames["video/theora"] = "theoraenc";
+
+		m_codecOptions["video/h264"] = QStringList() << "quantizer";
+		m_codecOptions["video/xvid"] = QStringList() << "quantizer" << "profile";
+		m_codecOptions["video/mpeg4"] = QStringList() << "quantizer";
+		m_codecOptions["video/mpeg1"] = QStringList() << "quantizer";
+		m_codecOptions["video/mpeg2"] = QStringList() << "quantizer";
+		m_codecOptions["video/theora"] = QStringList();
+    }
 
     foreach( const QByteArray& codecName, codecCandidates ) {
         QByteArray elementName = m_elementNames[codecName];
@@ -144,6 +159,84 @@ void QGstreamerVideoEncode::setVideoSettings(const QVideoEncoderSettings &settin
 
 GstElement *QGstreamerVideoEncode::createEncoder()
 {
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    if(m_videoSettings.codec() == QLatin1String("video/x-h264"))
+    {
+        GstElement *mixEncoder = gst_element_factory_make("MixVideoEncoderH264", "video-encoder");
+        if(mixEncoder)
+        {
+            if (m_videoSettings.encodingMode() == QtMultimediaKit::ConstantQualityEncoding) {
+                QtMultimediaKit::EncodingQuality qualityValue = m_videoSettings.quality();
+                int qualityTable[] = {
+                    50, //VeryLow
+                    37, //Low
+                    24, //Normal
+                    16, //High
+                    8 //VeryHigh
+                };
+                g_object_set(G_OBJECT(mixEncoder), "init-qp", qualityTable[qualityValue], NULL);
+
+            } else {
+                int bitrate = m_videoSettings.bitRate();
+                if (bitrate > 0) {
+                    g_object_set(G_OBJECT(mixEncoder), "bit-rate", bitrate, NULL);
+                }
+            }
+            return mixEncoder;
+        }
+
+    }
+    else if(m_videoSettings.codec() == QLatin1String("video/mpeg"))
+    {
+        GstElement *mixEncoder = gst_element_factory_make("MixVideoEncoderMPEG4", "video-encoder");
+        if(mixEncoder)
+        {
+            if (m_videoSettings.encodingMode() == QtMultimediaKit::ConstantQualityEncoding) {
+                QtMultimediaKit::EncodingQuality qualityValue = m_videoSettings.quality();
+                int qualityTable[] = {
+                    30, //VeryLow
+                    18, //Low
+                    6, //Normal
+                    4, //High
+                    2 //VeryHigh
+                };
+                g_object_set(G_OBJECT(mixEncoder), "init-qp", qualityTable[qualityValue], NULL);
+
+            } else {
+                int bitrate = m_videoSettings.bitRate();
+                if (bitrate > 0) {
+                    g_object_set(G_OBJECT(mixEncoder), "bit-rate", bitrate, NULL);
+                }
+            }
+            return mixEncoder;
+        }
+
+    }
+    else if(m_videoSettings.codec() == QLatin1String("video/x-h263"))
+    {
+        GstElement *mixEncoder = gst_element_factory_make("MixVideoEncoderH263", "video-encoder");
+        if(mixEncoder)
+        {
+            if (m_videoSettings.encodingMode() == QtMultimediaKit::ConstantQualityEncoding) {
+                QtMultimediaKit::EncodingQuality qualityValue = m_videoSettings.quality();
+                int qualityTable[] = {
+                    31, //VeryLow
+                    23, //Low
+                    15, //Normal
+                    9, //High
+                    3 //VeryHigh
+                };
+                g_object_set(G_OBJECT(mixEncoder), "init-qp", qualityTable[qualityValue], NULL);
+            } else {
+                int bitrate = m_videoSettings.bitRate();
+                if (bitrate > 0) {
+                    g_object_set(G_OBJECT(mixEncoder), "bit-rate", bitrate, NULL);
+                }
+            }
+            return mixEncoder;
+        }
+    }
+#endif
     QString codec = m_videoSettings.codec();
     //qDebug() << "create encoder for video codec" << codec;
     GstElement *encoderElement = gst_element_factory_make( m_elementNames.value(codec).constData(), "video-encoder");
--- a/plugins/multimedia/gstreamer/qgstreamerserviceplugin.cpp
+++ b/plugins/multimedia/gstreamer/qgstreamerserviceplugin.cpp
@@ -195,6 +195,10 @@ void QGstreamerServicePlugin::updateDevices() const
 
     QFileInfoList entries = devDir.entryInfoList(QStringList() << "video*");
 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    int cameraCount = 0;
+#endif
+
     foreach( const QFileInfo &entryInfo, entries ) {
         //qDebug() << "Try" << entryInfo.filePath();
 
@@ -206,6 +210,18 @@ void QGstreamerServicePlugin::updateDevices() const
 
         v4l2_input input;
         memset(&input, 0, sizeof(input));
+
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+        for(int i=0 ; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; input.index = ++i)
+        {
+            if(input.type == V4L2_INPUT_TYPE_CAMERA)
+            {
+                m_cameraDevices << QString("/dev/video%1").arg(cameraCount).toAscii();
+                m_cameraDescriptions << tr("Camera") + QString(" %1").arg(cameraCount);
+                cameraCount ++;
+            }
+        }
+#else
         for (; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; ++input.index) {
             if(input.type == V4L2_INPUT_TYPE_CAMERA || input.type == 0) {
                 isCamera = ::ioctl(fd, VIDIOC_S_INPUT, input.index) != 0;
@@ -228,6 +244,7 @@ void QGstreamerServicePlugin::updateDevices() const
             m_cameraDevices.append(entryInfo.filePath().toLocal8Bit());
             m_cameraDescriptions.append(name);
         }
+#endif
         ::close(fd);
     }
 }
--- a/plugins/multimedia/gstreamer/qgstreamervideoinputdevicecontrol.cpp
+++ b/plugins/multimedia/gstreamer/qgstreamervideoinputdevicecontrol.cpp
@@ -123,6 +123,10 @@ void QGstreamerVideoInputDeviceControl::update()
 
     QFileInfoList entries = devDir.entryInfoList(QStringList() << "video*");
 
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    int cameraCount = 0;
+#endif
+
     foreach( const QFileInfo &entryInfo, entries ) {
         //qDebug() << "Try" << entryInfo.filePath();
 
@@ -134,6 +138,17 @@ void QGstreamerVideoInputDeviceControl::update()
 
         v4l2_input input;
         memset(&input, 0, sizeof(input));
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+        for(int i=0 ; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; input.index = ++i)
+        {
+            if(input.type == V4L2_INPUT_TYPE_CAMERA)
+            {
+                m_names << QString("/dev/video%1").arg(cameraCount).toAscii();
+                m_descriptions << tr("Camera") + QString(" %1").arg(cameraCount);
+                cameraCount ++;
+            }
+        }
+#else
         for (; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; ++input.index) {
             if(input.type == V4L2_INPUT_TYPE_CAMERA || input.type == 0) {
                 isCamera = ::ioctl(fd, VIDIOC_S_INPUT, input.index) != 0;
@@ -156,6 +171,7 @@ void QGstreamerVideoInputDeviceControl::update()
             m_names.append(entryInfo.filePath());
             m_descriptions.append(name);
         }
+#endif
         ::close(fd);
     }
 #endif
--- a/plugins/multimedia/gstreamer/qgstreamervideowidget.cpp
+++ b/plugins/multimedia/gstreamer/qgstreamervideowidget.cpp
@@ -122,7 +122,14 @@ void QGstreamerVideoWidgetControl::createVideoWidget()
     m_widget->installEventFilter(this);
     m_windowId = m_widget->winId();
 
-    m_videoSink = gst_element_factory_make ("xvimagesink", NULL);
+#ifdef QMEDIA_GSTREAMER_CAMERA_MOORESTOWN_SUPPORT
+    m_videoSink = gst_element_factory_make ("vaimagesink", NULL);
+    if(!m_videoSink)
+#endif
+    {
+        m_videoSink = gst_element_factory_make ("xvimagesink", NULL);
+    }
+
     if (m_videoSink) {
         // Check if the xv sink is usable
         if (gst_element_set_state(m_videoSink, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) {
--- a/src/multimedia/qmediapluginloader.cpp
+++ b/src/multimedia/qmediapluginloader.cpp
@@ -176,6 +176,7 @@ QStringList QMediaPluginLoader::availablePlugins() const
 
     // Qt paths
     paths << QCoreApplication::libraryPaths();
+    paths.removeDuplicates();
 
     foreach (const QString &path, paths) {
         QDir typeDir(path + m_location);