Don't mirror the image from the camera unless it has been flipped
authorAndy Shaw <andy.shaw@digia.com>
Fri, 31 Jan 2014 07:23:47 +0000 (08:23 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 3 Feb 2014 15:54:28 +0000 (16:54 +0100)
The camera itself can have a mode set that causes the image to be flipped
so instead of always mirroring the image that is taken from the camera we
check for the supported modes first and then check the mode and only
mirror if it is set. Otherwise we assume that it does not need
horizontally flipping but that it needs vertically flipping which seems to
be the standard for cameras on Windows.

[ChangeLog][QtMultimedia][Windows] Fixed the incorrect mirroring of the
image from the camera
Task-number: QTBUG-30365

Change-Id: I166b1f354e8d91c9a6c64f64164d782b52df98d8
Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
src/plugins/directshow/camera/dscamerasession.cpp
src/plugins/directshow/camera/dscamerasession.h

index cc1594f..801367f 100644 (file)
@@ -173,6 +173,8 @@ public:
 DSCameraSession::DSCameraSession(QObject *parent)
     : QObject(parent)
       ,m_currentImageId(0)
+    , needsHorizontalMirroring(false)
+    , needsVerticalMirroring(true)
 {
     pBuild = NULL;
     pGraph = NULL;
@@ -581,7 +583,7 @@ void DSCameraSession::captureFrame()
             mutex.lock();
 
             image = QImage(frames.at(0)->buffer,m_windowSize.width(),m_windowSize.height(),
-                    QImage::Format_RGB888).rgbSwapped().mirrored(true);
+                    QImage::Format_RGB888).rgbSwapped().mirrored(needsHorizontalMirroring, needsVerticalMirroring);
 
             QVideoFrame frame(image);
             frame.setStartTime(frames.at(0)->time);
@@ -595,7 +597,7 @@ void DSCameraSession::captureFrame()
             mutex.lock();
 
             image = QImage(frames.at(0)->buffer,m_windowSize.width(),m_windowSize.height(),
-                    QImage::Format_RGB32).mirrored(true);
+                    QImage::Format_RGB32).mirrored(needsHorizontalMirroring, needsVerticalMirroring);
 
             QVideoFrame frame(image);
             frame.setStartTime(frames.at(0)->time);
@@ -805,7 +807,39 @@ void DSCameraSession::updateProperties()
 
     types.clear();
     resolutions.clear();
-
+    IAMVideoControl *pVideoControl = 0;
+    hr = pBuild->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,pCap,
+                               IID_IAMVideoControl, (void**)&pVideoControl);
+    if (FAILED(hr)) {
+        qWarning() << "Failed to get the video control";
+    } else {
+        IPin *pPin = 0;
+        if (pCap) {
+            hr = getPin(pCap, PINDIR_OUTPUT, &pPin);
+            if (FAILED(hr)) {
+                qWarning() << "Failed to get the pin for the video control";
+            } else {
+                long supportedModes;
+                hr = pVideoControl->GetCaps(pPin, &supportedModes);
+                if (FAILED(hr)) {
+                    qWarning() << "Failed to get the supported modes of the video control";
+                } else if (supportedModes & VideoControlFlag_FlipHorizontal || supportedModes & VideoControlFlag_FlipVertical) {
+                    long mode;
+                    hr = pVideoControl->GetMode(pPin, &mode);
+                    if (FAILED(hr)) {
+                        qWarning() << "Failed to get the mode of the video control";
+                    } else {
+                        if (supportedModes & VideoControlFlag_FlipHorizontal)
+                            needsHorizontalMirroring = (mode & VideoControlFlag_FlipHorizontal);
+                        if (supportedModes & VideoControlFlag_FlipVertical)
+                            needsVerticalMirroring = (mode & VideoControlFlag_FlipVertical);
+                    }
+                }
+                pPin->Release();
+            }
+        }
+        pVideoControl->Release();
+    }
     for (int iIndex = 0; iIndex < iCount; iIndex++) {
         hr = pConfig->GetStreamCaps(iIndex, &pmt, reinterpret_cast<BYTE*>(&scc));
         if (hr == S_OK) {
index e78358a..0fe12de 100644 (file)
@@ -188,6 +188,8 @@ private:
 
     QString m_snapshot;
     int m_currentImageId;
+    bool needsHorizontalMirroring;
+    bool needsVerticalMirroring;
 protected:
     HRESULT getPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin);
     bool createFilterGraph();