From 404b7dbe3fce3881990fc5a1bd908c72750f6ad9 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Wed, 19 Dec 2012 00:11:29 +0800 Subject: [PATCH 01/17] Example: Notify user of errors Before, the widget simply failed silently, which gave the impression that the widget is broken. Change-Id: I8ab7ed0e0a62f9643791b6f4732f7f3b2cd7521a Reviewed-by: Martin Smith --- .../multimediawidgets/videowidget/videoplayer.cpp | 15 ++++++++++++++- .../multimediawidgets/videowidget/videoplayer.h | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/examples/multimediawidgets/videowidget/videoplayer.cpp b/examples/multimediawidgets/videowidget/videoplayer.cpp index d961a63f..4083543e 100644 --- a/examples/multimediawidgets/videowidget/videoplayer.cpp +++ b/examples/multimediawidgets/videowidget/videoplayer.cpp @@ -49,6 +49,7 @@ VideoPlayer::VideoPlayer(QWidget *parent) , mediaPlayer(0, QMediaPlayer::VideoSurface) , playButton(0) , positionSlider(0) + , errorLabel(0) { QVideoWidget *videoWidget = new QVideoWidget; @@ -68,6 +69,9 @@ VideoPlayer::VideoPlayer(QWidget *parent) connect(positionSlider, SIGNAL(sliderMoved(int)), this, SLOT(setPosition(int))); + errorLabel = new QLabel; + errorLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); + QBoxLayout *controlLayout = new QHBoxLayout; controlLayout->setMargin(0); controlLayout->addWidget(openButton); @@ -77,6 +81,7 @@ VideoPlayer::VideoPlayer(QWidget *parent) QBoxLayout *layout = new QVBoxLayout; layout->addWidget(videoWidget); layout->addLayout(controlLayout); + layout->addWidget(errorLabel); setLayout(layout); @@ -85,6 +90,7 @@ VideoPlayer::VideoPlayer(QWidget *parent) this, SLOT(mediaStateChanged(QMediaPlayer::State))); connect(&mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); connect(&mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64))); + connect(&mediaPlayer, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(handleError())); } VideoPlayer::~VideoPlayer() @@ -93,11 +99,12 @@ VideoPlayer::~VideoPlayer() void VideoPlayer::openFile() { + errorLabel->setText(""); + QString fileName = QFileDialog::getOpenFileName(this, tr("Open Movie"),QDir::homePath()); if (!fileName.isEmpty()) { mediaPlayer.setMedia(QUrl::fromLocalFile(fileName)); - playButton->setEnabled(true); } } @@ -140,3 +147,9 @@ void VideoPlayer::setPosition(int position) { mediaPlayer.setPosition(position); } + +void VideoPlayer::handleError() +{ + playButton->setEnabled(false); + errorLabel->setText("Error: " + mediaPlayer.errorString()); +} diff --git a/examples/multimediawidgets/videowidget/videoplayer.h b/examples/multimediawidgets/videowidget/videoplayer.h index ddad1872..0bd720bf 100644 --- a/examples/multimediawidgets/videowidget/videoplayer.h +++ b/examples/multimediawidgets/videowidget/videoplayer.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE class QAbstractButton; class QSlider; +class QLabel; QT_END_NAMESPACE class VideoPlayer : public QWidget @@ -67,11 +68,13 @@ private slots: void positionChanged(qint64 position); void durationChanged(qint64 duration); void setPosition(int position); + void handleError(); private: QMediaPlayer mediaPlayer; QAbstractButton *playButton; QSlider *positionSlider; + QLabel *errorLabel; }; #endif From 5739d43eef89e415974ca64fb348371f9f8659c7 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 20 Dec 2012 11:49:20 +0200 Subject: [PATCH 02/17] Add qmake generated files to .gitignore. Add source files generated by qmake for automatic static plugin imports to .gitignore. Change-Id: I38977c5d410e1dc9f424de39c88a9fcd281d1e69 Reviewed-by: Oswald Buddenhagen --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 3c1e1d30..464f1814 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,6 @@ src/multimediawidgets/qtmultimediawidgetsversion.h tst_* !tst_*.cpp tests/auto/cmake/build + +# Generated static plugin import sources +*_plugin_import.cpp From 416168db8a9bb54614117469a43f751a401de854 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 18 Dec 2012 15:11:44 +0100 Subject: [PATCH 03/17] Polish and fix qmlvideofx example Change-Id: I30f6d7d2af784ba018a659a16aceb4876a4b1be6 Reviewed-by: hjk --- examples/multimedia/video/qmlvideo/main.cpp | 6 +-- .../video/qmlvideofx/filereader.cpp | 30 +++---------- .../multimedia/video/qmlvideofx/filereader.h | 2 +- examples/multimedia/video/qmlvideofx/main.cpp | 8 ++-- .../qmlvideofx/qml/qmlvideofx/Effect.qml | 2 +- .../qml/qmlvideofx/EffectBillboard.qml | 2 +- .../qml/qmlvideofx/EffectBlackAndWhite.qml | 2 +- .../qml/qmlvideofx/EffectEmboss.qml | 2 +- .../qml/qmlvideofx/EffectGaussianBlur.qml | 4 +- .../qmlvideofx/qml/qmlvideofx/EffectGlow.qml | 2 +- .../qml/qmlvideofx/EffectIsolate.qml | 2 +- .../qml/qmlvideofx/EffectMagnify.qml | 2 +- .../qml/qmlvideofx/EffectPageCurl.qml | 2 +- .../qml/qmlvideofx/EffectPixelate.qml | 2 +- .../qml/qmlvideofx/EffectPosterize.qml | 2 +- .../qml/qmlvideofx/EffectRipple.qml | 2 +- .../qmlvideofx/qml/qmlvideofx/EffectSepia.qml | 2 +- .../qml/qmlvideofx/EffectSharpen.qml | 2 +- .../qml/qmlvideofx/EffectShockwave.qml | 2 +- .../qmlvideofx/EffectSobelEdgeDetection1.qml | 2 +- .../qmlvideofx/EffectSobelEdgeDetection2.qml | 2 +- .../qml/qmlvideofx/EffectTiltShift.qml | 2 +- .../qmlvideofx/qml/qmlvideofx/EffectToon.qml | 2 +- .../qml/qmlvideofx/EffectVignette.qml | 2 +- .../qml/qmlvideofx/EffectWarhol.qml | 2 +- .../qml/qmlvideofx/EffectWobble.qml | 2 +- .../video/qmlvideofx/qmlvideofx.pro | 10 ++--- .../video/qmlvideofx/qmlvideofx.qrc | 23 ++++++++++ examples/multimedia/video/qmlvideofx/trace.h | 12 ++--- .../frequencymonitor/frequencymonitor.cpp | 26 +++++------ .../frequencymonitor/frequencymonitor.h | 7 +-- .../performancemonitor/performancemonitor.cpp | 44 +++++++++---------- .../performancemonitor/performancemonitor.h | 31 +++++++------ 33 files changed, 122 insertions(+), 123 deletions(-) diff --git a/examples/multimedia/video/qmlvideo/main.cpp b/examples/multimedia/video/qmlvideo/main.cpp index 8230e944..ac26c983 100644 --- a/examples/multimedia/video/qmlvideo/main.cpp +++ b/examples/multimedia/video/qmlvideo/main.cpp @@ -69,8 +69,8 @@ int main(int argc, char *argv[]) QStringList args = app.arguments(); PerformanceMonitor::State performanceMonitorState; bool sourceIsUrl = false; - for (int i=1; i -#include -#include -#include -#include -QString adjustPath(const QString &path) -{ -#ifdef Q_OS_UNIX -#ifdef Q_OS_MAC - if (!QDir::isAbsolutePath(path)) - return QCoreApplication::applicationDirPath() - + QLatin1String("/../Resources/") + path; -#else - QString pathInInstallDir; - const QString applicationDirPath = QCoreApplication::applicationDirPath(); - pathInInstallDir = QString::fromLatin1("%1/../%2").arg(applicationDirPath, path); - - if (QFileInfo(pathInInstallDir).exists()) - return pathInInstallDir; -#endif -#endif - return path; -} +#include +#include +#include +#include +#include QString FileReader::readFile(const QString &fileName) { qtTrace() << "FileReader::readFile" << "fileName" << fileName; QString content; - QFile file(adjustPath(fileName)); + QFile file(fileName); if (file.open(QIODevice::ReadOnly)) { QTextStream stream(&file); content = stream.readAll(); diff --git a/examples/multimedia/video/qmlvideofx/filereader.h b/examples/multimedia/video/qmlvideofx/filereader.h index 44393b1c..443a2a2f 100644 --- a/examples/multimedia/video/qmlvideofx/filereader.h +++ b/examples/multimedia/video/qmlvideofx/filereader.h @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include +#include class FileReader : public QObject { diff --git a/examples/multimedia/video/qmlvideofx/main.cpp b/examples/multimedia/video/qmlvideofx/main.cpp index 9f47a9c1..056c274e 100644 --- a/examples/multimedia/video/qmlvideofx/main.cpp +++ b/examples/multimedia/video/qmlvideofx/main.cpp @@ -72,17 +72,17 @@ int main(int argc, char *argv[]) #ifdef PERFORMANCEMONITOR_SUPPORT PerformanceMonitor::State performanceMonitorState; #endif - for (int i=1; iqml/qmlvideofx/main-smallscreen.qml qml/qmlvideofx/ParameterPanel.qml qml/qmlvideofx/Slider.qml + shaders/billboard.fsh + shaders/blackandwhite.fsh + shaders/emboss.fsh + shaders/gaussianblur_h.fsh + shaders/gaussianblur_v.fsh + shaders/glow.fsh + shaders/isolate.fsh + shaders/magnify.fsh + shaders/pagecurl.fsh + shaders/pixelate.fsh + shaders/posterize.fsh + shaders/ripple.fsh + shaders/selectionpanel.fsh + shaders/sepia.fsh + shaders/sharpen.fsh + shaders/shockwave.fsh + shaders/sobeledgedetection1.fsh + shaders/sobeledgedetection2.fsh + shaders/tiltshift.fsh + shaders/toon.fsh + shaders/vignette.fsh + shaders/warhol.fsh + shaders/wobble.fsh diff --git a/examples/multimedia/video/qmlvideofx/trace.h b/examples/multimedia/video/qmlvideofx/trace.h index 73095f59..c5332d5d 100644 --- a/examples/multimedia/video/qmlvideofx/trace.h +++ b/examples/multimedia/video/qmlvideofx/trace.h @@ -42,7 +42,7 @@ #ifndef TRACE_H #define TRACE_H -#include +#include #define ENABLE_TRACE //#define VERBOSE_TRACE @@ -53,7 +53,7 @@ class NullDebug { public: template - NullDebug& operator<<(const T&) { return *this; } + NullDebug &operator<<(const T &) { return *this; } }; inline NullDebug nullDebug() { return NullDebug(); } @@ -68,18 +68,12 @@ struct PtrWrapper } // namespace Trace template -inline QDebug& operator<<(QDebug &debug, const Trace::PtrWrapper &wrapper) +inline QDebug &operator<<(QDebug &debug, const Trace::PtrWrapper &wrapper) { debug.nospace() << "[" << (void*)wrapper.m_ptr << "]"; return debug.space(); } -template -inline const void *qtVoidPtr(const T *ptr) -{ return static_cast(ptr); } - -#define qtThisPtr() qtVoidPtr(this) - #ifdef ENABLE_TRACE inline QDebug qtTrace() { return qDebug() << "[qmlvideofx]"; } # ifdef VERBOSE_TRACE diff --git a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp index 1d44f129..568bbc79 100644 --- a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp +++ b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.cpp @@ -40,11 +40,11 @@ ****************************************************************************/ #include "frequencymonitor.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include //#define VERBOSE_TRACE @@ -61,6 +61,7 @@ static const int DefaultTraceInterval = 0; class FrequencyMonitorPrivate : public QObject { Q_OBJECT + public: FrequencyMonitorPrivate(FrequencyMonitor *parent); void calculateInstantaneousFrequency(); @@ -116,16 +117,16 @@ void FrequencyMonitorPrivate::calculateInstantaneousFrequency() m_stalledTimer->start(3 * ms); if (m_instantaneousFrequency) q_ptr->setActive(true); - q_ptr->emit instantaneousFrequencyChanged(m_instantaneousFrequency); - q_ptr->emit frequencyChanged(); + emit q_ptr->instantaneousFrequencyChanged(m_instantaneousFrequency); + emit q_ptr->frequencyChanged(); } void FrequencyMonitorPrivate::calculateAverageFrequency() { const qint64 ms = m_averageElapsed.restart(); m_averageFrequency = qreal(m_count * 1000) / ms; - q_ptr->emit averageFrequencyChanged(m_averageFrequency); - q_ptr->emit frequencyChanged(); + emit q_ptr->averageFrequencyChanged(m_averageFrequency); + emit q_ptr->frequencyChanged(); m_count = 0; } @@ -134,14 +135,13 @@ void FrequencyMonitorPrivate::stalled() if (m_instantaneousFrequency) { qtVerboseTrace() << "FrequencyMonitor::stalled"; m_instantaneousFrequency = 0; - q_ptr->emit instantaneousFrequencyChanged(m_instantaneousFrequency); - q_ptr->emit frequencyChanged(); + emit q_ptr->instantaneousFrequencyChanged(m_instantaneousFrequency); + emit q_ptr->frequencyChanged(); } } FrequencyMonitor::FrequencyMonitor(QObject *parent) : QObject(parent) -, d_ptr(0) { d_ptr = new FrequencyMonitorPrivate(this); qtTrace() << "FrequencyMonitor::FrequencyMonitor"; @@ -152,7 +152,7 @@ FrequencyMonitor::~FrequencyMonitor() } -const QString &FrequencyMonitor::label() const +QString FrequencyMonitor::label() const { return d_func()->m_label; } diff --git a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.h b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.h index 1efd8b3a..f34646f9 100644 --- a/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.h +++ b/examples/multimedia/video/snippets/frequencymonitor/frequencymonitor.h @@ -42,8 +42,8 @@ #ifndef FREQUENCYMONITOR_H #define FREQUENCYMONITOR_H -#include -#include +#include +#include class FrequencyMonitorPrivate; @@ -64,13 +64,14 @@ class FrequencyMonitor : public QObject Q_PROPERTY(int traceInterval READ traceInterval WRITE setTraceInterval NOTIFY traceIntervalChanged) Q_PROPERTY(qreal instantaneousFrequency READ instantaneousFrequency NOTIFY instantaneousFrequencyChanged) Q_PROPERTY(qreal averageFrequency READ averageFrequency NOTIFY averageFrequencyChanged) + public: FrequencyMonitor(QObject *parent = 0); ~FrequencyMonitor(); static void qmlRegisterType(); - const QString &label() const; + QString label() const; bool active() const; int samplingInterval() const; int traceInterval() const; diff --git a/examples/multimedia/video/snippets/performancemonitor/performancemonitor.cpp b/examples/multimedia/video/snippets/performancemonitor/performancemonitor.cpp index 9a7e060b..07c83485 100644 --- a/examples/multimedia/video/snippets/performancemonitor/performancemonitor.cpp +++ b/examples/multimedia/video/snippets/performancemonitor/performancemonitor.cpp @@ -43,27 +43,27 @@ namespace PerformanceMonitor { - bool parseArgument(const QString &arg, State &state) - { - bool result = false; - if ("-log-perf" == arg) { - state.logging = true; - state.valid = true; - result = true; - } else if ("-no-log-perf" == arg) { - state.logging = false; - state.valid = true; - result = true; - } else if ("-show-perf" == arg) { - state.visible = true; - state.valid = true; - result = true; - } else if ("-hide-perf" == arg) { - state.visible = false; - state.valid = true; - result = true; - } - return result; +bool State::parseArgument(const QByteArray &arg) +{ + bool result = false; + if (arg == "-log-perf") { + logging = true; + valid = true; + result = true; + } else if (arg == "-no-log-perf") { + logging = false; + valid = true; + result = true; + } else if (arg == "-show-perf") { + visible = true; + valid = true; + result = true; + } else if (arg == "-hide-perf") { + visible = false; + valid = true; + result = true; } - + return result; } + +} // namespace PerformanceMonitor diff --git a/examples/multimedia/video/snippets/performancemonitor/performancemonitor.h b/examples/multimedia/video/snippets/performancemonitor/performancemonitor.h index d87d71ea..f1a443e0 100644 --- a/examples/multimedia/video/snippets/performancemonitor/performancemonitor.h +++ b/examples/multimedia/video/snippets/performancemonitor/performancemonitor.h @@ -42,24 +42,27 @@ #ifndef PERFORMANCEMONITOR_H #define PERFORMANCEMONITOR_H -#include +#include namespace PerformanceMonitor { - struct State { - bool valid; - bool logging; - bool visible; - State() : valid(true), logging(false), visible(true) { } - State(bool l, bool v) : valid(true), logging(l), visible(v) { } - bool operator==(const State &other) const - { return logging == other.logging && visible == other.visible; } - bool operator!=(const State &other) const - { return logging != other.logging || visible != other.visible; } - }; +struct State +{ + State() : valid(true), logging(false), visible(true) { } + State(bool l, bool v) : valid(true), logging(l), visible(v) { } + bool operator==(const State &other) const + { return logging == other.logging && visible == other.visible; } + bool operator!=(const State &other) const + { return logging != other.logging || visible != other.visible; } - bool parseArgument(const QString &arg, State &state); -} + bool parseArgument(const QByteArray &arg); + + bool valid; + bool logging; + bool visible; +}; + +} // namespace PerformanceMonitor #endif // PERFORMANCEMONITOR_H From d8426bbf71d30f69b506a5e0148cafc05c79bae9 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 20 Dec 2012 16:19:59 +0100 Subject: [PATCH 04/17] WMF: Fixed incorrect QMediaPlayer volume reporting. Task-number: QTBUG-26621 Change-Id: Id70a68ad61fd7d68f4ee277f33a54bd9c00c05d0 Reviewed-by: Jason Barron --- src/plugins/wmf/player/mfplayersession.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp index 1eb91c20..d9ff0e7c 100644 --- a/src/plugins/wmf/player/mfplayersession.cpp +++ b/src/plugins/wmf/player/mfplayersession.cpp @@ -413,7 +413,7 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService) , m_hCloseEvent(0) , m_closing(false) , m_pendingRate(1) - , m_volume(1) + , m_volume(100) , m_muted(false) , m_status(QMediaPlayer::NoMedia) , m_scrubbing(false) @@ -1640,7 +1640,7 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent) } if (SUCCEEDED(MFGetService(m_session, MR_POLICY_VOLUME_SERVICE, IID_PPV_ARGS(&m_volumeControl)))) { - m_volumeControl->SetMasterVolume(m_volume); + m_volumeControl->SetMasterVolume(m_volume * 0.01f); m_volumeControl->SetMute(m_muted); } @@ -1692,9 +1692,10 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent) if (m_volumeControl) { float currentVolume = 1; if (SUCCEEDED(m_volumeControl->GetMasterVolume(¤tVolume))) { - if (currentVolume != m_volume) { - m_volume = currentVolume; - emit volumeChanged(int(m_volume * 100)); + int scaledVolume = currentVolume * 100; + if (scaledVolume != m_volume) { + m_volume = scaledVolume; + emit volumeChanged(scaledVolume); } } BOOL currentMuted = FALSE; From b0b78d200bf6d1366cad9f0152cb515e6241d4bd Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 20 Dec 2012 16:51:11 +0100 Subject: [PATCH 05/17] Use qrc to deploy qml files in declarative-camera examples Make the declarative-camera example working in shadow builds by including the Qt Quick assets via a .qrc file. Change-Id: Iea56e7d69558503abdf15a600a6ce21ea90ee99a Reviewed-by: Oswald Buddenhagen --- .../declarative-camera/declarative-camera.pro | 1 + .../declarative-camera/declarative-camera.qrc | 26 +++++++++++++++++++ .../declarative-camera/qmlcamera.cpp | 3 +-- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 examples/multimediawidgets/declarative-camera/declarative-camera.qrc diff --git a/examples/multimediawidgets/declarative-camera/declarative-camera.pro b/examples/multimediawidgets/declarative-camera/declarative-camera.pro index c52a1d1e..5fb0a1b5 100644 --- a/examples/multimediawidgets/declarative-camera/declarative-camera.pro +++ b/examples/multimediawidgets/declarative-camera/declarative-camera.pro @@ -4,6 +4,7 @@ TARGET=declarative-camera QT += quick qml multimedia SOURCES += qmlcamera.cpp +RESOURCES += declarative-camera.qrc target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/declarative-camera INSTALLS += target diff --git a/examples/multimediawidgets/declarative-camera/declarative-camera.qrc b/examples/multimediawidgets/declarative-camera/declarative-camera.qrc new file mode 100644 index 00000000..d99b86c0 --- /dev/null +++ b/examples/multimediawidgets/declarative-camera/declarative-camera.qrc @@ -0,0 +1,26 @@ + + + PhotoPreview.qml + ZoomControl.qml + VideoCaptureControls.qml + VideoPreview.qml + FocusButton.qml + PhotoCaptureControls.qml + declarative-camera.qml + CameraPropertyPopup.qml + CameraPropertyButton.qml + CameraButton.qml + images/camera_auto_mode.png + images/camera_camera_setting.png + images/camera_flash_auto.png + images/camera_flash_fill.png + images/camera_flash_off.png + images/camera_flash_redeye.png + images/camera_white_balance_cloudy.png + images/camera_white_balance_flourescent.png + images/camera_white_balance_incandescent.png + images/camera_white_balance_sunny.png + images/toolbutton.png + images/toolbutton.sci + + diff --git a/examples/multimediawidgets/declarative-camera/qmlcamera.cpp b/examples/multimediawidgets/declarative-camera/qmlcamera.cpp index 0d8dbc46..3da61565 100644 --- a/examples/multimediawidgets/declarative-camera/qmlcamera.cpp +++ b/examples/multimediawidgets/declarative-camera/qmlcamera.cpp @@ -50,8 +50,7 @@ int main(int argc, char* argv[]) // Qt.quit() called in embedded .qml by default only emits // quit() signal, so do this (optionally use Qt.exit()). QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit())); - view.setSource(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + - QLatin1String("/declarative-camera.qml"))); + view.setSource(QUrl("qrc:///declarative-camera.qml")); view.resize(800, 480); view.show(); return app.exec(); From 1e0b3d862500dbfdb4f9e4b0084cde99ef3a5a2b Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Thu, 20 Dec 2012 01:20:49 +0100 Subject: [PATCH 06/17] fix include statements Names are case sensitive when cross bulding for mingw on unix. Change-Id: I355b9388241c7c5fefb05b6f0c231efec4530c7e Reviewed-by: Michael Goddard Reviewed-by: Jonas Rabbe --- src/plugins/directshow/camera/dscameraservice.cpp | 2 +- src/plugins/directshow/camera/dsvideodevicecontrol.cpp | 2 +- src/plugins/directshow/camera/dsvideowidgetcontrol.cpp | 2 +- src/plugins/directshow/camera/dsvideowidgetcontrol.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/directshow/camera/dscameraservice.cpp b/src/plugins/directshow/camera/dscameraservice.cpp index 6d297416..fcbd1ef5 100644 --- a/src/plugins/directshow/camera/dscameraservice.cpp +++ b/src/plugins/directshow/camera/dscameraservice.cpp @@ -44,7 +44,7 @@ #if defined(HAVE_WIDGETS) #include -#include +#include #endif #include "dscameraservice.h" diff --git a/src/plugins/directshow/camera/dsvideodevicecontrol.cpp b/src/plugins/directshow/camera/dsvideodevicecontrol.cpp index 46865690..7c33d130 100644 --- a/src/plugins/directshow/camera/dsvideodevicecontrol.cpp +++ b/src/plugins/directshow/camera/dsvideodevicecontrol.cpp @@ -49,7 +49,7 @@ #include #include #include -#include +#include #include extern const CLSID CLSID_VideoInputDeviceCategory; diff --git a/src/plugins/directshow/camera/dsvideowidgetcontrol.cpp b/src/plugins/directshow/camera/dsvideowidgetcontrol.cpp index 843719b8..d7a913d7 100644 --- a/src/plugins/directshow/camera/dsvideowidgetcontrol.cpp +++ b/src/plugins/directshow/camera/dsvideowidgetcontrol.cpp @@ -42,7 +42,7 @@ #include #include -#include "DSVideoWidgetControl.h" +#include "dsvideowidgetcontrol.h" #include "dscamerasession.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/directshow/camera/dsvideowidgetcontrol.h b/src/plugins/directshow/camera/dsvideowidgetcontrol.h index ac390c82..9249c317 100644 --- a/src/plugins/directshow/camera/dsvideowidgetcontrol.h +++ b/src/plugins/directshow/camera/dsvideowidgetcontrol.h @@ -49,7 +49,7 @@ #include #include -#include "DsCameraControl.h" +#include "dscameracontrol.h" QT_BEGIN_HEADER From 47b0d553d99ba51c3ab942ee1eb7ba50c1387399 Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Sat, 22 Dec 2012 00:43:52 +0100 Subject: [PATCH 07/17] Bump Qt version to 5.0.1 Change-Id: Ic45b749ceea86263281b5c23509bf301fa334e5f Reviewed-by: Jonas Rabbe --- src/multimedia/doc/qtmultimedia.qdocconf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/multimedia/doc/qtmultimedia.qdocconf b/src/multimedia/doc/qtmultimedia.qdocconf index 08a62890..3873bd25 100644 --- a/src/multimedia/doc/qtmultimedia.qdocconf +++ b/src/multimedia/doc/qtmultimedia.qdocconf @@ -3,7 +3,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) project = qtmultimedia description = Qt Multimedia Documentation url = http://qt-project.org/doc/qtmultimedia -version = 5.0.0 +version = 5.0.1 # The following parameters are for creating a qhp file, the qhelpgenerator # program can convert the qhp file into a qch file which can be opened in From 3df5999a07cfa8e23734cb939373cd4fe46fac74 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 22 Dec 2012 14:07:36 -0800 Subject: [PATCH 08/17] Remove comma at the end of the enum Required for public header cleanliness Change-Id: I2641fd085071b2a69806e8622c7c35be74f744b1 Reviewed-by: Jonas Rabbe --- src/multimedia/audio/qsound.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/multimedia/audio/qsound.h b/src/multimedia/audio/qsound.h index cf799e5d..a4d5327e 100644 --- a/src/multimedia/audio/qsound.h +++ b/src/multimedia/audio/qsound.h @@ -57,7 +57,7 @@ class Q_MULTIMEDIA_EXPORT QSound : public QObject public: enum Loop { - Infinite = -1, + Infinite = -1 }; static void play(const QString& filename); From 85faa55780a1057b4d1929a07c253847bfdc93fd Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Wed, 19 Dec 2012 14:36:55 +0100 Subject: [PATCH 09/17] Doc: Moved the qdocinc and image to the sourcedirs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QDoc parses the \input command relative to the sourcedirs and not exampledirs. So I had to move the qdocinc file and the corresponding image to the sourcedirs. Task-number: QTBUG-28727 Change-Id: Ie064f0b79ab8ffcb0587b43ff4508f5865a321a9 Reviewed-by: Martin Smith Reviewed-by: Topi Reiniƶ Reviewed-by: Sergio Ahumada --- examples/multimedia/video/doc/src/qmlvideo.qdoc | 4 ++-- examples/multimedia/video/doc/src/qmlvideofx.qdoc | 4 ++-- .../doc/src/examples}/video-qml-paint-rate.qdocinc | 6 +++--- .../doc/src}/images/video-qml-paint-rate.png | Bin 4 files changed, 7 insertions(+), 7 deletions(-) rename {examples/multimedia/video/doc/src => src/multimedia/doc/src/examples}/video-qml-paint-rate.qdocinc (78%) rename {examples/multimedia/video/doc => src/multimedia/doc/src}/images/video-qml-paint-rate.png (100%) diff --git a/examples/multimedia/video/doc/src/qmlvideo.qdoc b/examples/multimedia/video/doc/src/qmlvideo.qdoc index 359d0715..0f4de6ce 100644 --- a/examples/multimedia/video/doc/src/qmlvideo.qdoc +++ b/examples/multimedia/video/doc/src/qmlvideo.qdoc @@ -129,13 +129,13 @@ instance, the embedded \section1 Calculating and displaying QML painting rate -\input video-qml-paint-rate.qdocinc +\input multimedia/doc/src/examples/video-qml-paint-rate.qdocinc All that remains is to connect the afterRendering() signal of the QQuickView object to a JavaScript function, which will eventually call frequencyItem.notify(): \quotefromfile multimedia/video/qmlvideo/main.cpp -\skipto QmlApplicationViewer +\skipto QGuiApplication \printuntil ; \dots \skipto QQuickItem diff --git a/examples/multimedia/video/doc/src/qmlvideofx.qdoc b/examples/multimedia/video/doc/src/qmlvideofx.qdoc index b6535a95..a3b7c01a 100644 --- a/examples/multimedia/video/doc/src/qmlvideofx.qdoc +++ b/examples/multimedia/video/doc/src/qmlvideofx.qdoc @@ -203,13 +203,13 @@ And here is the effect selection menu: \section1 Calculating and displaying QML painting rate -\input video-qml-paint-rate.qdocinc +\input multimedia/doc/src/examples/video-qml-paint-rate.qdocinc All that remains is to connect the afterRendering() signal of the QQuickView object to a JavaScript function, which will eventually call frequencyItem.notify(): \quotefromfile multimedia/video/qmlvideofx/main.cpp -\skipto QmlApplicationViewer +\skipto QGuiApplication \printuntil ; \dots \skipto QQuickItem diff --git a/examples/multimedia/video/doc/src/video-qml-paint-rate.qdocinc b/src/multimedia/doc/src/examples/video-qml-paint-rate.qdocinc similarity index 78% rename from examples/multimedia/video/doc/src/video-qml-paint-rate.qdocinc rename to src/multimedia/doc/src/examples/video-qml-paint-rate.qdocinc index 84098e24..860f1427 100644 --- a/examples/multimedia/video/doc/src/video-qml-paint-rate.qdocinc +++ b/src/multimedia/doc/src/examples/video-qml-paint-rate.qdocinc @@ -2,7 +2,7 @@ The QML painting rate is calculated by the FrequencyMonitor class, which turns a stream of events (received via the notify() slot), into an instantaneous and an averaged frequency: -\quotefromfile video/snippets/frequencymonitor/frequencymonitor.h +\quotefromfile multimedia/video/snippets/frequencymonitor/frequencymonitor.h \skipto class FrequencyMonitor : public QObject \printuntil Q_OBJECT \skipto Q_PROPERTY(qreal instantaneousFrequency @@ -19,13 +19,13 @@ instantaneous and an averaged frequency: The FrequencyMonitor class is exposed to QML like this -\quotefromfile video/snippets/frequencymonitor/frequencymonitordeclarative.cpp +\quotefromfile multimedia/video/snippets/frequencymonitor/frequencymonitordeclarative.cpp \skipto FrequencyMonitor::qmlRegisterType \printuntil } and its data is displayed by defining a QML item called FrequencyItem, like this: -\quotefromfile video/snippets/frequencymonitor/qml/frequencymonitor/FrequencyItem.qml +\quotefromfile multimedia/video/snippets/frequencymonitor/qml/frequencymonitor/FrequencyItem.qml \skipto import FrequencyMonitor \printuntil id: root \dots diff --git a/examples/multimedia/video/doc/images/video-qml-paint-rate.png b/src/multimedia/doc/src/images/video-qml-paint-rate.png similarity index 100% rename from examples/multimedia/video/doc/images/video-qml-paint-rate.png rename to src/multimedia/doc/src/images/video-qml-paint-rate.png From 6902c5d770bfa79522d4349215c0b582642c7594 Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Sat, 22 Dec 2012 17:58:23 +0100 Subject: [PATCH 10/17] Add changes-5.0.1 file Task-number: QTBUG-26065 Change-Id: If025c8cc5be1304b30e3cbc983d0a1de31224a1b Reviewed-by: Jonas Rabbe Reviewed-by: Lars Knoll --- dist/changes-5.0.1 | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 dist/changes-5.0.1 diff --git a/dist/changes-5.0.1 b/dist/changes-5.0.1 new file mode 100644 index 00000000..cc5a6704 --- /dev/null +++ b/dist/changes-5.0.1 @@ -0,0 +1,51 @@ +Qt 5.0.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.0.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://qt-project.org/doc/qt-5.0/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt-project.org/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + +**************************************************************************** +* General * +**************************************************************************** + +General Improvements +-------------------- + +Third party components +---------------------- + +**************************************************************************** +* Library * +**************************************************************************** + + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + + +**************************************************************************** +* Compiler Specific Changes * +**************************************************************************** + + +**************************************************************************** +* Tools * +**************************************************************************** + + +**************************************************************************** +* Plugins * +**************************************************************************** + From b64ca061fde2987e138cc93903b2917b6c341f8c Mon Sep 17 00:00:00 2001 From: Oleg Shparber Date: Tue, 25 Dec 2012 01:47:22 +0200 Subject: [PATCH 11/17] Make QtMultimedia an identified module Task-number: QTBUG-28376 Change-Id: I7b27dc52b3085eb50695e559029f2533aa743d4f Reviewed-by: Jonas Rabbe Reviewed-by: Andy Nichols --- src/imports/multimedia/qmldir | 1 + 1 file changed, 1 insertion(+) diff --git a/src/imports/multimedia/qmldir b/src/imports/multimedia/qmldir index d5bc20d4..673f7ffd 100644 --- a/src/imports/multimedia/qmldir +++ b/src/imports/multimedia/qmldir @@ -1,3 +1,4 @@ +module QtMultimedia plugin declarative_multimedia typeinfo plugins.qmltypes Video 5.0 Video.qml From 73200f5464b4032fa25eedb5b594f17e48f5e7eb Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 18 Dec 2012 21:40:55 +0100 Subject: [PATCH 12/17] WMF: re-enabled video probes and made it more robust. Fixed the way the custom MF Transform (getting the frames) works: - Recreate it whenever we load a new media - During media type negotiation between nodes, the MFT should support the same types as the video sink supports - Allow input and output types to be changed as many times as needed, otherwise the topology cannot be resolved in some cases Change-Id: I7ca77e1a3dee83643f1a97f2e6ada9c5c0e88309 Reviewed-by: Lars Knoll --- src/plugins/wmf/mftvideo.cpp | 70 ++++++++-- src/plugins/wmf/mftvideo.h | 5 + src/plugins/wmf/player/mfplayerservice.cpp | 11 +- src/plugins/wmf/player/mfplayersession.cpp | 147 +++++++++++++-------- src/plugins/wmf/player/mfplayersession.h | 1 + 5 files changed, 165 insertions(+), 69 deletions(-) diff --git a/src/plugins/wmf/mftvideo.cpp b/src/plugins/wmf/mftvideo.cpp index f13ae3e2..12e80198 100644 --- a/src/plugins/wmf/mftvideo.cpp +++ b/src/plugins/wmf/mftvideo.cpp @@ -47,6 +47,7 @@ #include #include #include +#include // This MFT sends all samples it processes to connected video probes. // Sample is sent to probes in ProcessInput. @@ -70,6 +71,9 @@ MFTransform::~MFTransform() if (m_outputType) m_outputType->Release(); + + for (int i = 0; i < m_mediaTypes.size(); ++i) + m_mediaTypes[i]->Release(); } void MFTransform::addProbe(MFVideoProbeControl *probe) @@ -88,6 +92,14 @@ void MFTransform::removeProbe(MFVideoProbeControl *probe) m_videoProbes.removeOne(probe); } +void MFTransform::addSupportedMediaType(IMFMediaType *type) +{ + if (!type) + return; + QMutexLocker locker(&m_mutex); + m_mediaTypes.append(type); +} + STDMETHODIMP MFTransform::QueryInterface(REFIID riid, void** ppv) { if (!ppv) @@ -151,6 +163,8 @@ STDMETHODIMP MFTransform::GetStreamIDs(DWORD dwInputIDArraySize, DWORD *pdwInput STDMETHODIMP MFTransform::GetInputStreamInfo(DWORD dwInputStreamID, MFT_INPUT_STREAM_INFO *pStreamInfo) { + QMutexLocker locker(&m_mutex); + if (dwInputStreamID > 0) return MF_E_INVALIDSTREAMNUMBER; @@ -167,6 +181,8 @@ STDMETHODIMP MFTransform::GetInputStreamInfo(DWORD dwInputStreamID, MFT_INPUT_ST STDMETHODIMP MFTransform::GetOutputStreamInfo(DWORD dwOutputStreamID, MFT_OUTPUT_STREAM_INFO *pStreamInfo) { + QMutexLocker locker(&m_mutex); + if (dwOutputStreamID > 0) return MF_E_INVALIDSTREAMNUMBER; @@ -243,16 +259,27 @@ STDMETHODIMP MFTransform::SetInputType(DWORD dwInputStreamID, IMFMediaType *pTyp QMutexLocker locker(&m_mutex); - DWORD flags = 0; - if (m_outputType && m_outputType->IsEqual(pType, &flags) != S_OK) { + if (m_sample) + return MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING; + + if (!isMediaTypeSupported(pType)) + return MF_E_INVALIDMEDIATYPE; + + DWORD flags = 0; + if (pType && !m_inputType && m_outputType && m_outputType->IsEqual(pType, &flags) != S_OK) return MF_E_INVALIDMEDIATYPE; - } if (dwFlags == MFT_SET_TYPE_TEST_ONLY) return pType ? S_OK : E_POINTER; - if (m_inputType) + if (m_inputType) { m_inputType->Release(); + // Input type has changed, discard output type (if it's set) so it's reset later on + if (m_outputType && m_outputType->IsEqual(pType, &flags) != S_OK) { + m_outputType->Release(); + m_outputType = 0; + } + } m_inputType = pType; @@ -269,16 +296,27 @@ STDMETHODIMP MFTransform::SetOutputType(DWORD dwOutputStreamID, IMFMediaType *pT QMutexLocker locker(&m_mutex); - DWORD flags = 0; - if (m_inputType && m_inputType->IsEqual(pType, &flags) != S_OK) { + if (m_sample) + return MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING; + + if (!isMediaTypeSupported(pType)) + return MF_E_INVALIDMEDIATYPE; + + DWORD flags = 0; + if (pType && !m_outputType && m_inputType && m_inputType->IsEqual(pType, &flags) != S_OK) return MF_E_INVALIDMEDIATYPE; - } if (dwFlags == MFT_SET_TYPE_TEST_ONLY) return pType ? S_OK : E_POINTER; - if (m_outputType) + if (m_outputType) { m_outputType->Release(); + // Output type has changed, discard input type (if it's set) so it's reset later on + if (m_inputType && m_inputType->IsEqual(pType, &flags) != S_OK) { + m_inputType->Release(); + m_inputType = 0; + } + } m_outputType = pType; @@ -645,3 +683,19 @@ QByteArray MFTransform::dataFromBuffer(IMFMediaBuffer *buffer, int height, int * return array; } + +bool MFTransform::isMediaTypeSupported(IMFMediaType *type) +{ + // if the list is empty, it supports all formats + if (!type || m_mediaTypes.isEmpty()) + return true; + + for (int i = 0; i < m_mediaTypes.size(); ++i) { + DWORD flags = 0; + m_mediaTypes.at(i)->IsEqual(type, &flags); + if (flags & MF_MEDIATYPE_EQUAL_FORMAT_TYPES) + return true; + } + + return false; +} diff --git a/src/plugins/wmf/mftvideo.h b/src/plugins/wmf/mftvideo.h index 45520c81..3a3823c9 100644 --- a/src/plugins/wmf/mftvideo.h +++ b/src/plugins/wmf/mftvideo.h @@ -61,6 +61,8 @@ public: void addProbe(MFVideoProbeControl* probe); void removeProbe(MFVideoProbeControl* probe); + void addSupportedMediaType(IMFMediaType *type); + // IUnknown methods STDMETHODIMP QueryInterface(REFIID iid, void** ppv); STDMETHODIMP_(ULONG) AddRef(); @@ -97,6 +99,7 @@ private: static QVideoSurfaceFormat videoFormatForMFMediaType(IMFMediaType *mediaType, int *bytesPerLine); QVideoFrame makeVideoFrame(); QByteArray dataFromBuffer(IMFMediaBuffer *buffer, int height, int *bytesPerLine); + bool isMediaTypeSupported(IMFMediaType *type); long m_cRef; IMFMediaType *m_inputType; @@ -104,6 +107,8 @@ private: IMFSample *m_sample; QMutex m_mutex; + QList m_mediaTypes; + QList m_videoProbes; QMutex m_videoProbeMutex; diff --git a/src/plugins/wmf/player/mfplayerservice.cpp b/src/plugins/wmf/player/mfplayerservice.cpp index 5bda9f98..ea06031f 100644 --- a/src/plugins/wmf/player/mfplayerservice.cpp +++ b/src/plugins/wmf/player/mfplayerservice.cpp @@ -116,12 +116,11 @@ QMediaControl* MFPlayerService::requestControl(const char *name) } return 0; } else if (qstrcmp(name,QMediaVideoProbeControl_iid) == 0) { - // FIXME!! Disabled in Qt 5.0 because it is unstable -// if (m_session) { -// MFVideoProbeControl *probe = new MFVideoProbeControl(this); -// m_session->addProbe(probe); -// return probe; -// } + if (m_session) { + MFVideoProbeControl *probe = new MFVideoProbeControl(this); + m_session->addProbe(probe); + return probe; + } return 0; } diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp index d9ff0e7c..c4a56123 100644 --- a/src/plugins/wmf/player/mfplayersession.cpp +++ b/src/plugins/wmf/player/mfplayersession.cpp @@ -436,7 +436,6 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService) m_request.rate = 1.0f; m_audioSampleGrabber = new AudioSampleGrabberCallback; - m_videoProbeMFT = new MFTransform; } void MFPlayerSession::close() @@ -472,6 +471,11 @@ void MFPlayerSession::close() m_sourceResolver->Release(); m_sourceResolver = 0; } + if (m_videoProbeMFT) { + m_videoProbeMFT->Release(); + m_videoProbeMFT = 0; + } + if (m_session) m_session->Release(); @@ -493,18 +497,26 @@ void MFPlayerSession::removeProbe(MFAudioProbeControl *probe) void MFPlayerSession::addProbe(MFVideoProbeControl* probe) { - m_videoProbeMFT->addProbe(probe); + if (m_videoProbes.contains(probe)) + return; + + m_videoProbes.append(probe); + + if (m_videoProbeMFT) + m_videoProbeMFT->addProbe(probe); } void MFPlayerSession::removeProbe(MFVideoProbeControl* probe) { - m_videoProbeMFT->removeProbe(probe); + m_videoProbes.removeOne(probe); + + if (m_videoProbeMFT) + m_videoProbeMFT->removeProbe(probe); } MFPlayerSession::~MFPlayerSession() { m_audioSampleGrabber->Release(); - m_videoProbeMFT->Release(); } @@ -988,73 +1000,92 @@ IMFTopology *MFPlayerSession::insertMFT(IMFTopology *topology, TOPOID outputNode if (FAILED(topoLoader->Load(topology, &resolvedTopology, NULL))) break; -// FIXME!! VideoProbe disabled in Qt 5.0 because it is unstable. -// Commented out the following code to skip inserting the transform node -// getting the video frames. - // Get all output nodes and search for video output node. -// if (FAILED(resolvedTopology->GetOutputNodeCollection(&outputNodes))) -// break; + if (FAILED(resolvedTopology->GetOutputNodeCollection(&outputNodes))) + break; -// DWORD elementCount = 0; -// if (FAILED(outputNodes->GetElementCount(&elementCount))) -// break; + DWORD elementCount = 0; + if (FAILED(outputNodes->GetElementCount(&elementCount))) + break; -// for (DWORD n = 0; n < elementCount; n++) { -// IUnknown *element = 0; -// IMFTopologyNode *node = 0; -// IMFTopologyNode *inputNode = 0; -// IMFTopologyNode *mftNode = 0; + for (DWORD n = 0; n < elementCount; n++) { + IUnknown *element = 0; + IMFTopologyNode *node = 0; + IUnknown *outputObject = 0; + IMFMediaTypeHandler *videoSink = 0; + IMFTopologyNode *inputNode = 0; + IMFTopologyNode *mftNode = 0; -// do { -// if (FAILED(outputNodes->GetElement(n, &element))) -// break; + do { + if (FAILED(outputNodes->GetElement(n, &element))) + break; -// if (FAILED(element->QueryInterface(IID_IMFTopologyNode, (void**)&node))) -// break; + if (FAILED(element->QueryInterface(IID_IMFTopologyNode, (void**)&node))) + break; -// TOPOID id; -// if (FAILED(node->GetTopoNodeID(&id))) -// break; + TOPOID id; + if (FAILED(node->GetTopoNodeID(&id))) + break; -// if (id != outputNodeId) -// break; + if (id != outputNodeId) + break; -// // Insert MFT between the output node and the node connected to it. -// DWORD outputIndex = 0; -// if (FAILED(node->GetInput(0, &inputNode, &outputIndex))) -// break; + // Use output supported media types for the MFT + if (FAILED(node->GetObject(&outputObject))) + break; -// if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &mftNode))) -// break; + if (FAILED(outputObject->QueryInterface(IID_IMFMediaTypeHandler, (void**)&videoSink))) + break; -// if (FAILED(mftNode->SetObject(m_videoProbeMFT))) -// break; + DWORD mtCount; + if (FAILED(videoSink->GetMediaTypeCount(&mtCount))) + break; -// if (FAILED(resolvedTopology->AddNode(mftNode))) -// break; + for (DWORD i = 0; i < mtCount; ++i) { + IMFMediaType *type = 0; + if (SUCCEEDED(videoSink->GetMediaTypeByIndex(i, &type))) + m_videoProbeMFT->addSupportedMediaType(type); + } -// if (FAILED(inputNode->ConnectOutput(0, mftNode, 0))) -// break; + // Insert MFT between the output node and the node connected to it. + DWORD outputIndex = 0; + if (FAILED(node->GetInput(0, &inputNode, &outputIndex))) + break; -// if (FAILED(mftNode->ConnectOutput(0, node, 0))) -// break; + if (FAILED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &mftNode))) + break; -// isNewTopology = true; -// } while (false); + if (FAILED(mftNode->SetObject(m_videoProbeMFT))) + break; -// if (mftNode) -// mftNode->Release(); -// if (inputNode) -// inputNode->Release(); -// if (node) -// node->Release(); -// if (element) -// element->Release(); + if (FAILED(resolvedTopology->AddNode(mftNode))) + break; -// if (isNewTopology) -// break; -// } + if (FAILED(inputNode->ConnectOutput(0, mftNode, 0))) + break; + + if (FAILED(mftNode->ConnectOutput(0, node, 0))) + break; + + isNewTopology = true; + } while (false); + + if (mftNode) + mftNode->Release(); + if (inputNode) + inputNode->Release(); + if (node) + node->Release(); + if (element) + element->Release(); + if (videoSink) + videoSink->Release(); + if (outputObject) + outputObject->Release(); + + if (isNewTopology) + break; + } } while (false); if (outputNodes) @@ -1181,6 +1212,10 @@ void MFPlayerSession::createSession() QObject::connect(m_sourceResolver, SIGNAL(mediaSourceReady()), this, SLOT(handleMediaSourceReady())); QObject::connect(m_sourceResolver, SIGNAL(error(long)), this, SLOT(handleSourceError(long))); + m_videoProbeMFT = new MFTransform; + for (int i = 0; i < m_videoProbes.size(); ++i) + m_videoProbeMFT->addProbe(m_videoProbes.at(i)); + Q_ASSERT(m_session == NULL); HRESULT hr = MFCreateMediaSession(NULL, &m_session); if (FAILED(hr)) { @@ -1569,7 +1604,9 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent) break; case MESourceUnknown: changeStatus(QMediaPlayer::InvalidMedia); + break; case MEError: + changeStatus(QMediaPlayer::UnknownMediaStatus); qWarning() << "handleSessionEvent: serious error = " << hrStatus; emit error(QMediaPlayer::ResourceError, tr("Media session serious error."), true); break; diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h index b8b6f085..21efbf6a 100644 --- a/src/plugins/wmf/player/mfplayersession.h +++ b/src/plugins/wmf/player/mfplayersession.h @@ -232,6 +232,7 @@ private: IMFTopology *insertMFT(IMFTopology *topology, TOPOID outputNodeId); MFTransform *m_videoProbeMFT; + QList m_videoProbes; }; From 6eb192f047123079bcdfb45ca6da8f01cb97b90c Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 4 Jan 2013 17:30:28 +0100 Subject: [PATCH 13/17] WMF: Fixed uninitialized member variable. Change-Id: Iee60d6eee7bbf9dd7804216f4a49c4549f41ba5a Reviewed-by: Jason Barron --- src/plugins/wmf/player/mfvideorenderercontrol.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp index c3c5c1ae..c9b364f6 100644 --- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp +++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp @@ -318,6 +318,7 @@ namespace , m_prerollTargetTime(0) , m_startTime(0) , m_rendererControl(rendererControl) + , m_rate(1.f) { m_sink = parent; From 60eb27dfef8de1a737e4dca99d13cef8a9876af6 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 18 Dec 2012 22:16:13 +0100 Subject: [PATCH 14/17] WMF: release video controls before releasing the session For the VideoRendererControl, also stop the video surface at the same time. This fixes a crash when changing video. Change-Id: I49484f8b277c345dafb3e5947cf5d23df15546f3 Reviewed-by: Jason Barron --- src/plugins/wmf/player/evr9videowindowcontrol.cpp | 5 +++++ src/plugins/wmf/player/evr9videowindowcontrol.h | 1 + src/plugins/wmf/player/mfplayersession.cpp | 7 +++++++ src/plugins/wmf/player/mfvideorenderercontrol.cpp | 13 ++++++++++--- src/plugins/wmf/player/mfvideorenderercontrol.h | 1 + 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/plugins/wmf/player/evr9videowindowcontrol.cpp b/src/plugins/wmf/player/evr9videowindowcontrol.cpp index 7f1c7133..b15eef15 100644 --- a/src/plugins/wmf/player/evr9videowindowcontrol.cpp +++ b/src/plugins/wmf/player/evr9videowindowcontrol.cpp @@ -85,6 +85,11 @@ void Evr9VideoWindowControl::clear() m_currentActivate = NULL; } +void Evr9VideoWindowControl::releaseActivate() +{ + clear(); +} + WId Evr9VideoWindowControl::winId() const { return m_windowId; diff --git a/src/plugins/wmf/player/evr9videowindowcontrol.h b/src/plugins/wmf/player/evr9videowindowcontrol.h index ea4bae56..01a9c42f 100644 --- a/src/plugins/wmf/player/evr9videowindowcontrol.h +++ b/src/plugins/wmf/player/evr9videowindowcontrol.h @@ -86,6 +86,7 @@ public: void setSaturation(int saturation); IMFActivate* createActivate(); + void releaseActivate(); void setProcAmpValues(); diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp index c4a56123..7c732022 100644 --- a/src/plugins/wmf/player/mfplayersession.cpp +++ b/src/plugins/wmf/player/mfplayersession.cpp @@ -476,6 +476,13 @@ void MFPlayerSession::close() m_videoProbeMFT = 0; } + if (m_playerService->videoRendererControl()) { + m_playerService->videoRendererControl()->releaseActivate(); +#ifndef Q_WS_SIMULATOR + } else if (m_playerService->videoWindowControl()) { + m_playerService->videoWindowControl()->releaseActivate(); +#endif + } if (m_session) m_session->Release(); diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp index c9b364f6..28fcb5b1 100644 --- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp +++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp @@ -1781,6 +1781,7 @@ namespace , m_sink(0) , m_rendererControl(rendererControl) , m_attributes(0) + , m_surface(0) { MFCreateAttributes(&m_attributes, 0); m_sink = new MediaSink(rendererControl); @@ -2143,6 +2144,9 @@ MFVideoRendererControl::~MFVideoRendererControl() void MFVideoRendererControl::clear() { + if (m_surface) + m_surface->stop(); + if (m_currentActivate) { m_currentActivate->ShutdownObject(); m_currentActivate->Release(); @@ -2150,6 +2154,11 @@ void MFVideoRendererControl::clear() m_currentActivate = NULL; } +void MFVideoRendererControl::releaseActivate() +{ + clear(); +} + QAbstractVideoSurface *MFVideoRendererControl::surface() const { return m_surface; @@ -2209,10 +2218,8 @@ IMFActivate* MFVideoRendererControl::createActivate() clear(); m_currentActivate = new VideoRendererActivate(this); - if (m_surface) { + if (m_surface) setSurface(m_surface); - supportedFormatsChanged(); - } return m_currentActivate; } diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.h b/src/plugins/wmf/player/mfvideorenderercontrol.h index ba04e73b..0829e732 100644 --- a/src/plugins/wmf/player/mfvideorenderercontrol.h +++ b/src/plugins/wmf/player/mfvideorenderercontrol.h @@ -59,6 +59,7 @@ public: void setSurface(QAbstractVideoSurface *surface); IMFActivate* createActivate(); + void releaseActivate(); protected: void customEvent(QEvent *event); From c414890d8505323a0737227e413b5f7b0749ec1f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 21 Dec 2012 21:31:19 +0100 Subject: [PATCH 15/17] remove leftover code from multimediawidgets carve-out Change-Id: Ibb347193761a94ce4a309eddb75af37b73dd9be6 Reviewed-by: Jonas Rabbe --- src/multimedia/multimedia.pro | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro index e8ced991..9dbea399 100644 --- a/src/multimedia/multimedia.pro +++ b/src/multimedia/multimedia.pro @@ -1,11 +1,6 @@ TARGET = QtMultimedia QT = core-private network gui -contains(QT_CONFIG, opengl) | contains(QT_CONFIG, opengles2) { -} else { - DEFINES += QT_NO_OPENGL -} - QMAKE_DOCS = $$PWD/doc/qtmultimedia.qdocconf load(qt_module) From 77494db8d2a37a37c6410a7d72229f5bc41b3cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 8 Jan 2013 14:39:10 +0100 Subject: [PATCH 16/17] Compile in 32-bit mode. CGRect == NSRect only in 64-bit mode. Don't add -framework QuickTime based on the host arch, use QT_ARCH instead. Change-Id: I829bc1bcfe37f70a07e8c55a5bc7dee90aaa981a Reviewed-by: Gabriel de Dietrich --- .../avfoundation/mediaplayer/avfmediaplayersession.mm | 8 ++++---- .../avfoundation/mediaplayer/avfvideowidgetcontrol.mm | 2 +- src/plugins/qt7/qt7.pro | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm index 3fb93545..f9310604 100644 --- a/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm +++ b/src/plugins/avfoundation/mediaplayer/avfmediaplayersession.mm @@ -257,8 +257,8 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo]; if ([tracks count]) { AVAssetTrack *videoTrack = [tracks objectAtIndex:0]; - m_playerLayer.anchorPoint = NSMakePoint(0.0f, 0.0f); - m_playerLayer.bounds = NSMakeRect(0.0f, 0.0f, videoTrack.naturalSize.width, videoTrack.naturalSize.height); + m_playerLayer.anchorPoint = CGPointMake(0.0f, 0.0f); + m_playerLayer.bounds = CGRectMake(0.0f, 0.0f, videoTrack.naturalSize.width, videoTrack.naturalSize.height); } } @@ -368,8 +368,8 @@ static void *AVFMediaPlayerSessionObserverCurrentItemObservationContext = &AVFMe NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo]; if ([tracks count]) { AVAssetTrack *videoTrack = [tracks objectAtIndex:0]; - m_playerLayer.anchorPoint = NSMakePoint(0.0f, 0.0f); - m_playerLayer.bounds = NSMakeRect(0.0f, 0.0f, videoTrack.naturalSize.width, videoTrack.naturalSize.height); + m_playerLayer.anchorPoint = CGPointMake(0.0f, 0.0f); + m_playerLayer.bounds = CGRectMake(0.0f, 0.0f, videoTrack.naturalSize.width, videoTrack.naturalSize.height); } } diff --git a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm b/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm index b8cd7821..c995d92f 100644 --- a/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm +++ b/src/plugins/avfoundation/mediaplayer/avfvideowidgetcontrol.mm @@ -207,7 +207,7 @@ void AVFVideoWidgetControl::updateVideoFrame(const CVTimeStamp &ts) void AVFVideoWidgetControl::setupVideoOutput() { - NSRect layerBounds = [(AVPlayerLayer*)m_playerLayer bounds]; + CGRect layerBounds = [(AVPlayerLayer*)m_playerLayer bounds]; m_nativeSize = QSize(layerBounds.size.width, layerBounds.size.height); m_videoWidget->setNativeSize(m_nativeSize); diff --git a/src/plugins/qt7/qt7.pro b/src/plugins/qt7/qt7.pro index ae87bd44..f5d8bae3 100644 --- a/src/plugins/qt7/qt7.pro +++ b/src/plugins/qt7/qt7.pro @@ -23,7 +23,7 @@ LIBS += -framework AppKit -framework AudioUnit \ # QUICKTIME_C_API_AVAILABLE is true only on i386 # so make sure to link QuickTime -contains(QMAKE_HOST.arch, i386) { +contains(QT_ARCH, i386) { LIBS += -framework QuickTime } From 2d54a14ac130812965d89237c8ede479cc2e2df6 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Thu, 20 Dec 2012 15:01:08 +0100 Subject: [PATCH 17/17] WMF: added more metadata keys (on Windows 7 and later). Change-Id: I01eebd0582d33eb3d581176bba2a84fa75db2463 Reviewed-by: Jason Barron Reviewed-by: Yoann Lopes --- src/plugins/wmf/player/mfmetadatacontrol.cpp | 221 ++++++++++++++++++- 1 file changed, 216 insertions(+), 5 deletions(-) diff --git a/src/plugins/wmf/player/mfmetadatacontrol.cpp b/src/plugins/wmf/player/mfmetadatacontrol.cpp index 18c6a420..142b8650 100644 --- a/src/plugins/wmf/player/mfmetadatacontrol.cpp +++ b/src/plugins/wmf/player/mfmetadatacontrol.cpp @@ -39,12 +39,95 @@ ** ****************************************************************************/ +#include +#include + #include "mfmetadatacontrol.h" #include "mfplayerservice.h" #include "Propkey.h" //#define DEBUG_MEDIAFOUNDATION +static QString nameForGUID(GUID guid) +{ + // Audio formats + if (guid == MFAudioFormat_AAC) + return QStringLiteral("MPEG AAC Audio"); + else if (guid == MFAudioFormat_ADTS) + return QStringLiteral("MPEG ADTS AAC Audio"); + else if (guid == MFAudioFormat_Dolby_AC3_SPDIF) + return QStringLiteral("Dolby AC-3 SPDIF"); + else if (guid == MFAudioFormat_DRM) + return QStringLiteral("DRM"); + else if (guid == MFAudioFormat_DTS) + return QStringLiteral("Digital Theater Systems Audio (DTS)"); + else if (guid == MFAudioFormat_Float) + return QStringLiteral("IEEE Float Audio"); + else if (guid == MFAudioFormat_MP3) + return QStringLiteral("MPEG Audio Layer-3 (MP3)"); + else if (guid == MFAudioFormat_MPEG) + return QStringLiteral("MPEG-1 Audio"); + else if (guid == MFAudioFormat_MSP1) + return QStringLiteral("Windows Media Audio Voice"); + else if (guid == MFAudioFormat_PCM) + return QStringLiteral("Uncompressed PCM Audio"); + else if (guid == MFAudioFormat_WMASPDIF) + return QStringLiteral("Windows Media Audio 9 SPDIF"); + else if (guid == MFAudioFormat_WMAudioV8) + return QStringLiteral("Windows Media Audio 8 (WMA2)"); + else if (guid == MFAudioFormat_WMAudioV9) + return QStringLiteral("Windows Media Audio 9 (WMA3"); + else if (guid == MFAudioFormat_WMAudio_Lossless) + return QStringLiteral("Windows Media Audio 9 Lossless"); + + // Video formats + if (guid == MFVideoFormat_DV25) + return QStringLiteral("DVCPRO 25 (DV25)"); + else if (guid == MFVideoFormat_DV50) + return QStringLiteral("DVCPRO 50 (DV50)"); + else if (guid == MFVideoFormat_DVC) + return QStringLiteral("DVC/DV Video"); + else if (guid == MFVideoFormat_DVH1) + return QStringLiteral("DVCPRO 100 (DVH1)"); + else if (guid == MFVideoFormat_DVHD) + return QStringLiteral("HD-DVCR (DVHD)"); + else if (guid == MFVideoFormat_DVSD) + return QStringLiteral("SDL-DVCR (DVSD)"); + else if (guid == MFVideoFormat_DVSL) + return QStringLiteral("SD-DVCR (DVSL)"); + else if (guid == MFVideoFormat_H264) + return QStringLiteral("H.264 Video"); + else if (guid == MFVideoFormat_M4S2) + return QStringLiteral("MPEG-4 part 2 Video (M4S2)"); + else if (guid == MFVideoFormat_MJPG) + return QStringLiteral("Motion JPEG (MJPG)"); + else if (guid == MFVideoFormat_MP43) + return QStringLiteral("Microsoft MPEG 4 version 3 (MP43)"); + else if (guid == MFVideoFormat_MP4S) + return QStringLiteral("ISO MPEG 4 version 1 (MP4S)"); + else if (guid == MFVideoFormat_MP4V) + return QStringLiteral("MPEG-4 part 2 Video (MP4V)"); + else if (guid == MFVideoFormat_MPEG2) + return QStringLiteral("MPEG-2 Video"); + else if (guid == MFVideoFormat_MPG1) + return QStringLiteral("MPEG-1 Video"); + else if (guid == MFVideoFormat_MSS1) + return QStringLiteral("Windows Media Screen 1 (MSS1)"); + else if (guid == MFVideoFormat_MSS2) + return QStringLiteral("Windows Media Video 9 Screen (MSS2)"); + else if (guid == MFVideoFormat_WMV1) + return QStringLiteral("Windows Media Video 7 (WMV1)"); + else if (guid == MFVideoFormat_WMV2) + return QStringLiteral("Windows Media Video 8 (WMV2)"); + else if (guid == MFVideoFormat_WMV3) + return QStringLiteral("Windows Media Video 9 (WMV3)"); + else if (guid == MFVideoFormat_WVC1) + return QStringLiteral("Windows Media Video VC1 (WVC1)"); + + else + return QStringLiteral("Unknown codec"); +} + MFMetaDataControl::MFMetaDataControl(QObject *parent) : QMetaDataReaderControl(parent) , m_metaData(0) @@ -83,9 +166,46 @@ QVariant MFMetaDataControl::metaData(const QString &key) const else if (m_metaData) hr = m_metaData->GetProperty(reinterpret_cast(m_commonNames[index].utf16()), &var); - if (SUCCEEDED(hr)) + if (SUCCEEDED(hr)) { value = convertValue(var); + // some metadata needs to be reformatted + if (value.isValid() && m_content) { + if (key == QMediaMetaData::MediaType) { + QString v = value.toString(); + if (v == QLatin1String("{D1607DBC-E323-4BE2-86A1-48A42A28441E}")) + value = QStringLiteral("Music"); + else if (v == QLatin1String("{DB9830BD-3AB3-4FAB-8A37-1A995F7FF74B}")) + value = QStringLiteral("Video"); + else if (v == QLatin1String("{01CD0F29-DA4E-4157-897B-6275D50C4F11}")) + value = QStringLiteral("Audio"); + else if (v == QLatin1String("{FCF24A76-9A57-4036-990D-E35DD8B244E1}")) + value = QStringLiteral("Other"); + } else if (key == QMediaMetaData::Duration) { + // duration is provided in 100-nanosecond units, convert to milliseconds + value = (value.toLongLong() + 10000) / 10000; + } else if (key == QMediaMetaData::AudioCodec || key == QMediaMetaData::VideoCodec) { + GUID guid; + if (SUCCEEDED(CLSIDFromString((const WCHAR*)value.toString().utf16(), &guid))) + value = nameForGUID(guid); + } else if (key == QMediaMetaData::Resolution) { + QSize res; + res.setHeight(value.toUInt()); + if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_FrameWidth, &var))) + res.setWidth(convertValue(var).toUInt()); + value = res; + } else if (key == QMediaMetaData::PixelAspectRatio) { + QSize aspectRatio; + aspectRatio.setWidth(value.toUInt()); + if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_VerticalAspectRatio, &var))) + aspectRatio.setHeight(convertValue(var).toUInt()); + value = aspectRatio; + } else if (key == QMediaMetaData::VideoFrameRate) { + value = value.toReal() / 1000.f; + } + } + } + PropVariantClear(&var); return value; } @@ -93,9 +213,6 @@ QVariant MFMetaDataControl::metaData(const QString &key) const QVariant MFMetaDataControl::convertValue(const PROPVARIANT& var) const { QVariant value; - //form MSDN: http://msdn.microsoft.com/en-us/library/ff384862%28v=VS.85%29.aspx - //it seems that those 4 types are enough for media foundation metadata - //add more later if necessary switch (var.vt) { case VT_LPWSTR: value = QString::fromUtf16(reinterpret_cast(var.pwszVal)); @@ -109,6 +226,33 @@ QVariant MFMetaDataControl::convertValue(const PROPVARIANT& var) const case VT_BOOL: value = bool(var.boolVal); break; + case VT_FILETIME: + SYSTEMTIME sysDate; + if (!FileTimeToSystemTime(&var.filetime, &sysDate)) + break; + value = QDate(sysDate.wYear, sysDate.wMonth, sysDate.wDay); + break; + case VT_STREAM: + { + STATSTG stat; + if (FAILED(var.pStream->Stat(&stat, STATFLAG_NONAME))) + break; + void *data = malloc(stat.cbSize.QuadPart); + ULONG read = 0; + if (FAILED(var.pStream->Read(data, stat.cbSize.QuadPart, &read))) { + free(data); + break; + } + value = QImage::fromData((const uchar*)data, read); + free(data); + } + break; + case VT_VECTOR | VT_LPWSTR: + QStringList vList; + for (ULONG i = 0; i < var.calpwstr.cElems; ++i) + vList.append(QString::fromUtf16(reinterpret_cast(var.calpwstr.pElems[i]))); + value = vList; + break; } return value; } @@ -147,13 +291,80 @@ void MFMetaDataControl::updateSource(IMFPresentationDescriptor* sourcePD, IMFMed m_availableMetaDatas.push_back(QMediaMetaData::Author); } else if (key == PKEY_Title) { m_availableMetaDatas.push_back(QMediaMetaData::Title); + } else if (key == PKEY_Media_SubTitle) { + m_availableMetaDatas.push_back(QMediaMetaData::SubTitle); } else if (key == PKEY_ParentalRating) { m_availableMetaDatas.push_back(QMediaMetaData::ParentalRating); } else if (key == PKEY_Comment) { m_availableMetaDatas.push_back(QMediaMetaData::Description); } else if (key == PKEY_Copyright) { m_availableMetaDatas.push_back(QMediaMetaData::Copyright); - //TODO: add more common keys + } else if (key == PKEY_Comment) { + m_availableMetaDatas.push_back(QMediaMetaData::Comment); + } else if (key == PKEY_Media_ProviderStyle) { + m_availableMetaDatas.push_back(QMediaMetaData::Genre); + } else if (key == PKEY_Media_Year) { + m_availableMetaDatas.push_back(QMediaMetaData::Year); + } else if (key == PKEY_Media_DateEncoded) { + m_availableMetaDatas.push_back(QMediaMetaData::Date); + } else if (key == PKEY_Rating) { + m_availableMetaDatas.push_back(QMediaMetaData::UserRating); + } else if (key == PKEY_Keywords) { + m_availableMetaDatas.push_back(QMediaMetaData::Keywords); + } else if (key == PKEY_Language) { + m_availableMetaDatas.push_back(QMediaMetaData::Language); + } else if (key == PKEY_Media_Publisher) { + m_availableMetaDatas.push_back(QMediaMetaData::Publisher); + } else if (key == PKEY_Media_ClassPrimaryID) { + m_availableMetaDatas.push_back(QMediaMetaData::MediaType); + } else if (key == PKEY_Media_Duration) { + m_availableMetaDatas.push_back(QMediaMetaData::Duration); + } else if (key == PKEY_Audio_EncodingBitrate) { + m_availableMetaDatas.push_back(QMediaMetaData::AudioBitRate); + } else if (key == PKEY_Audio_Format) { + m_availableMetaDatas.push_back(QMediaMetaData::AudioCodec); + } else if (key == PKEY_Media_AverageLevel) { + m_availableMetaDatas.push_back(QMediaMetaData::AverageLevel); + } else if (key == PKEY_Audio_ChannelCount) { + m_availableMetaDatas.push_back(QMediaMetaData::ChannelCount); + } else if (key == PKEY_Audio_PeakValue) { + m_availableMetaDatas.push_back(QMediaMetaData::PeakValue); + } else if (key == PKEY_Audio_SampleRate) { + m_availableMetaDatas.push_back(QMediaMetaData::SampleRate); + } else if (key == PKEY_Music_AlbumTitle) { + m_availableMetaDatas.push_back(QMediaMetaData::AlbumTitle); + } else if (key == PKEY_Music_AlbumArtist) { + m_availableMetaDatas.push_back(QMediaMetaData::AlbumArtist); + } else if (key == PKEY_Music_Artist) { + m_availableMetaDatas.push_back(QMediaMetaData::ContributingArtist); + } else if (key == PKEY_Music_Composer) { + m_availableMetaDatas.push_back(QMediaMetaData::Composer); + } else if (key == PKEY_Music_Conductor) { + m_availableMetaDatas.push_back(QMediaMetaData::Conductor); + } else if (key == PKEY_Music_Lyrics) { + m_availableMetaDatas.push_back(QMediaMetaData::Lyrics); + } else if (key == PKEY_Music_Mood) { + m_availableMetaDatas.push_back(QMediaMetaData::Mood); + } else if (key == PKEY_Music_TrackNumber) { + m_availableMetaDatas.push_back(QMediaMetaData::TrackNumber); + } else if (key == PKEY_Music_Genre) { + m_availableMetaDatas.push_back(QMediaMetaData::Genre); + } else if (key == PKEY_ThumbnailStream) { + m_availableMetaDatas.push_back(QMediaMetaData::ThumbnailImage); + } else if (key == PKEY_Video_FrameHeight) { + m_availableMetaDatas.push_back(QMediaMetaData::Resolution); + } else if (key == PKEY_Video_HorizontalAspectRatio) { + m_availableMetaDatas.push_back(QMediaMetaData::PixelAspectRatio); + } else if (key == PKEY_Video_FrameRate) { + m_availableMetaDatas.push_back(QMediaMetaData::VideoFrameRate); + } else if (key == PKEY_Video_EncodingBitrate) { + m_availableMetaDatas.push_back(QMediaMetaData::VideoBitRate); + } else if (key == PKEY_Video_Compression) { + m_availableMetaDatas.push_back(QMediaMetaData::VideoCodec); + } else if (key == PKEY_Video_Director) { + m_availableMetaDatas.push_back(QMediaMetaData::Director); + } else if (key == PKEY_Media_Writer) { + m_availableMetaDatas.push_back(QMediaMetaData::Writer); } else { common = false; //TODO: add more extended keys