summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWouter Huysentruit <wouter.huysentruit@dzine.be>2013-01-12 14:07:02 +0100
committerThomas McGuire <thomas.mcguire@kdab.com>2013-01-14 09:05:28 +0100
commited9b5462a5b5f224a0c80e619d4cc36fd5267670 (patch)
tree4ce0ffa77e3cfd5903cd7f1fe6b9d51cdbc21de8
parent90fb09730239214a9f945565e713d0be26f881e0 (diff)
Fix: Bug fix in determination of scanline direction
YUV and other compressed frame formats are always TopToBottom. Only for uncompressed RGB formats the sign of their height is used to indicate the scanline direction. This is a backport of change I6474783583672861eeeb538b79d14ee3d6995f59 from the qt/qtmultimedia project. Change-Id: I0d92dc7eff9e8e73e059e95d698175076120f033 Reviewed-by: Dmytro Poplavskiy <dmytro.poplavskiy@gmail.com>
-rw-r--r--plugins/multimedia/directshow/player/directshowmediatype.cpp36
-rw-r--r--plugins/multimedia/directshow/player/directshowmediatype.h3
2 files changed, 33 insertions, 6 deletions
diff --git a/plugins/multimedia/directshow/player/directshowmediatype.cpp b/plugins/multimedia/directshow/player/directshowmediatype.cpp
index 6e5b9c68f0..ad8cad9afc 100644
--- a/plugins/multimedia/directshow/player/directshowmediatype.cpp
+++ b/plugins/multimedia/directshow/player/directshowmediatype.cpp
@@ -127,9 +127,7 @@ QVideoSurfaceFormat DirectShowMediaType::formatFromType(const AM_MEDIA_TYPE &typ
if (header->AvgTimePerFrame > 0)
format.setFrameRate(10000 /header->AvgTimePerFrame);
- format.setScanLineDirection(header->bmiHeader.biHeight < 0
- ? QVideoSurfaceFormat::TopToBottom
- : QVideoSurfaceFormat::BottomToTop);
+ format.setScanLineDirection(scanLineDirection(format.pixelFormat(), header->bmiHeader));
return format;
} else if (IsEqualGUID(type.formattype, FORMAT_VideoInfo2)) {
@@ -142,9 +140,7 @@ QVideoSurfaceFormat DirectShowMediaType::formatFromType(const AM_MEDIA_TYPE &typ
if (header->AvgTimePerFrame > 0)
format.setFrameRate(10000 / header->AvgTimePerFrame);
- format.setScanLineDirection(header->bmiHeader.biHeight < 0
- ? QVideoSurfaceFormat::TopToBottom
- : QVideoSurfaceFormat::BottomToTop);
+ format.setScanLineDirection(scanLineDirection(format.pixelFormat(), header->bmiHeader));
return format;
}
@@ -183,3 +179,31 @@ int DirectShowMediaType::bytesPerLine(const QVideoSurfaceFormat &format)
return 0;
}
}
+
+QVideoSurfaceFormat::Direction DirectShowMediaType::scanLineDirection(QVideoFrame::PixelFormat pixelFormat, const BITMAPINFOHEADER &bmiHeader)
+{
+ /* MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/dd318229(v=vs.85).aspx */
+ /* For uncompressed RGB bitmaps:
+ * if biHeight is positive, the bitmap is a bottom-up DIB with the origin at the lower left corner.
+ * If biHeight is negative, the bitmap is a top-down DIB with the origin at the upper left corner.
+ *
+ * For YUV bitmaps:
+ * the bitmap is always top-down, regardless of the sign of biHeight.
+ * Decoders should offer YUV formats with postive biHeight, but for backward compatibility they should accept YUV formats with either positive or negative biHeight.
+ *
+ * For compressed formats:
+ * biHeight must be positive, regardless of image orientation.
+ */
+ switch (pixelFormat)
+ {
+ case QVideoFrame::Format_RGB32:
+ case QVideoFrame::Format_BGR24:
+ case QVideoFrame::Format_RGB565:
+ case QVideoFrame::Format_RGB555:
+ return bmiHeader.biHeight < 0
+ ? QVideoSurfaceFormat::TopToBottom
+ : QVideoSurfaceFormat::BottomToTop;
+ default:
+ return QVideoSurfaceFormat::TopToBottom;
+ }
+}
diff --git a/plugins/multimedia/directshow/player/directshowmediatype.h b/plugins/multimedia/directshow/player/directshowmediatype.h
index a6d328817d..d48c3edfc2 100644
--- a/plugins/multimedia/directshow/player/directshowmediatype.h
+++ b/plugins/multimedia/directshow/player/directshowmediatype.h
@@ -69,6 +69,9 @@ public:
static QVideoSurfaceFormat formatFromType(const AM_MEDIA_TYPE &type);
static int bytesPerLine(const QVideoSurfaceFormat &format);
+
+private:
+ static QVideoSurfaceFormat::Direction scanLineDirection(QVideoFrame::PixelFormat pixelFormat, const BITMAPINFOHEADER &bmiHeader);
};
#endif