From da55ada028bc3c7e573e9997c1b2202f361fa571 Mon Sep 17 00:00:00 2001 From: Wouter Huysentruit Date: Fri, 11 Jan 2013 11:21:35 +0100 Subject: [PATCH] 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. Change-Id: I6474783583672861eeeb538b79d14ee3d6995f59 Reviewed-by: Dmytro Poplavskiy --- .../directshow/player/directshowmediatype.cpp | 36 ++++++++++++++++++---- .../directshow/player/directshowmediatype.h | 3 ++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/plugins/directshow/player/directshowmediatype.cpp b/src/plugins/directshow/player/directshowmediatype.cpp index b64e47c..7b3a3bc 100644 --- a/src/plugins/directshow/player/directshowmediatype.cpp +++ b/src/plugins/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/src/plugins/directshow/player/directshowmediatype.h b/src/plugins/directshow/player/directshowmediatype.h index 378c163..3808d1c 100644 --- a/src/plugins/directshow/player/directshowmediatype.h +++ b/src/plugins/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 -- 2.7.4