diff options
Diffstat (limited to 'src/multimedia/platform')
60 files changed, 783 insertions, 1886 deletions
diff --git a/src/multimedia/platform/android/mediaplayer/mediaplayer.pri b/src/multimedia/platform/android/mediaplayer/mediaplayer.pri index 33348b38b..184e7efc3 100644 --- a/src/multimedia/platform/android/mediaplayer/mediaplayer.pri +++ b/src/multimedia/platform/android/mediaplayer/mediaplayer.pri @@ -3,11 +3,11 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/qandroidmediaplayercontrol_p.h \ $$PWD/qandroidmediaservice_p.h \ - $$PWD/qandroidmetadatareadercontrol_p.h \ + $$PWD/qandroidmetadata_p.h \ $$PWD/qandroidmediaplayervideorenderercontrol_p.h SOURCES += \ $$PWD/qandroidmediaplayercontrol.cpp \ $$PWD/qandroidmediaservice.cpp \ - $$PWD/qandroidmetadatareadercontrol.cpp \ + $$PWD/qandroidmetadata.cpp \ $$PWD/qandroidmediaplayervideorenderercontrol.cpp diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol.cpp b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol.cpp index d11e2ef14..11d18d362 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol.cpp +++ b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol.cpp @@ -40,6 +40,7 @@ #include "qandroidmediaplayercontrol_p.h" #include "androidmediaplayer_p.h" #include "qandroidvideooutput_p.h" +#include "qandroidmetadata_p.h" QT_BEGIN_NAMESPACE @@ -298,6 +299,11 @@ QStringList QAndroidMediaPlayerControl::supportedCustomAudioRoles() const << "USAGE_VOICE_COMMUNICATION_SIGNALLING"; } +QMediaMetaData QAndroidMediaPlayerControl::metaData() const +{ + return QAndroidMetaData::extractMetadata(mMediaContent); +} + int QAndroidMediaPlayerControl::bufferStatus() const { return mBufferFilled ? 100 : 0; @@ -536,7 +542,7 @@ void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra) setSeekable(false); break; case AndroidMediaPlayer::MEDIA_INFO_METADATA_UPDATE: - Q_EMIT metaDataUpdated(); + Q_EMIT metaDataChanged(); break; } } @@ -650,7 +656,7 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state) } else { onBufferingChanged(100); } - Q_EMIT metaDataUpdated(); + Q_EMIT metaDataChanged(); setAudioAvailable(true); flushPendingStates(); break; diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol_p.h b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol_p.h index 40fbf8464..b8a5f9884 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol_p.h +++ b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol_p.h @@ -90,10 +90,11 @@ public: void setCustomAudioRole(const QString &role) override; QStringList supportedCustomAudioRoles() const override; + QMediaMetaData metaData() const override; + void setVideoOutput(QAndroidVideoOutput *videoOutput); Q_SIGNALS: - void metaDataUpdated(); void audioRoleChanged(QAudio::Role role); void customAudioRoleChanged(const QString &role); diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaservice.cpp b/src/multimedia/platform/android/mediaplayer/qandroidmediaservice.cpp index 15aaf962c..6f8e88dc0 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmediaservice.cpp +++ b/src/multimedia/platform/android/mediaplayer/qandroidmediaservice.cpp @@ -40,7 +40,6 @@ #include "qandroidmediaservice_p.h" #include "qandroidmediaplayercontrol_p.h" -#include "qandroidmetadatareadercontrol_p.h" #include "qandroidmediaplayervideorenderercontrol_p.h" QT_BEGIN_NAMESPACE @@ -48,17 +47,11 @@ QT_BEGIN_NAMESPACE QAndroidMediaService::QAndroidMediaService() { mMediaControl = new QAndroidMediaPlayerControl; - mMetadataControl = new QAndroidMetaDataReaderControl; - connect(mMediaControl, SIGNAL(mediaChanged(QUrl)), - mMetadataControl, SLOT(onMediaChanged(QUrl))); - connect(mMediaControl, SIGNAL(metaDataUpdated()), - mMetadataControl, SLOT(onUpdateMetaData())); } QAndroidMediaService::~QAndroidMediaService() { delete mVideoRendererControl; - delete mMetadataControl; delete mMediaControl; } @@ -67,9 +60,6 @@ QObject *QAndroidMediaService::requestControl(const char *name) if (qstrcmp(name, QMediaPlayerControl_iid) == 0) return mMediaControl; - if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) - return mMetadataControl; - if (qstrcmp(name, QVideoRendererControl_iid) == 0) { if (!mVideoRendererControl) { mVideoRendererControl = new QAndroidMediaPlayerVideoRendererControl(mMediaControl); @@ -93,11 +83,6 @@ QMediaPlayerControl *QAndroidMediaService::player() return mMediaControl; } -QMetaDataReaderControl *QAndroidMediaService::dataReader() -{ - return mMetadataControl; -} - QVideoRendererControl *QAndroidMediaService::createVideoRenderer() { if (!mVideoRendererControl) { diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaservice_p.h b/src/multimedia/platform/android/mediaplayer/qandroidmediaservice_p.h index 2a238e676..9b227809e 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmediaservice_p.h +++ b/src/multimedia/platform/android/mediaplayer/qandroidmediaservice_p.h @@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE class QAndroidMediaPlayerControl; -class QAndroidMetaDataReaderControl; class QAndroidMediaPlayerVideoRendererControl; class QAndroidMediaService : public QMediaPlatformPlayerInterface @@ -71,7 +70,6 @@ public: // QMediaPlatformPlayerInterface QMediaPlayerControl *player() override; - QMetaDataReaderControl *dataReader() override; // QMediaStreamsControl *streams() override; QVideoRendererControl *createVideoRenderer() override; @@ -79,7 +77,6 @@ public: private: QAndroidMediaPlayerControl *mMediaControl = nullptr; - QAndroidMetaDataReaderControl *mMetadataControl = nullptr; QAndroidMediaPlayerVideoRendererControl *mVideoRendererControl = nullptr; }; diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmetadatareadercontrol.cpp b/src/multimedia/platform/android/mediaplayer/qandroidmetadata.cpp index 5a8987cf4..e086ba1b4 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmetadatareadercontrol.cpp +++ b/src/multimedia/platform/android/mediaplayer/qandroidmetadata.cpp @@ -37,7 +37,7 @@ ** ****************************************************************************/ -#include "qandroidmetadatareadercontrol_p.h" +#include "qandroidmetadata_p.h" #include "androidmediametadataretriever_p.h" #include <QtMultimedia/qmediametadata.h> @@ -71,90 +71,14 @@ static const char* qt_ID3GenreNames[] = "Euro-House", "Dance Hall" }; -typedef QList<QAndroidMetaDataReaderControl *> AndroidMetaDataReaders; -Q_GLOBAL_STATIC(AndroidMetaDataReaders, g_metaDataReaders) -Q_GLOBAL_STATIC(QMutex, g_metaDataReadersMtx) - -QAndroidMetaDataReaderControl::QAndroidMetaDataReaderControl(QObject *parent) - : QMetaDataReaderControl(parent) - , m_available(false) -{ -} - -QAndroidMetaDataReaderControl::~QAndroidMetaDataReaderControl() -{ - QMutexLocker l(g_metaDataReadersMtx()); - const int idx = g_metaDataReaders->indexOf(this); - if (idx != -1) - g_metaDataReaders->remove(idx); -} - -bool QAndroidMetaDataReaderControl::isMetaDataAvailable() const -{ - const QMutexLocker l(&m_mtx); - return m_available && !m_metadata.isEmpty(); -} - -QVariant QAndroidMetaDataReaderControl::metaData(const QString &key) const -{ - const QMutexLocker l(&m_mtx); - return m_metadata.value(key); -} - -QStringList QAndroidMetaDataReaderControl::availableMetaData() const -{ - const QMutexLocker l(&m_mtx); - return m_metadata.keys(); -} - -void QAndroidMetaDataReaderControl::onMediaChanged(const QUrl &media) -{ - const QMutexLocker l(&m_mtx); - m_metadata.clear(); - m_mediaContent = media; -} - -void QAndroidMetaDataReaderControl::onUpdateMetaData() +QMediaMetaData QAndroidMetaData::extractMetadata(const QUrl &url) { - { - const QMutexLocker l(g_metaDataReadersMtx()); - if (!g_metaDataReaders->contains(this)) - g_metaDataReaders->append(this); - } - - const QMutexLocker ml(&m_mtx); - if (m_mediaContent.isEmpty()) - return; - - (void)QtConcurrent::run(&extractMetadata, this, m_mediaContent); -} - -void QAndroidMetaDataReaderControl::updateData(const QVariantMap &metadata, const QUrl &url) -{ - const QMutexLocker l(&m_mtx); - - if (m_mediaContent != url) - return; - - const bool oldAvailable = m_available; - m_metadata = metadata; - m_available = !m_metadata.isEmpty(); - - if (m_available != oldAvailable) - Q_EMIT metaDataAvailableChanged(m_available); - - Q_EMIT metaDataChanged(); -} - -void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderControl *caller, - const QUrl &url) -{ - QVariantMap metadata; + QMediaMetaData metadata; if (!url.isEmpty()) { AndroidMediaMetadataRetriever retriever; if (!retriever.setDataSource(url)) - return; + return metadata; QString mimeType = retriever.extractMetadata(AndroidMediaMetadataRetriever::MimeType); if (!mimeType.isNull()) @@ -175,12 +99,12 @@ void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderContro if (!string.isNull()) { metadata.insert(isVideo ? QMediaMetaData::LeadPerformer : QMediaMetaData::ContributingArtist, - string.split('/', Qt::SkipEmptyParts)); + string.split(QLatin1Char('/'), Qt::SkipEmptyParts)); } string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Author); if (!string.isNull()) - metadata.insert(QMediaMetaData::Author, string.split('/', Qt::SkipEmptyParts)); + metadata.insert(QMediaMetaData::Author, string.split(QLatin1Char('/'), Qt::SkipEmptyParts)); string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Bitrate); if (!string.isNull()) { @@ -195,7 +119,7 @@ void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderContro string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Composer); if (!string.isNull()) - metadata.insert(QMediaMetaData::Composer, string.split('/', Qt::SkipEmptyParts)); + metadata.insert(QMediaMetaData::Composer, string.split(QLatin1Char('/'), Qt::SkipEmptyParts)); string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Date); if (!string.isNull()) @@ -208,7 +132,7 @@ void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderContro string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Genre); if (!string.isNull()) { // The genre can be returned as an ID3v2 id, get the name for it in that case - if (string.startsWith('(') && string.endsWith(')')) { + if (string.startsWith(QLatin1Char('(')) && string.endsWith(QLatin1Char(')'))) { bool ok = false; const int genreId = QStringView{string}.mid(1, string.length() - 2).toInt(&ok); if (ok && genreId >= 0 && genreId <= 125) @@ -228,20 +152,16 @@ void QAndroidMetaDataReaderControl::extractMetadata(QAndroidMetaDataReaderContro metadata.insert(QMediaMetaData::Resolution, QSize(width, height)); } - string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Writer); - if (!string.isNull()) - metadata.insert(QMediaMetaData::Writer, string.split('/', Qt::SkipEmptyParts)); +// string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Writer); +// if (!string.isNull()) +// metadata.insert(QMediaMetaData::Writer, string.split('/', Qt::SkipEmptyParts)); string = retriever.extractMetadata(AndroidMediaMetadataRetriever::Year); if (!string.isNull()) metadata.insert(QMediaMetaData::Year, string.toInt()); } - const QMutexLocker lock(g_metaDataReadersMtx()); - if (!g_metaDataReaders->contains(caller)) - return; - - caller->updateData(metadata, url); + return metadata; } QT_END_NAMESPACE diff --git a/src/multimedia/platform/darwin/camera/avfcamerametadatacontrol_p.h b/src/multimedia/platform/android/mediaplayer/qandroidmetadata_p.h index 45addb946..4ce65dc09 100644 --- a/src/multimedia/platform/darwin/camera/avfcamerametadatacontrol_p.h +++ b/src/multimedia/platform/android/mediaplayer/qandroidmetadata_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef AVFCAMERAMETADATACONTROL_H -#define AVFCAMERAMETADATACONTROL_H +#ifndef QANDROIDMETADATA_H +#define QANDROIDMETADATA_H // // W A R N I N G @@ -51,31 +51,21 @@ // We mean it. // -#include <qmetadatawritercontrol.h> -#include <QtCore/qvariant.h> +#include <qmediametadata.h> +#include <qurl.h> +#include <QMutex> +#include <QVariant> QT_BEGIN_NAMESPACE -class AVFMediaRecorderControl; +class AndroidMediaMetadataRetriever; -class AVFCameraMetaDataControl : public QMetaDataWriterControl +class QAndroidMetaData : public QMediaMetaData { - Q_OBJECT public: - AVFCameraMetaDataControl(AVFMediaRecorderControl *parent = nullptr); - virtual ~AVFCameraMetaDataControl(); - - bool isMetaDataAvailable() const override; - bool isWritable() const override; - - QVariant metaData(const QString &key) const override; - void setMetaData(const QString &key, const QVariant &value) override; - QStringList availableMetaData() const override; - -private: - QMap<QString, QVariant> m_tags; + static QMediaMetaData extractMetadata(const QUrl &url); }; QT_END_NAMESPACE -#endif +#endif // QANDROIDMETADATA_H diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmetadatareadercontrol_p.h b/src/multimedia/platform/android/mediaplayer/qandroidmetadatareadercontrol_p.h deleted file mode 100644 index 1f372ae17..000000000 --- a/src/multimedia/platform/android/mediaplayer/qandroidmetadatareadercontrol_p.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QANDROIDMETADATAREADERCONTROL_H -#define QANDROIDMETADATAREADERCONTROL_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QMetaDataReaderControl> -#include <qurl.h> -#include <QMutex> -#include <QVariant> - -QT_BEGIN_NAMESPACE - -class AndroidMediaMetadataRetriever; - -class QAndroidMetaDataReaderControl : public QMetaDataReaderControl -{ - Q_OBJECT -public: - explicit QAndroidMetaDataReaderControl(QObject *parent = 0); - ~QAndroidMetaDataReaderControl() override; - - bool isMetaDataAvailable() const override; - - QVariant metaData(const QString &key) const override; - QStringList availableMetaData() const override; - -public Q_SLOTS: - void onMediaChanged(const QUrl &media); - void onUpdateMetaData(); - -private: - void updateData(const QVariantMap &metadata, const QUrl &url); - static void extractMetadata(QAndroidMetaDataReaderControl *caller, const QUrl &url); - - mutable QMutex m_mtx; - QUrl m_mediaContent; - bool m_available; - QVariantMap m_metadata; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDMETADATAREADERCONTROL_H diff --git a/src/multimedia/platform/darwin/camera/avfcamerametadatacontrol.mm b/src/multimedia/platform/darwin/camera/avfcamerametadatacontrol.mm deleted file mode 100644 index d346a7dee..000000000 --- a/src/multimedia/platform/darwin/camera/avfcamerametadatacontrol.mm +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "avfcamerametadatacontrol_p.h" -#include "avfcamerasession_p.h" -#include "avfcameraservice_p.h" -#include "avfmediarecordercontrol_p.h" - -QT_USE_NAMESPACE - -//metadata support is not implemented yet - -AVFCameraMetaDataControl::AVFCameraMetaDataControl(AVFMediaRecorderControl *parent) - : QMetaDataWriterControl(parent) -{ -} - -AVFCameraMetaDataControl::~AVFCameraMetaDataControl() -{ -} - -bool AVFCameraMetaDataControl::isMetaDataAvailable() const -{ - return !m_tags.isEmpty(); -} - -bool AVFCameraMetaDataControl::isWritable() const -{ - return false; -} - -QVariant AVFCameraMetaDataControl::metaData(const QString &key) const -{ - return m_tags.value(key); -} - -void AVFCameraMetaDataControl::setMetaData(const QString &key, const QVariant &value) -{ - m_tags.insert(key, value); -} - -QStringList AVFCameraMetaDataControl::availableMetaData() const -{ - return m_tags.keys(); -} - -#include "moc_avfcamerametadatacontrol_p.cpp" diff --git a/src/multimedia/platform/darwin/camera/avfcameraservice.mm b/src/multimedia/platform/darwin/camera/avfcameraservice.mm index b327c8d17..0ed6b74ce 100644 --- a/src/multimedia/platform/darwin/camera/avfcameraservice.mm +++ b/src/multimedia/platform/darwin/camera/avfcameraservice.mm @@ -43,7 +43,6 @@ #include "avfcameraservice_p.h" #include "avfcameracontrol_p.h" #include "avfcamerasession_p.h" -#include "avfcamerametadatacontrol_p.h" #include "avfmediarecordercontrol_p.h" #include "avfimagecapturecontrol_p.h" #include "avfcamerarenderercontrol_p.h" diff --git a/src/multimedia/platform/darwin/camera/avfmediarecordercontrol.mm b/src/multimedia/platform/darwin/camera/avfmediarecordercontrol.mm index 983fd8357..e39161cfd 100644 --- a/src/multimedia/platform/darwin/camera/avfmediarecordercontrol.mm +++ b/src/multimedia/platform/darwin/camera/avfmediarecordercontrol.mm @@ -42,7 +42,6 @@ #include "avfcamerasession_p.h" #include "avfcameraservice_p.h" #include "avfcameracontrol_p.h" -#include "avfcamerametadatacontrol_p.h" #include "qaudiodeviceinfo.h" #include "qmediadevicemanager.h" @@ -151,8 +150,6 @@ AVFMediaRecorderControl::AVFMediaRecorderControl(AVFCameraService *service, QObj connect(m_cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes)), SLOT(setupSessionForCapture())); connect(m_session, SIGNAL(readyToConfigureConnections()), SLOT(setupSessionForCapture())); connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(setupSessionForCapture())); - - m_metaData = new AVFCameraMetaDataControl(this); } AVFMediaRecorderControl::~AVFMediaRecorderControl() @@ -533,11 +530,6 @@ void AVFMediaRecorderControl::setEncoderSettings(const QMediaEncoderSettings &se m_settings = settings; } -QMetaDataWriterControl *AVFMediaRecorderControl::metaDataControl() -{ - return m_metaData; -} - void AVFMediaRecorderControl::setState(QMediaRecorder::State state) { if (m_state == state) diff --git a/src/multimedia/platform/darwin/camera/avfmediarecordercontrol_p.h b/src/multimedia/platform/darwin/camera/avfmediarecordercontrol_p.h index 1d50ceb72..02a8581d2 100644 --- a/src/multimedia/platform/darwin/camera/avfmediarecordercontrol_p.h +++ b/src/multimedia/platform/darwin/camera/avfmediarecordercontrol_p.h @@ -68,7 +68,6 @@ QT_BEGIN_NAMESPACE class AVFCameraSession; class AVFCameraControl; class AVFCameraService; -class AVFCameraMetaDataControl; class AVFMediaRecorderControl : public QMediaRecorderControl { @@ -96,8 +95,6 @@ public: void setEncoderSettings(const QMediaEncoderSettings &settings) override; - QMetaDataWriterControl *metaDataControl() override; - public Q_SLOTS: void setState(QMediaRecorder::State state) override; void setMuted(bool muted) override; @@ -116,7 +113,6 @@ private: AVFCameraControl *m_cameraControl; AVFCameraSession *m_session; AVCaptureDevice *m_audioCaptureDevice = nullptr; - AVFCameraMetaDataControl *m_metaData = nullptr; bool m_connected; QUrl m_outputLocation; diff --git a/src/multimedia/platform/darwin/camera/camera.pri b/src/multimedia/platform/darwin/camera/camera.pri index 648c5c358..49aecdac4 100644 --- a/src/multimedia/platform/darwin/camera/camera.pri +++ b/src/multimedia/platform/darwin/camera/camera.pri @@ -1,7 +1,6 @@ HEADERS += \ $$PWD/avfcameradebug_p.h \ $$PWD/avfcameracontrol_p.h \ - $$PWD/avfcamerametadatacontrol_p.h \ $$PWD/avfimagecapturecontrol_p.h \ $$PWD/avfcameraservice_p.h \ $$PWD/avfcamerasession_p.h \ @@ -15,7 +14,6 @@ HEADERS += \ SOURCES += \ $$PWD/avfcameracontrol.mm \ - $$PWD/avfcamerametadatacontrol.mm \ $$PWD/avfimagecapturecontrol.mm \ $$PWD/avfcameraservice.mm \ $$PWD/avfcamerasession.mm \ diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol.mm b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol.mm index bfc667509..1e55fb770 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol.mm +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol.mm @@ -177,6 +177,17 @@ QAudioDeviceInfo AVFMediaPlayerControl::audioOutput() const #endif } +QMediaMetaData AVFMediaPlayerControl::metaData() const +{ + return m_metaData; +} + +void AVFMediaPlayerControl::setMetaData(const QMediaMetaData &metaData) +{ + m_metaData = metaData; + metaDataChanged(); +} + void AVFMediaPlayerControl::setPosition(qint64 pos) { m_session->setPosition(pos); diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol_p.h b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol_p.h index b4fd8dc5a..9b8018ecb 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol_p.h +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol_p.h @@ -94,6 +94,9 @@ public: bool setAudioOutput(const QAudioDeviceInfo &) override; QAudioDeviceInfo audioOutput() const override; + QMediaMetaData metaData() const override; + void setMetaData(const QMediaMetaData &metaData); + public Q_SLOTS: void setPosition(qint64 pos) override; @@ -106,6 +109,7 @@ public Q_SLOTS: private: AVFMediaPlayerSession *m_session; + QMediaMetaData m_metaData; }; QT_END_NAMESPACE diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice.mm b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice.mm index b300c4c1a..32cc5fd27 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice.mm +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice.mm @@ -40,7 +40,6 @@ #include "avfmediaplayerservice_p.h" #include "avfmediaplayersession_p.h" #include "avfmediaplayercontrol_p.h" -#include "avfmediaplayermetadatacontrol_p.h" #include "avfvideooutput_p.h" #if QT_CONFIG(opengl) #include "avfvideorenderercontrol_p.h" @@ -56,9 +55,6 @@ AVFMediaPlayerService::AVFMediaPlayerService() m_session = new AVFMediaPlayerSession(this); m_control = new AVFMediaPlayerControl(this); m_control->setSession(m_session); - m_playerMetaDataControl = new AVFMediaPlayerMetaDataControl(m_session, this); - - connect(m_control, SIGNAL(mediaChanged(QMediaContent)), m_playerMetaDataControl, SLOT(updateTags())); } AVFMediaPlayerService::~AVFMediaPlayerService() @@ -78,9 +74,6 @@ QObject *AVFMediaPlayerService::requestControl(const char *name) if (qstrcmp(name, QMediaPlayerControl_iid) == 0) return m_control; - if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) - return m_playerMetaDataControl; - #if QT_CONFIG(opengl) if (qstrcmp(name, QVideoRendererControl_iid) == 0) { if (!m_videoOutput) @@ -124,11 +117,6 @@ QMediaPlayerControl *AVFMediaPlayerService::player() return m_control; } -QMetaDataReaderControl *AVFMediaPlayerService::dataReader() -{ - return m_playerMetaDataControl; -} - QVideoRendererControl *AVFMediaPlayerService::createVideoRenderer() { if (m_videoOutput) @@ -152,20 +140,3 @@ QVideoWindowControl *AVFMediaPlayerService::createVideoWindow() m_session->setVideoOutput(control); return control; } - -#if 0 -void listSupportedMimeTypes() -{ - //Populate m_supportedMimeTypes with mimetypes AVAsset supports - NSArray *mimeTypes = [AVURLAsset audiovisualMIMETypes]; - for (NSString *mimeType in mimeTypes) - { - m_supportedMimeTypes.append(QString::fromUtf8([mimeType UTF8String])); - } -#ifdef QT_DEBUG_AVF - qDebug() << "AVFMediaPlayerServicePlugin::buildSupportedTypes"; - qDebug() << "Supported Types: " << m_supportedMimeTypes; -#endif - -} -#endif diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice_p.h b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice_p.h index f37c1e50f..2690c7828 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice_p.h +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice_p.h @@ -57,7 +57,6 @@ QT_BEGIN_NAMESPACE class AVFMediaPlayerSession; class AVFMediaPlayerControl; -class AVFMediaPlayerMetaDataControl; class AVFVideoOutput; class AVFMediaPlayerService : public QMediaPlatformPlayerInterface @@ -71,7 +70,6 @@ public: // QMediaPlatformPlayerInterface QMediaPlayerControl *player() override; - QMetaDataReaderControl *dataReader() override; // QMediaStreamsControl *streams() override; QVideoRendererControl *createVideoRenderer() override; @@ -82,7 +80,6 @@ private: AVFMediaPlayerSession *m_session = nullptr; AVFMediaPlayerControl *m_control = nullptr; QObject *m_videoOutput = nullptr; - AVFMediaPlayerMetaDataControl *m_playerMetaDataControl = nullptr; }; QT_END_NAMESPACE diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession.mm b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession.mm index 7fa6d25c6..386e66ecd 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession.mm +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession.mm @@ -39,7 +39,9 @@ #include "avfmediaplayersession_p.h" #include "avfmediaplayerservice_p.h" +#include "avfmediaplayercontrol_p.h" #include "avfvideooutput_p.h" +#include "avfmetadata_p.h" #include <qpointer.h> #include <QFileInfo> @@ -945,6 +947,10 @@ void AVFMediaPlayerSession::processLoadStateChange(QMediaPlayer::State newState) AVPlayerItem *playerItem = [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) playerItem]; + // get the meta data + QMediaMetaData metaData = AVFMetaData::fromAsset(playerItem.asset); + static_cast<AVFMediaPlayerControl *>(m_service->player())->setMetaData(metaData); + if (playerItem) { // Check each track for audio and video content AVAssetTrack *videoTrack = nil; diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayermetadatacontrol.mm b/src/multimedia/platform/darwin/mediaplayer/avfmetadata.mm index 5a5780e52..0b6feace4 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayermetadatacontrol.mm +++ b/src/multimedia/platform/darwin/mediaplayer/avfmetadata.mm @@ -37,8 +37,7 @@ ** ****************************************************************************/ -#include "avfmediaplayermetadatacontrol_p.h" -#include "avfmediaplayersession_p.h" +#include "avfmetadata_p.h" #include <QtMultimedia/qmediametadata.h> @@ -46,50 +45,15 @@ QT_USE_NAMESPACE -AVFMediaPlayerMetaDataControl::AVFMediaPlayerMetaDataControl(AVFMediaPlayerSession *session, QObject *parent) - : QMetaDataReaderControl(parent) - , m_session(session) - , m_asset(nullptr) -{ - QObject::connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(updateTags())); -} - -AVFMediaPlayerMetaDataControl::~AVFMediaPlayerMetaDataControl() -{ -#ifdef QT_DEBUG_AVF - qDebug() << Q_FUNC_INFO; -#endif -} - -bool AVFMediaPlayerMetaDataControl::isMetaDataAvailable() const -{ - return !m_tags.isEmpty(); -} - -bool AVFMediaPlayerMetaDataControl::isWritable() const -{ - return false; -} - -QVariant AVFMediaPlayerMetaDataControl::metaData(const QString &key) const -{ - return m_tags.value(key); -} - -QStringList AVFMediaPlayerMetaDataControl::availableMetaData() const -{ - return m_tags.keys(); -} - -static QString itemKey(AVMetadataItem *item) +static std::optional<QMediaMetaData::Key> itemKey(AVMetadataItem *item) { NSString *keyString = [item commonKey]; if (keyString.length != 0) { if ([keyString isEqualToString:AVMetadataCommonKeyTitle]) { return QMediaMetaData::Title; - } else if ([keyString isEqualToString: AVMetadataCommonKeySubject]) { - return QMediaMetaData::SubTitle; +// } else if ([keyString isEqualToString: AVMetadataCommonKeySubject]) { +// return QMediaMetaData::SubTitle; } else if ([keyString isEqualToString: AVMetadataCommonKeyDescription]) { return QMediaMetaData::Description; } else if ([keyString isEqualToString: AVMetadataCommonKeyPublisher]) { @@ -108,54 +72,32 @@ static QString itemKey(AVMetadataItem *item) return QMediaMetaData::Author; } else if ([keyString isEqualToString: AVMetadataCommonKeyArtist]) { return QMediaMetaData::ContributingArtist; - } else if ([keyString isEqualToString: AVMetadataCommonKeyArtwork]) { - return QMediaMetaData::PosterUrl; +// } else if ([keyString isEqualToString: AVMetadataCommonKeyArtwork]) { +// return QMediaMetaData::PosterUrl; } } - return QString(); + return std::nullopt; } -void AVFMediaPlayerMetaDataControl::updateTags() +QMediaMetaData AVFMetaData::fromAsset(AVAsset *asset) { #ifdef QT_DEBUG_AVF qDebug() << Q_FUNC_INFO; #endif - AVAsset *currentAsset = static_cast<AVAsset*>(m_session->currentAssetHandle()); - - //Don't read the tags from the same asset more than once - if (currentAsset == m_asset) - return; - - m_asset = currentAsset; - - QVariantMap oldTags = m_tags; - //Since we've changed assets, clear old tags - m_tags.clear(); - bool changed = false; + QMediaMetaData metaData; // TODO: also process ID3, iTunes and QuickTime metadata - NSArray *metadataItems = [currentAsset commonMetadata]; + NSArray *metadataItems = [asset commonMetadata]; for (AVMetadataItem* item in metadataItems) { - const QString key = itemKey(item); - if (!key.isEmpty()) { - const QString value = QString::fromNSString([item stringValue]); - if (!value.isNull()) { - m_tags.insert(key, value); - if (value != oldTags.value(key)) { - changed = true; - Q_EMIT metaDataChanged(key, value); - } - } - } - } + auto key = itemKey(item); + if (!key) + continue; - if (oldTags.isEmpty() != m_tags.isEmpty()) { - Q_EMIT metaDataAvailableChanged(!m_tags.isEmpty()); - changed = true; + const QString value = QString::fromNSString([item stringValue]); + if (!value.isNull()) + metaData.insert(*key, value); } - - if (changed) - Q_EMIT metaDataChanged(); + return metaData; } diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayermetadatacontrol_p.h b/src/multimedia/platform/darwin/mediaplayer/avfmetadata_p.h index 067aa2487..c88a4084d 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayermetadatacontrol_p.h +++ b/src/multimedia/platform/darwin/mediaplayer/avfmetadata_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include <QtMultimedia/QMetaDataReaderControl> +#include <QtMultimedia/QMediaMetaData> #include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -60,27 +60,10 @@ Q_FORWARD_DECLARE_OBJC_CLASS(AVAsset); class AVFMediaPlayerSession; -class AVFMediaPlayerMetaDataControl : public QMetaDataReaderControl +class AVFMetaData { - Q_OBJECT public: - explicit AVFMediaPlayerMetaDataControl(AVFMediaPlayerSession *session, QObject *parent = nullptr); - virtual ~AVFMediaPlayerMetaDataControl(); - - bool isMetaDataAvailable() const override; - bool isWritable() const; - - QVariant metaData(const QString &key) const override; - QStringList availableMetaData() const override; - -private Q_SLOTS: - void updateTags(); - -private: - AVFMediaPlayerSession *m_session; - QVariantMap m_tags; - AVAsset *m_asset; - + static QMediaMetaData fromAsset(AVAsset *asset); }; QT_END_NAMESPACE diff --git a/src/multimedia/platform/darwin/mediaplayer/mediaplayer.pri b/src/multimedia/platform/darwin/mediaplayer/mediaplayer.pri index 6c02ed23d..0aab9faa5 100644 --- a/src/multimedia/platform/darwin/mediaplayer/mediaplayer.pri +++ b/src/multimedia/platform/darwin/mediaplayer/mediaplayer.pri @@ -2,7 +2,7 @@ QT += opengl network HEADERS += \ $$PWD/avfmediaplayercontrol_p.h \ - $$PWD/avfmediaplayermetadatacontrol_p.h \ + $$PWD/avfmetadata_p.h \ $$PWD/avfmediaplayerservice_p.h \ $$PWD/avfmediaplayersession_p.h \ $$PWD/avfvideooutput_p.h \ @@ -10,7 +10,7 @@ HEADERS += \ SOURCES += \ $$PWD/avfmediaplayercontrol.mm \ - $$PWD/avfmediaplayermetadatacontrol.mm \ + $$PWD/avfmetadata.mm \ $$PWD/avfmediaplayerservice.mm \ $$PWD/avfmediaplayersession.mm \ $$PWD/avfvideooutput.mm \ diff --git a/src/multimedia/platform/gstreamer/common/common.pri b/src/multimedia/platform/gstreamer/common/common.pri index 54167b557..944e0ed60 100644 --- a/src/multimedia/platform/gstreamer/common/common.pri +++ b/src/multimedia/platform/gstreamer/common/common.pri @@ -2,6 +2,7 @@ HEADERS += \ $$PWD/qgstappsrc_p.h \ $$PWD/qgstreamerbushelper_p.h \ $$PWD/qgstreamermessage_p.h \ + $$PWD/qgstreamermetadata_p.h \ $$PWD/qgstutils_p.h \ $$PWD/qgstvideobuffer_p.h \ $$PWD/qgstreamerbufferprobe_p.h \ @@ -18,6 +19,7 @@ SOURCES += \ $$PWD/qgstappsrc.cpp \ $$PWD/qgstreamerbushelper.cpp \ $$PWD/qgstreamermessage.cpp \ + $$PWD/qgstreamermetadata.cpp \ $$PWD/qgstutils.cpp \ $$PWD/qgstvideobuffer.cpp \ $$PWD/qgstreamerbufferprobe.cpp \ diff --git a/src/multimedia/platform/gstreamer/common/qgstreamermetadata.cpp b/src/multimedia/platform/gstreamer/common/qgstreamermetadata.cpp new file mode 100644 index 000000000..494bc8167 --- /dev/null +++ b/src/multimedia/platform/gstreamer/common/qgstreamermetadata.cpp @@ -0,0 +1,290 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgstreamermetadata_p.h" +#include <private/qgstreamerplayersession_p.h> +#include <QDebug> +#include <QtMultimedia/qmediametadata.h> +#include <QtCore/qdatetime.h> + +#include <gst/gstversion.h> +#include <private/qgstutils_p.h> + +QT_BEGIN_NAMESPACE + +struct { + const char *tag; + QMediaMetaData::Key key; +} gstTagToMetaDataKey[] = { + { GST_TAG_TITLE, QMediaMetaData::Title }, + { GST_TAG_COMMENT, QMediaMetaData::Comment }, + { GST_TAG_DESCRIPTION, QMediaMetaData::Description }, + { GST_TAG_GENRE, QMediaMetaData::Genre }, + { "year", QMediaMetaData::Year }, + + { GST_TAG_LANGUAGE_CODE, QMediaMetaData::Language }, + + { GST_TAG_ORGANIZATION, QMediaMetaData::Publisher }, + { GST_TAG_COPYRIGHT, QMediaMetaData::Copyright }, + + // Media + { GST_TAG_DURATION, QMediaMetaData::Duration }, + + // Audio + { GST_TAG_BITRATE, QMediaMetaData::AudioBitRate }, + { GST_TAG_AUDIO_CODEC, QMediaMetaData::AudioCodec }, + + // Music + { GST_TAG_ALBUM, QMediaMetaData::AlbumTitle }, + { GST_TAG_ALBUM_ARTIST, QMediaMetaData::AlbumArtist }, + { GST_TAG_ARTIST, QMediaMetaData::ContributingArtist }, + { GST_TAG_TRACK_NUMBER, QMediaMetaData::TrackNumber }, + + { GST_TAG_PREVIEW_IMAGE, QMediaMetaData::ThumbnailImage }, + { GST_TAG_IMAGE, QMediaMetaData::CoverArtImage }, + + // Image/Video + { "resolution", QMediaMetaData::Resolution }, + { GST_TAG_IMAGE_ORIENTATION, QMediaMetaData::Orientation }, + + // Video + { GST_TAG_VIDEO_CODEC, QMediaMetaData::VideoCodec }, + + // Movie + { GST_TAG_PERFORMER, QMediaMetaData::LeadPerformer }, + + { nullptr, QMediaMetaData::Title } +}; + +static QMediaMetaData::Key tagToKey(const char *tag) +{ + auto *map = gstTagToMetaDataKey; + while (map->tag) { + if (!strcmp(map->tag, tag)) + return map->key; + ++map; + } + return QMediaMetaData::Key(-1); +} + +static const char *keyToTag(QMediaMetaData::Key key) +{ + auto *map = gstTagToMetaDataKey; + while (map->tag) { + if (map->key == key) + return map->tag; + ++map; + } + return nullptr; +} + +//internal +static void addTagToMap(const GstTagList *list, + const gchar *tag, + gpointer user_data) +{ + QMediaMetaData::Key key = tagToKey(tag); + if (key == QMediaMetaData::Key(-1)) + return; + + auto *map = reinterpret_cast<QHash<QMediaMetaData::Key, QVariant>* >(user_data); + + GValue val; + val.g_type = 0; + gst_tag_list_copy_value(&val, list, tag); + + + switch( G_VALUE_TYPE(&val) ) { + case G_TYPE_STRING: + { + const gchar *str_value = g_value_get_string(&val); + map->insert(key, QString::fromUtf8(str_value)); + break; + } + case G_TYPE_INT: + map->insert(key, g_value_get_int(&val)); + break; + case G_TYPE_UINT: + map->insert(key, g_value_get_uint(&val)); + break; + case G_TYPE_LONG: + map->insert(key, qint64(g_value_get_long(&val))); + break; + case G_TYPE_BOOLEAN: + map->insert(key, g_value_get_boolean(&val)); + break; + case G_TYPE_CHAR: + map->insert(key, g_value_get_schar(&val)); + break; + case G_TYPE_DOUBLE: + map->insert(key, g_value_get_double(&val)); + break; + default: + // GST_TYPE_DATE is a function, not a constant, so pull it out of the switch + if (G_VALUE_TYPE(&val) == G_TYPE_DATE) { + const GDate *date = (const GDate *)g_value_get_boxed(&val); + if (g_date_valid(date)) { + int year = g_date_get_year(date); + int month = g_date_get_month(date); + int day = g_date_get_day(date); + map->insert(key, QDate(year,month,day)); + if (!map->contains(QMediaMetaData::Year)) + map->insert(QMediaMetaData::Year, year); + } + } else if (G_VALUE_TYPE(&val) == GST_TYPE_DATE_TIME) { + const GstDateTime *dateTime = (const GstDateTime *)g_value_get_boxed(&val); + int year = gst_date_time_has_year(dateTime) ? gst_date_time_get_year(dateTime) : 0; + int month = gst_date_time_has_month(dateTime) ? gst_date_time_get_month(dateTime) : 0; + int day = gst_date_time_has_day(dateTime) ? gst_date_time_get_day(dateTime) : 0; + if (gst_date_time_has_time(dateTime)) { + int hour = gst_date_time_get_hour(dateTime); + int minute = gst_date_time_get_minute(dateTime); + int second = gst_date_time_get_second(dateTime); + float tz = gst_date_time_get_time_zone_offset(dateTime); + QDateTime dateTime(QDate(year, month, day), QTime(hour, minute, second), + Qt::OffsetFromUTC, tz * 60 * 60); + map->insert(key, dateTime); + } else if (year > 0 && month > 0 && day > 0) { + map->insert(key, QDate(year,month,day)); + } + if (!map->contains(QMediaMetaData::Year) && year > 0) + map->insert(QMediaMetaData::Year, year); + } else if (G_VALUE_TYPE(&val) == GST_TYPE_SAMPLE) { + GstSample *sample = (GstSample *)g_value_get_boxed(&val); + GstCaps* caps = gst_sample_get_caps(sample); + if (caps && !gst_caps_is_empty(caps)) { + GstStructure *structure = gst_caps_get_structure(caps, 0); + const gchar *name = gst_structure_get_name(structure); + if (QByteArray(name).startsWith("image/")) { + GstBuffer *buffer = gst_sample_get_buffer(sample); + if (buffer) { + GstMapInfo info; + gst_buffer_map(buffer, &info, GST_MAP_READ); + map->insert(key, QImage::fromData(info.data, info.size, name)); + gst_buffer_unmap(buffer, &info); + } + } + } + } else if (G_VALUE_TYPE(&val) == GST_TYPE_FRACTION) { + int nom = gst_value_get_fraction_numerator(&val); + int denom = gst_value_get_fraction_denominator(&val); + + if (denom > 0) { + map->insert(key, double(nom)/denom); + } + } + break; + } + + g_value_unset(&val); +} + + +QGstreamerMetaData QGstreamerMetaData::fromGstTagList(const GstTagList *tags) +{ + QGstreamerMetaData m; + gst_tag_list_foreach(tags, addTagToMap, &m.data); + return m; +} + + +void QGstreamerMetaData::setMetaData(GstElement *element) +{ + if (!GST_IS_TAG_SETTER(element)) + return; + + gst_tag_setter_reset_tags(GST_TAG_SETTER(element)); + + for (auto it = data.cbegin(), end = data.cend(); it != end; ++it) { + const char *tagName = keyToTag(it.key()); + const QVariant &tagValue = it.value(); + + switch (tagValue.typeId()) { + case QMetaType::QString: + gst_tag_setter_add_tags(GST_TAG_SETTER(element), + GST_TAG_MERGE_REPLACE, + tagName, + tagValue.toString().toUtf8().constData(), + nullptr); + break; + case QMetaType::Int: + case QMetaType::LongLong: + gst_tag_setter_add_tags(GST_TAG_SETTER(element), + GST_TAG_MERGE_REPLACE, + tagName, + tagValue.toInt(), + nullptr); + break; + case QMetaType::Double: + gst_tag_setter_add_tags(GST_TAG_SETTER(element), + GST_TAG_MERGE_REPLACE, + tagName, + tagValue.toDouble(), + nullptr); + break; + case QMetaType::QDateTime: { + QDateTime date = tagValue.toDateTime().toLocalTime(); + gst_tag_setter_add_tags(GST_TAG_SETTER(element), + GST_TAG_MERGE_REPLACE, + tagName, + gst_date_time_new_local_time( + date.date().year(), date.date().month(), date.date().day(), + date.time().hour(), date.time().minute(), date.time().second()), + nullptr); + break; + } + default: + break; + } + } +} + +void QGstreamerMetaData::setMetaData(GstBin *bin) +{ + GstIterator *elements = gst_bin_iterate_all_by_interface(bin, GST_TYPE_TAG_SETTER); + GValue item = G_VALUE_INIT; + while (gst_iterator_next(elements, &item) == GST_ITERATOR_OK) { + GstElement * const element = GST_ELEMENT(g_value_get_object(&item)); + setMetaData(element); + } + gst_iterator_free(elements); +} + + +QT_END_NAMESPACE diff --git a/src/multimedia/platform/qnx/mediaplayer/mmrenderermetadatareadercontrol_p.h b/src/multimedia/platform/gstreamer/common/qgstreamermetadata_p.h index f540f3f93..9088215a5 100644 --- a/src/multimedia/platform/qnx/mediaplayer/mmrenderermetadatareadercontrol_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstreamermetadata_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 Research In Motion +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Toolkit. @@ -36,8 +36,9 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef MMRENDERERMETADATAREADERCONTROL_H -#define MMRENDERERMETADATAREADERCONTROL_H + +#ifndef QGSTREAMERMETADATA_H +#define QGSTREAMERMETADATA_H // // W A R N I N G @@ -50,28 +51,25 @@ // We mean it. // -#include "mmrenderermetadata_p.h" -#include <qmetadatareadercontrol.h> +#include <qmediametadata.h> +#include <qvariant.h> + +#include <gst/gst.h> QT_BEGIN_NAMESPACE -class MmRendererMetaDataReaderControl : public QMetaDataReaderControl +class QGstreamerPlayerSession; + +class QGstreamerMetaData : public QMediaMetaData { - Q_OBJECT public: - explicit MmRendererMetaDataReaderControl(QObject *parent = 0); - - bool isMetaDataAvailable() const override; - - QVariant metaData(const QString &key) const override; - QStringList availableMetaData() const override; - - void setMetaData(const MmRendererMetaData &data); + static QGstreamerMetaData fromGstTagList(const GstTagList *tags); + GstTagList *toGstTagList() const; -private: - MmRendererMetaData m_metaData; + void setMetaData(GstBin *bin); + void setMetaData(GstElement *element); }; QT_END_NAMESPACE -#endif +#endif // QGSTREAMERMETADATA_H diff --git a/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol.cpp b/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol.cpp index ef4161748..c8fdd00a3 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol.cpp @@ -71,6 +71,7 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio connect(m_session, &QGstreamerPlayerSession::error, this, &QGstreamerPlayerControl::error); connect(m_session, &QGstreamerPlayerSession::invalidMedia, this, &QGstreamerPlayerControl::handleInvalidMedia); connect(m_session, &QGstreamerPlayerSession::playbackRateChanged, this, &QGstreamerPlayerControl::playbackRateChanged); + connect(m_session, &QGstreamerPlayerSession::metaDataChanged, this, &QGstreamerPlayerControl::metaDataChanged); } QGstreamerPlayerControl::~QGstreamerPlayerControl() @@ -379,6 +380,11 @@ QAudioDeviceInfo QGstreamerPlayerControl::audioOutput() const return m_session->audioOutputDevice(); } +QMediaMetaData QGstreamerPlayerControl::metaData() const +{ + return m_session->metaData(); +} + void QGstreamerPlayerControl::setVideoOutput(QObject *output) { m_session->setVideoRenderer(output); diff --git a/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol_p.h b/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol_p.h index 66deb54e7..1c4321663 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol_p.h @@ -99,6 +99,8 @@ public: bool setAudioOutput(const QAudioDeviceInfo &) override; QAudioDeviceInfo audioOutput() const override; + QMediaMetaData metaData() const override; + public Q_SLOTS: void setPosition(qint64 pos) override; diff --git a/src/multimedia/platform/gstreamer/common/qgstreamerplayersession.cpp b/src/multimedia/platform/gstreamer/common/qgstreamerplayersession.cpp index 92ec8d7ec..6f4bb61d5 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamerplayersession.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreamerplayersession.cpp @@ -43,6 +43,7 @@ #include <private/qgstreamervideorendererinterface_p.h> #include <private/qgstutils_p.h> #include <private/qgstvideorenderersink_p.h> +#include <private/qgstreamermetadata_p.h> #include <gst/gstvalue.h> #include <gst/base/gstbasesrc.h> @@ -247,8 +248,8 @@ void QGstreamerPlayerSession::loadFromStream(const QNetworkRequest &request, QIO m_appSrc->setStream(appSrcStream); if (!parsePipeline() && m_playbin) { - m_tags.clear(); - emit tagsChanged(); + m_metaData.clear(); + emit metaDataChanged(); g_object_set(G_OBJECT(m_playbin), "uri", "appsrc://", nullptr); @@ -279,8 +280,8 @@ void QGstreamerPlayerSession::loadFromUri(const QNetworkRequest &request) #endif if (!parsePipeline() && m_playbin) { - m_tags.clear(); - emit tagsChanged(); + m_metaData.clear(); + emit metaDataChanged(); g_object_set(G_OBJECT(m_playbin), "uri", m_request.url().toEncoded().constData(), nullptr); @@ -921,14 +922,11 @@ bool QGstreamerPlayerSession::processBusMessage(const QGstreamerMessage &message GstTagList *tag_list; gst_message_parse_tag(gm, &tag_list); - QMap<QByteArray, QVariant> newTags = QGstUtils::gstTagListToMap(tag_list); - QMap<QByteArray, QVariant>::const_iterator it = newTags.constBegin(); - for ( ; it != newTags.constEnd(); ++it) - m_tags.insert(it.key(), it.value()); // overwrite existing tags + m_metaData = QGstreamerMetaData::fromGstTagList(tag_list); gst_tag_list_free(tag_list); - emit tagsChanged(); + emit metaDataChanged(); } else if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_DURATION) { updateDuration(); } @@ -1207,7 +1205,7 @@ void QGstreamerPlayerSession::getStreamsInfo() if (!m_playbin) return; - QList< QMap<QString,QVariant> > oldProperties = m_streamProperties; + QList<QMediaMetaData> oldProperties = m_streamProperties; QList<QMediaStreamsControl::StreamType> oldTypes = m_streamTypes; QMap<QMediaStreamsControl::StreamType, int> oldOffset = m_playbin2StreamOffset; @@ -1244,7 +1242,7 @@ void QGstreamerPlayerSession::getStreamsInfo() for (int i=0; i<m_streamTypes.count(); i++) { QMediaStreamsControl::StreamType streamType = m_streamTypes[i]; - QMap<QString, QVariant> streamProperties; + QMediaMetaData streamProperties; int streamIndex = i - m_playbin2StreamOffset[streamType]; @@ -1322,22 +1320,16 @@ void QGstreamerPlayerSession::updateVideoResolutionTag() gst_object_unref(GST_OBJECT(pad)); - QSize currentSize = m_tags.value("resolution").toSize(); - QSize currentAspectRatio = m_tags.value("pixel-aspect-ratio").toSize(); - - if (currentSize != size || currentAspectRatio != aspectRatio) { - if (aspectRatio.isEmpty()) - m_tags.remove("pixel-aspect-ratio"); + QSize currentSize = m_metaData.value(QMediaMetaData::Resolution).toSize(); + if (currentSize != size) { if (size.isEmpty()) { - m_tags.remove("resolution"); + m_metaData.remove(QMediaMetaData::Resolution); } else { - m_tags.insert("resolution", QVariant(size)); - if (!aspectRatio.isEmpty()) - m_tags.insert("pixel-aspect-ratio", QVariant(aspectRatio)); + m_metaData.insert(QMediaMetaData::Resolution, QVariant(size)); } - emit tagsChanged(); + emit metaDataChanged(); } } diff --git a/src/multimedia/platform/gstreamer/common/qgstreamerplayersession_p.h b/src/multimedia/platform/gstreamer/common/qgstreamerplayersession_p.h index 187d942e7..1a3b329a7 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamerplayersession_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstreamerplayersession_p.h @@ -119,8 +119,7 @@ public: QMediaTimeRange availablePlaybackRanges() const; - QMap<QByteArray ,QVariant> tags() const { return m_tags; } - QMap<QString,QVariant> streamProperties(int streamNumber) const { return m_streamProperties[streamNumber]; } + QMediaMetaData streamProperties(int streamNumber) const { return m_streamProperties[streamNumber]; } int streamCount() const { return m_streamProperties.count(); } QMediaStreamsControl::StreamType streamType(int streamNumber) { return m_streamTypes.value(streamNumber, QMediaStreamsControl::UnknownStream); } @@ -143,6 +142,8 @@ public: void finishAudioOutputChange(); + QMediaMetaData metaData() const { return m_metaData; } + public slots: void loadFromUri(const QNetworkRequest &url); void loadFromStream(const QNetworkRequest &url, QIODevice *stream); @@ -167,7 +168,7 @@ signals: void videoAvailableChanged(bool videoAvailable); void bufferingProgressChanged(int percentFilled); void playbackFinished(); - void tagsChanged(); + void metaDataChanged(); void streamsChanged(); void seekableChanged(bool); void error(int error, const QString &errorString); @@ -229,8 +230,8 @@ private: QGstAppSrc *m_appSrc = nullptr; #endif - QMap<QByteArray, QVariant> m_tags; - QList< QMap<QString,QVariant> > m_streamProperties; + QMediaMetaData m_metaData; + QList<QMediaMetaData> m_streamProperties; QList<QMediaStreamsControl::StreamType> m_streamTypes; QMap<QMediaStreamsControl::StreamType, int> m_playbin2StreamOffset; diff --git a/src/multimedia/platform/gstreamer/common/qgstutils.cpp b/src/multimedia/platform/gstreamer/common/qgstutils.cpp index 2e44924b5..9baae11b7 100644 --- a/src/multimedia/platform/gstreamer/common/qgstutils.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstutils.cpp @@ -62,125 +62,6 @@ template<typename T, int N> static int lengthOf(const T (&)[N]) { return N; } QT_BEGIN_NAMESPACE -//internal -static void addTagToMap(const GstTagList *list, - const gchar *tag, - gpointer user_data) -{ - QMap<QByteArray, QVariant> *map = reinterpret_cast<QMap<QByteArray, QVariant>* >(user_data); - - GValue val; - val.g_type = 0; - gst_tag_list_copy_value(&val,list,tag); - - switch( G_VALUE_TYPE(&val) ) { - case G_TYPE_STRING: - { - const gchar *str_value = g_value_get_string(&val); - map->insert(QByteArray(tag), QString::fromUtf8(str_value)); - break; - } - case G_TYPE_INT: - map->insert(QByteArray(tag), g_value_get_int(&val)); - break; - case G_TYPE_UINT: - map->insert(QByteArray(tag), g_value_get_uint(&val)); - break; - case G_TYPE_LONG: - map->insert(QByteArray(tag), qint64(g_value_get_long(&val))); - break; - case G_TYPE_BOOLEAN: - map->insert(QByteArray(tag), g_value_get_boolean(&val)); - break; - case G_TYPE_CHAR: -#if GLIB_CHECK_VERSION(2,32,0) - map->insert(QByteArray(tag), g_value_get_schar(&val)); -#else - map->insert(QByteArray(tag), g_value_get_char(&val)); -#endif - break; - case G_TYPE_DOUBLE: - map->insert(QByteArray(tag), g_value_get_double(&val)); - break; - default: - // GST_TYPE_DATE is a function, not a constant, so pull it out of the switch - if (G_VALUE_TYPE(&val) == G_TYPE_DATE) { - const GDate *date = (const GDate *)g_value_get_boxed(&val); - if (g_date_valid(date)) { - int year = g_date_get_year(date); - int month = g_date_get_month(date); - int day = g_date_get_day(date); - map->insert(QByteArray(tag), QDate(year,month,day)); - if (!map->contains("year")) - map->insert("year", year); - } - } else if (G_VALUE_TYPE(&val) == GST_TYPE_DATE_TIME) { - const GstDateTime *dateTime = (const GstDateTime *)g_value_get_boxed(&val); - int year = gst_date_time_has_year(dateTime) ? gst_date_time_get_year(dateTime) : 0; - int month = gst_date_time_has_month(dateTime) ? gst_date_time_get_month(dateTime) : 0; - int day = gst_date_time_has_day(dateTime) ? gst_date_time_get_day(dateTime) : 0; - if (gst_date_time_has_time(dateTime)) { - int hour = gst_date_time_get_hour(dateTime); - int minute = gst_date_time_get_minute(dateTime); - int second = gst_date_time_get_second(dateTime); - float tz = gst_date_time_get_time_zone_offset(dateTime); - QDateTime dateTime(QDate(year, month, day), QTime(hour, minute, second), - Qt::OffsetFromUTC, tz * 60 * 60); - map->insert(QByteArray(tag), dateTime); - } else if (year > 0 && month > 0 && day > 0) { - map->insert(QByteArray(tag), QDate(year,month,day)); - } - if (!map->contains("year") && year > 0) - map->insert("year", year); - } else if (G_VALUE_TYPE(&val) == GST_TYPE_SAMPLE) { - GstSample *sample = (GstSample *)g_value_get_boxed(&val); - GstCaps* caps = gst_sample_get_caps(sample); - if (caps && !gst_caps_is_empty(caps)) { - GstStructure *structure = gst_caps_get_structure(caps, 0); - const gchar *name = gst_structure_get_name(structure); - if (QByteArray(name).startsWith("image/")) { - GstBuffer *buffer = gst_sample_get_buffer(sample); - if (buffer) { - GstMapInfo info; - gst_buffer_map(buffer, &info, GST_MAP_READ); - map->insert(QByteArray(tag), QImage::fromData(info.data, info.size, name)); - gst_buffer_unmap(buffer, &info); - } - } - } - } else if (G_VALUE_TYPE(&val) == GST_TYPE_FRACTION) { - int nom = gst_value_get_fraction_numerator(&val); - int denom = gst_value_get_fraction_denominator(&val); - - if (denom > 0) { - map->insert(QByteArray(tag), double(nom)/denom); - } - } - break; - } - - g_value_unset(&val); -} - -/*! - \class QGstUtils - \internal -*/ - -/*! - Convert GstTagList structure to QMap<QByteArray, QVariant>. - - Mapping to int, bool, char, string, fractions and date are supported. - Fraction values are converted to doubles. -*/ -QMap<QByteArray, QVariant> QGstUtils::gstTagListToMap(const GstTagList *tags) -{ - QMap<QByteArray, QVariant> res; - gst_tag_list_foreach(tags, addTagToMap, &res); - - return res; -} - /*! Returns resolution of \a caps. If caps doesn't have a valid size, an empty QSize is returned. diff --git a/src/multimedia/platform/gstreamer/common/qgstutils_p.h b/src/multimedia/platform/gstreamer/common/qgstutils_p.h index 8dee7b704..36de4d0e8 100644 --- a/src/multimedia/platform/gstreamer/common/qgstutils_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstutils_p.h @@ -72,8 +72,6 @@ class QImage; class QVideoSurfaceFormat; namespace QGstUtils { - Q_MULTIMEDIA_EXPORT QMap<QByteArray, QVariant> gstTagListToMap(const GstTagList *list); - Q_MULTIMEDIA_EXPORT QSize capsResolution(const GstCaps *caps); Q_MULTIMEDIA_EXPORT QSize capsCorrectedResolution(const GstCaps *caps); Q_MULTIMEDIA_EXPORT QAudioFormat audioFormatForCaps(const GstCaps *caps); diff --git a/src/multimedia/platform/gstreamer/mediacapture/mediacapture.pri b/src/multimedia/platform/gstreamer/mediacapture/mediacapture.pri index 5e8f76192..3f3b10f2c 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/mediacapture.pri +++ b/src/multimedia/platform/gstreamer/mediacapture/mediacapture.pri @@ -4,7 +4,6 @@ HEADERS += $$PWD/qgstreamercaptureservice_p.h \ $$PWD/qgstreamercapturesession_p.h \ $$PWD/qgstreamerrecordercontrol_p.h \ $$PWD/qgstreamercameracontrol_p.h \ - $$PWD/qgstreamercapturemetadatacontrol_p.h \ $$PWD/qgstreamerimagecapturecontrol_p.h \ $$PWD/qgstreamervideoinput_p.h @@ -12,7 +11,6 @@ SOURCES += $$PWD/qgstreamercaptureservice.cpp \ $$PWD/qgstreamercapturesession.cpp \ $$PWD/qgstreamerrecordercontrol.cpp \ $$PWD/qgstreamercameracontrol.cpp \ - $$PWD/qgstreamercapturemetadatacontrol.cpp \ $$PWD/qgstreamerimagecapturecontrol.cpp \ $$PWD/qgstreamervideoinput.cpp diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.cpp deleted file mode 100644 index ba4a757a3..000000000 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamercapturemetadatacontrol_p.h" - -#include <QtMultimedia/qmediametadata.h> - -#include <gst/gst.h> -#include <gst/gstversion.h> - - -typedef QMap<QString, QByteArray> QGstreamerMetaDataKeyLookup; -Q_GLOBAL_STATIC(QGstreamerMetaDataKeyLookup, metadataKeys) - -static const QGstreamerMetaDataKeyLookup *qt_gstreamerMetaDataKeys() -{ - if (metadataKeys->isEmpty()) { - metadataKeys->insert(QMediaMetaData::Title, GST_TAG_TITLE); - metadataKeys->insert(QMediaMetaData::SubTitle, 0); - //metadataKeys->insert(QMediaMetaData::Author, 0); - metadataKeys->insert(QMediaMetaData::Comment, GST_TAG_COMMENT); - metadataKeys->insert(QMediaMetaData::Date, GST_TAG_DATE_TIME); - metadataKeys->insert(QMediaMetaData::Description, GST_TAG_DESCRIPTION); - //metadataKeys->insert(QMediaMetaData::Category, 0); - metadataKeys->insert(QMediaMetaData::Genre, GST_TAG_GENRE); - //metadataKeys->insert(QMediaMetaData::Year, 0); - //metadataKeys->insert(QMediaMetaData::UserRating, 0); - - metadataKeys->insert(QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE); - - metadataKeys->insert(QMediaMetaData::Publisher, GST_TAG_ORGANIZATION); - metadataKeys->insert(QMediaMetaData::Copyright, GST_TAG_COPYRIGHT); - //metadataKeys->insert(QMediaMetaData::ParentalRating, 0); - //metadataKeys->insert(QMediaMetaData::RatingOrganisation, 0); - - // Media - //metadataKeys->insert(QMediaMetaData::Size, 0); - //metadataKeys->insert(QMediaMetaData::MediaType, 0); - metadataKeys->insert(QMediaMetaData::Duration, GST_TAG_DURATION); - - // Audio - metadataKeys->insert(QMediaMetaData::AudioBitRate, GST_TAG_BITRATE); - metadataKeys->insert(QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC); - //metadataKeys->insert(QMediaMetaData::ChannelCount, 0); - //metadataKeys->insert(QMediaMetaData::SampleRate, 0); - - // Music - metadataKeys->insert(QMediaMetaData::AlbumTitle, GST_TAG_ALBUM); - metadataKeys->insert(QMediaMetaData::AlbumArtist, GST_TAG_ARTIST); - metadataKeys->insert(QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER); - metadataKeys->insert(QMediaMetaData::Composer, GST_TAG_COMPOSER); - //metadataKeys->insert(QMediaMetaData::Conductor, 0); - //metadataKeys->insert(QMediaMetaData::Lyrics, 0); - //metadataKeys->insert(QMediaMetaData::Mood, 0); - metadataKeys->insert(QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER); - - //metadataKeys->insert(QMediaMetaData::CoverArtUrlSmall, 0); - //metadataKeys->insert(QMediaMetaData::CoverArtUrlLarge, 0); - - // Image/Video - //metadataKeys->insert(QMediaMetaData::Resolution, 0); - //metadataKeys->insert(QMediaMetaData::PixelAspectRatio, 0); - - // Video - //metadataKeys->insert(QMediaMetaData::VideoFrameRate, 0); - //metadataKeys->insert(QMediaMetaData::VideoBitRate, 0); - metadataKeys->insert(QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC); - - //metadataKeys->insert(QMediaMetaData::PosterUrl, 0); - - // Movie - //metadataKeys->insert(QMediaMetaData::ChapterNumber, 0); - //metadataKeys->insert(QMediaMetaData::Director, 0); - metadataKeys->insert(QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER); - //metadataKeys->insert(QMediaMetaData::Writer, 0); - - // Photos - metadataKeys->insert(QMediaMetaData::CameraManufacturer, GST_TAG_DEVICE_MANUFACTURER); - metadataKeys->insert(QMediaMetaData::CameraModel, GST_TAG_DEVICE_MODEL); - //metadataKeys->insert(QMediaMetaData::Event, 0, QMetaType::QString)); - //metadataKeys->insert(QMediaMetaData::Subject, 0, QMetaType::QString)); - - metadataKeys->insert(QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION); - - // GPS - metadataKeys->insert(QMediaMetaData::GPSLatitude, GST_TAG_GEO_LOCATION_LATITUDE); - metadataKeys->insert(QMediaMetaData::GPSLongitude, GST_TAG_GEO_LOCATION_LONGITUDE); - metadataKeys->insert(QMediaMetaData::GPSAltitude, GST_TAG_GEO_LOCATION_ELEVATION); - metadataKeys->insert(QMediaMetaData::GPSTrack, GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION); - metadataKeys->insert(QMediaMetaData::GPSSpeed, GST_TAG_GEO_LOCATION_MOVEMENT_SPEED); - metadataKeys->insert(QMediaMetaData::GPSImgDirection, GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION); - } - - return metadataKeys; -} - -QGstreamerCaptureMetaDataControl::QGstreamerCaptureMetaDataControl(QObject *parent) - :QMetaDataWriterControl(parent) -{ -} - -QVariant QGstreamerCaptureMetaDataControl::metaData(const QString &key) const -{ - QGstreamerMetaDataKeyLookup::const_iterator it = qt_gstreamerMetaDataKeys()->find(key); - if (it != qt_gstreamerMetaDataKeys()->constEnd()) - return m_values.value(it.value()); - - return QVariant(); -} - -void QGstreamerCaptureMetaDataControl::setMetaData(const QString &key, const QVariant &value) -{ - QGstreamerMetaDataKeyLookup::const_iterator it = qt_gstreamerMetaDataKeys()->find(key); - if (it != qt_gstreamerMetaDataKeys()->constEnd()) { - m_values.insert(it.value(), value); - - emit QMetaDataWriterControl::metaDataChanged(); - emit QMetaDataWriterControl::metaDataChanged(key, value); - emit metaDataChanged(m_values); - } -} - -QStringList QGstreamerCaptureMetaDataControl::availableMetaData() const -{ - QStringList res; - for (auto it = m_values.keyBegin(), end = m_values.keyEnd(); it != end; ++it) { - QString tag = qt_gstreamerMetaDataKeys()->key(*it); - if (!tag.isEmpty()) - res.append(tag); - } - - return res; -} diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturemetadatacontrol_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturemetadatacontrol_p.h deleted file mode 100644 index 6e2106019..000000000 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturemetadatacontrol_p.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERCAPTUREMETADATACONTROL_H -#define QGSTREAMERCAPTUREMETADATACONTROL_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <qmetadatawritercontrol.h> -#include <qvariant.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerCaptureMetaDataControl : public QMetaDataWriterControl -{ - Q_OBJECT -public: - QGstreamerCaptureMetaDataControl(QObject *parent); - ~QGstreamerCaptureMetaDataControl() {} - - - bool isMetaDataAvailable() const override { return true; } - bool isWritable() const override { return true; } - - QVariant metaData(const QString &key) const override; - void setMetaData(const QString &key, const QVariant &value) override; - QStringList availableMetaData() const override; - -Q_SIGNALS: - void metaDataChanged(const QMap<QByteArray, QVariant>&); - -private: - QMap<QByteArray, QVariant> m_values; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERCAPTUREMETADATACONTROL_H diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercaptureservice.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercaptureservice.cpp index 191fb4575..56ba1da3e 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercaptureservice.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercaptureservice.cpp @@ -42,7 +42,6 @@ #include "qgstreamerrecordercontrol_p.h" #include "qgstreamercameracontrol_p.h" #include <private/qgstreamerbushelper_p.h> -#include "qgstreamercapturemetadatacontrol_p.h" #if defined(USE_GSTREAMER_CAMERA) #include "qgstreamervideoinput_p.h" diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession.cpp index 578e4d511..528d295c9 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession.cpp @@ -862,13 +862,13 @@ void QGstreamerCaptureSession::setAudioCaptureDevice(const QAudioDeviceInfo &dev m_audioDevice = device; } -void QGstreamerCaptureSession::setMetaData(const QMap<QByteArray, QVariant> &data) +void QGstreamerCaptureSession::setMetaData(const QGstreamerMetaData &data) { //qDebug() << "QGstreamerCaptureSession::setMetaData" << data; m_metaData = data; if (m_encodeBin) - QGstUtils::setMetaData(GST_BIN(m_encodeBin), data); + m_metaData.setMetaData(GST_BIN(m_encodeBin)); } bool QGstreamerCaptureSession::processBusMessage(const QGstreamerMessage &message) diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession_p.h index fc16b1d6a..56641af49 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession_p.h +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession_p.h @@ -63,6 +63,7 @@ #include <private/qgstreamerbushelper_p.h> #include <private/qgstreamerbufferprobe_p.h> +#include <private/qgstreamermetadata_p.h> QT_BEGIN_NAMESPACE @@ -157,7 +158,7 @@ public slots: void dumpGraph(const QString &fileName); - void setMetaData(const QMap<QByteArray, QVariant>&); + void setMetaData(const QGstreamerMetaData &); void setMuted(bool); void setVolume(qreal volume); @@ -184,7 +185,7 @@ private: bool m_waitingForEos; PipelineMode m_pipelineMode; QGstreamerCaptureSession::CaptureMode m_captureMode; - QMap<QByteArray, QVariant> m_metaData; + QGstreamerMetaData m_metaData; QGstreamerElementFactory *m_audioPreviewFactory; QGstreamerVideoInput *m_videoInputFactory; diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp index caeec0994..5c13fccb4 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "qgstreamerrecordercontrol_p.h" -#include "qgstreamercapturemetadatacontrol_p.h" #include <QtCore/QDebug> #include <QtGui/qdesktopservices.h> #include <QStandardPaths> @@ -57,15 +56,10 @@ QGstreamerRecorderControl::QGstreamerRecorderControl(QGstreamerCaptureSession *s connect(m_session, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged(bool))); connect(m_session, SIGNAL(volumeChanged(qreal)), SIGNAL(volumeChanged(qreal))); m_hasPreviewState = m_session->captureMode() != QGstreamerCaptureSession::Audio; - - m_metaData = new QGstreamerCaptureMetaDataControl(this); - connect(m_metaData, SIGNAL(metaDataChanged(QMap<QByteArray,QVariant>)), - m_session, SLOT(setMetaData(QMap<QByteArray,QVariant>))); } QGstreamerRecorderControl::~QGstreamerRecorderControl() { - delete m_metaData; } QUrl QGstreamerRecorderControl::outputLocation() const @@ -243,7 +237,12 @@ QMediaEncoderSettings QGstreamerRecorderControl::resolvedEncoderSettings() const return f; } -QMetaDataWriterControl *QGstreamerRecorderControl::metaDataControl() +void QGstreamerRecorderControl::setMetaData(const QMediaMetaData &metaData) +{ + m_metaData = static_cast<const QGstreamerMetaData &>(metaData); +} + +QMediaMetaData QGstreamerRecorderControl::metaData() const { return m_metaData; } diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamerrecordercontrol_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamerrecordercontrol_p.h index 340337058..0196ef835 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamerrecordercontrol_p.h +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamerrecordercontrol_p.h @@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE class QGstreamerCaptureMetaDataControl; +class QMediaMetaData; class QGstreamerRecorderControl : public QMediaRecorderControl { @@ -89,7 +90,8 @@ public: QMediaEncoderSettings encoderSettings() const { return m_settings; } QMediaEncoderSettings resolvedEncoderSettings() const; - QMetaDataWriterControl *metaDataControl() override; + void setMetaData(const QMediaMetaData &) override; + QMediaMetaData metaData() const override; public slots: void setState(QMediaRecorder::State state) override; @@ -110,7 +112,7 @@ private: QUrl m_outputLocation; QMediaEncoderSettings m_settings; QGstreamerCaptureSession *m_session; - QGstreamerCaptureMetaDataControl *m_metaData = nullptr;; + QGstreamerMetaData m_metaData; QMediaRecorder::State m_state; QMediaRecorder::Status m_status; bool m_hasPreviewState; diff --git a/src/multimedia/platform/gstreamer/mediaplayer/mediaplayer.pri b/src/multimedia/platform/gstreamer/mediaplayer/mediaplayer.pri index 1a0d7cefc..1071b25a2 100644 --- a/src/multimedia/platform/gstreamer/mediaplayer/mediaplayer.pri +++ b/src/multimedia/platform/gstreamer/mediaplayer/mediaplayer.pri @@ -3,9 +3,7 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/qgstreamerplayerservice_p.h \ $$PWD/qgstreamerstreamscontrol_p.h \ - $$PWD/qgstreamermetadataprovider_p.h SOURCES += \ $$PWD/qgstreamerplayerservice.cpp \ $$PWD/qgstreamerstreamscontrol.cpp \ - $$PWD/qgstreamermetadataprovider.cpp diff --git a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp deleted file mode 100644 index 578bbb8db..000000000 --- a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgstreamermetadataprovider_p.h" -#include <private/qgstreamerplayersession_p.h> -#include <QDebug> -#include <QtMultimedia/qmediametadata.h> - -#include <gst/gstversion.h> -#include <private/qgstutils_p.h> - -QT_BEGIN_NAMESPACE - -typedef QMap<QByteArray, QString> QGstreamerMetaDataKeyLookup; -Q_GLOBAL_STATIC(QGstreamerMetaDataKeyLookup, metadataKeys) - -static const QGstreamerMetaDataKeyLookup *qt_gstreamerMetaDataKeys() -{ - if (metadataKeys->isEmpty()) { - metadataKeys->insert(GST_TAG_TITLE, QMediaMetaData::Title); - //metadataKeys->insert(0, QMediaMetaData::SubTitle); - //metadataKeys->insert(0, QMediaMetaData::Author); - metadataKeys->insert(GST_TAG_COMMENT, QMediaMetaData::Comment); - metadataKeys->insert(GST_TAG_DESCRIPTION, QMediaMetaData::Description); - //metadataKeys->insert(0, QMediaMetaData::Category); - metadataKeys->insert(GST_TAG_GENRE, QMediaMetaData::Genre); - metadataKeys->insert("year", QMediaMetaData::Year); - //metadataKeys->insert(0, QMediaMetaData::UserRating); - - metadataKeys->insert(GST_TAG_LANGUAGE_CODE, QMediaMetaData::Language); - - metadataKeys->insert(GST_TAG_ORGANIZATION, QMediaMetaData::Publisher); - metadataKeys->insert(GST_TAG_COPYRIGHT, QMediaMetaData::Copyright); - //metadataKeys->insert(0, QMediaMetaData::ParentalRating); - //metadataKeys->insert(0, QMediaMetaData::RatingOrganisation); - - // Media - //metadataKeys->insert(0, QMediaMetaData::Size); - //metadataKeys->insert(0,QMediaMetaData::MediaType ); - metadataKeys->insert(GST_TAG_DURATION, QMediaMetaData::Duration); - - // Audio - metadataKeys->insert(GST_TAG_BITRATE, QMediaMetaData::AudioBitRate); - metadataKeys->insert(GST_TAG_AUDIO_CODEC, QMediaMetaData::AudioCodec); - //metadataKeys->insert(0, QMediaMetaData::ChannelCount); - //metadataKeys->insert(0, QMediaMetaData::SampleRate); - - // Music - metadataKeys->insert(GST_TAG_ALBUM, QMediaMetaData::AlbumTitle); - metadataKeys->insert(GST_TAG_ALBUM_ARTIST, QMediaMetaData::AlbumArtist); - metadataKeys->insert(GST_TAG_ARTIST, QMediaMetaData::ContributingArtist); - //metadataKeys->insert(0, QMediaMetaData::Conductor); - //metadataKeys->insert(0, QMediaMetaData::Lyrics); - //metadataKeys->insert(0, QMediaMetaData::Mood); - metadataKeys->insert(GST_TAG_TRACK_NUMBER, QMediaMetaData::TrackNumber); - - //metadataKeys->insert(0, QMediaMetaData::CoverArtUrlSmall); - //metadataKeys->insert(0, QMediaMetaData::CoverArtUrlLarge); - metadataKeys->insert(GST_TAG_PREVIEW_IMAGE, QMediaMetaData::ThumbnailImage); - metadataKeys->insert(GST_TAG_IMAGE, QMediaMetaData::CoverArtImage); - - // Image/Video - metadataKeys->insert("resolution", QMediaMetaData::Resolution); - metadataKeys->insert("pixel-aspect-ratio", QMediaMetaData::PixelAspectRatio); - metadataKeys->insert(GST_TAG_IMAGE_ORIENTATION, QMediaMetaData::Orientation); - - // Video - //metadataKeys->insert(0, QMediaMetaData::VideoFrameRate); - //metadataKeys->insert(0, QMediaMetaData::VideoBitRate); - metadataKeys->insert(GST_TAG_VIDEO_CODEC, QMediaMetaData::VideoCodec); - - //metadataKeys->insert(0, QMediaMetaData::PosterUrl); - - // Movie - //metadataKeys->insert(0, QMediaMetaData::ChapterNumber); - //metadataKeys->insert(0, QMediaMetaData::Director); - metadataKeys->insert(GST_TAG_PERFORMER, QMediaMetaData::LeadPerformer); - //metadataKeys->insert(0, QMediaMetaData::Writer); - - // Photos - //metadataKeys->insert(0, QMediaMetaData::CameraManufacturer); - //metadataKeys->insert(0, QMediaMetaData::CameraModel); - //metadataKeys->insert(0, QMediaMetaData::Event); - //metadataKeys->insert(0, QMediaMetaData::Subject); - } - - return metadataKeys; -} - -QGstreamerMetaDataProvider::QGstreamerMetaDataProvider(QGstreamerPlayerSession *session, QObject *parent) - :QMetaDataReaderControl(parent), m_session(session) -{ - connect(m_session, SIGNAL(tagsChanged()), SLOT(updateTags())); -} - -QGstreamerMetaDataProvider::~QGstreamerMetaDataProvider() -{ -} - -bool QGstreamerMetaDataProvider::isMetaDataAvailable() const -{ - return !m_session->tags().isEmpty(); -} - -bool QGstreamerMetaDataProvider::isWritable() const -{ - return false; -} - -QVariant QGstreamerMetaDataProvider::metaData(const QString &key) const -{ - if (key == QMediaMetaData::Orientation) - return QGstUtils::fromGStreamerOrientation(m_tags.value(key)); - return m_tags.value(key); -} - -QStringList QGstreamerMetaDataProvider::availableMetaData() const -{ - return m_tags.keys(); -} - -void QGstreamerMetaDataProvider::updateTags() -{ - QVariantMap oldTags = m_tags; - m_tags.clear(); - bool changed = false; - - const auto tags = m_session->tags(); - for (auto i = tags.cbegin(), end = tags.cend(); i != end; ++i) { - //use gstreamer native keys for elements not in our key map - QString key = qt_gstreamerMetaDataKeys()->value(i.key(), i.key()); - m_tags.insert(key, i.value()); - if (i.value() != oldTags.value(key)) { - changed = true; - emit metaDataChanged(key, i.value()); - } - } - - if (oldTags.isEmpty() != m_tags.isEmpty()) { - emit metaDataAvailableChanged(isMetaDataAvailable()); - changed = true; - } - - if (changed) - emit metaDataChanged(); -} - -QT_END_NAMESPACE diff --git a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamermetadataprovider_p.h b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamermetadataprovider_p.h deleted file mode 100644 index 468ab060b..000000000 --- a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamermetadataprovider_p.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGSTREAMERMETADATAPROVIDER_H -#define QGSTREAMERMETADATAPROVIDER_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <qmetadatareadercontrol.h> -#include <qvariant.h> - -QT_BEGIN_NAMESPACE - -class QGstreamerPlayerSession; - -class QGstreamerMetaDataProvider : public QMetaDataReaderControl -{ - Q_OBJECT -public: - QGstreamerMetaDataProvider( QGstreamerPlayerSession *session, QObject *parent ); - virtual ~QGstreamerMetaDataProvider(); - - bool isMetaDataAvailable() const override; - bool isWritable() const; - - QVariant metaData(const QString &key) const override; - QStringList availableMetaData() const override; - -private slots: - void updateTags(); - -private: - QGstreamerPlayerSession *m_session = nullptr; - QVariantMap m_tags; -}; - -QT_END_NAMESPACE - -#endif // QGSTREAMERMETADATAPROVIDER_H diff --git a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice.cpp b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice.cpp index 6da43f03b..3a00d7673 100644 --- a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice.cpp +++ b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice.cpp @@ -43,7 +43,6 @@ #include "qgstreamerplayerservice_p.h" -#include "qgstreamermetadataprovider_p.h" #include <private/qgstreamervideowindow_p.h> #include <private/qgstreamervideorenderer_p.h> @@ -59,7 +58,6 @@ QGstreamerPlayerService::QGstreamerPlayerService() { m_session = new QGstreamerPlayerSession(this); m_control = new QGstreamerPlayerControl(m_session, this); - m_metaData = new QGstreamerMetaDataProvider(m_session, this); m_streamsControl = new QGstreamerStreamsControl(m_session,this); m_videoRenderer = new QGstreamerVideoRenderer(this); m_videoWindow = new QGstreamerVideoWindow(this); @@ -80,9 +78,6 @@ QObject *QGstreamerPlayerService::requestControl(const char *name) if (qstrcmp(name,QMediaPlayerControl_iid) == 0) return m_control; - if (qstrcmp(name,QMetaDataReaderControl_iid) == 0) - return m_metaData; - if (!m_videoOutput) { if (qstrcmp(name, QVideoRendererControl_iid) == 0) m_videoOutput = m_videoRenderer; @@ -116,11 +111,6 @@ QMediaPlayerControl *QGstreamerPlayerService::player() return m_control; } -QMetaDataReaderControl *QGstreamerPlayerService::dataReader() -{ - return m_metaData; -} - QMediaStreamsControl *QGstreamerPlayerService::streams() { return m_streamsControl; @@ -160,32 +150,4 @@ void QGstreamerPlayerService::decreaseVideoRef() m_videoReferenceCount--; } -#if 0 -// ### Re-add something similar to be able to check for support of certain file formats -QMultimedia::SupportEstimate QGstreamerPlayerServicePlugin::hasSupport(const QString &mimeType, - const QStringList &codecs) const -{ - if (m_supportedMimeTypeSet.isEmpty()) - updateSupportedMimeTypes(); - - return QGstUtils::hasSupport(mimeType, codecs, m_supportedMimeTypeSet); -} - -static bool isDecoderOrDemuxer(GstElementFactory *factory) -{ - return gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DEMUXER) - || gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_DECODER); -} - -void QGstreamerPlayerServicePlugin::updateSupportedMimeTypes() const -{ - m_supportedMimeTypeSet = QGstUtils::supportedMimeTypes(isDecoderOrDemuxer); -} - -QStringList QGstreamerPlayerServicePlugin::supportedMimeTypes() const -{ - return QStringList(); -} -#endif - QT_END_NAMESPACE diff --git a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice_p.h b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice_p.h index 0a7663e51..52cd7f848 100644 --- a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice_p.h +++ b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice_p.h @@ -62,7 +62,6 @@ class QMediaPlayerControl; class QGstreamerMetaData; class QGstreamerPlayerControl; class QGstreamerPlayerSession; -class QGstreamerMetaDataProvider; class QGstreamerStreamsControl; class QGstreamerVideoRenderer; class QGstreamerVideoWindow; @@ -81,7 +80,6 @@ public: // QMediaPlatformPlayerInterface QMediaPlayerControl *player() override; - QMetaDataReaderControl *dataReader() override; QMediaStreamsControl *streams() override; QVideoRendererControl *createVideoRenderer() override; @@ -90,7 +88,6 @@ public: private: QGstreamerPlayerControl *m_control = nullptr; QGstreamerPlayerSession *m_session = nullptr; - QGstreamerMetaDataProvider *m_metaData = nullptr; QGstreamerStreamsControl *m_streamsControl = nullptr; QObject *m_videoOutput = nullptr; diff --git a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp index a4a2f46ec..4dc36fca4 100644 --- a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp +++ b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerstreamscontrol.cpp @@ -60,9 +60,9 @@ QMediaStreamsControl::StreamType QGstreamerStreamsControl::streamType(int stream return m_session->streamType(streamNumber); } -QVariant QGstreamerStreamsControl::metaData(int streamNumber, const QString &key) +QMediaMetaData QGstreamerStreamsControl::metaData(int streamNumber) { - return m_session->streamProperties(streamNumber).value(key); + return m_session->streamProperties(streamNumber); } bool QGstreamerStreamsControl::isActive(int streamNumber) diff --git a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerstreamscontrol_p.h b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerstreamscontrol_p.h index 730dcba3a..57d57045a 100644 --- a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerstreamscontrol_p.h +++ b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerstreamscontrol_p.h @@ -67,7 +67,7 @@ public: int streamCount() override; StreamType streamType(int streamNumber) override; - QVariant metaData(int streamNumber, const QString &key) override; + QMediaMetaData metaData(int streamNumber) override; bool isActive(int streamNumber) override; void setActive(int streamNumber, bool state) override; diff --git a/src/multimedia/platform/qmediaplatformplayerinterface_p.h b/src/multimedia/platform/qmediaplatformplayerinterface_p.h index a58cae316..b3598eb86 100644 --- a/src/multimedia/platform/qmediaplatformplayerinterface_p.h +++ b/src/multimedia/platform/qmediaplatformplayerinterface_p.h @@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE class QMediaPlayerControl; -class QMetaDataReaderControl; class QMediaStreamsControl; class QVideoRendererControl; class QVideoWindowControl; @@ -68,7 +67,6 @@ public: virtual ~QMediaPlatformPlayerInterface(); virtual QMediaPlayerControl *player() = 0; - virtual QMetaDataReaderControl *dataReader() { return nullptr; } // ### nothing in the frontend uses the stream info currently. Needs implementation in QMediaPlayer virtual QMediaStreamsControl *streams() { return nullptr; } diff --git a/src/multimedia/platform/qnx/mediaplayer/mediaplayer.pri b/src/multimedia/platform/qnx/mediaplayer/mediaplayer.pri index a44790b7d..5ab7516ab 100644 --- a/src/multimedia/platform/qnx/mediaplayer/mediaplayer.pri +++ b/src/multimedia/platform/qnx/mediaplayer/mediaplayer.pri @@ -4,7 +4,6 @@ HEADERS += \ $$PWD/mmrenderermediaplayercontrol_p.h \ $$PWD/mmrenderermediaplayerservice_p.h \ $$PWD/mmrenderermetadata_p.h \ - $$PWD/mmrenderermetadatareadercontrol_p.h \ $$PWD/mmrendererplayervideorenderercontrol_p.h \ $$PWD/mmrendererutil_p.h \ $$PWD/mmrenderervideowindowcontrol_p.h \ @@ -14,7 +13,6 @@ SOURCES += \ $$PWD/mmrenderermediaplayercontrol.cpp \ $$PWD/mmrenderermediaplayerservice.cpp \ $$PWD/mmrenderermetadata.cpp \ - $$PWD/mmrenderermetadatareadercontrol.cpp \ $$PWD/mmrendererplayervideorenderercontrol.cpp \ $$PWD/mmrendererutil.cpp \ $$PWD/mmrenderervideowindowcontrol.cpp \ diff --git a/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp b/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp index 6c622c275..b253ab36b 100644 --- a/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp +++ b/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp @@ -39,7 +39,6 @@ #include "mmrendereraudiorolecontrol_p.h" #include "mmrenderercustomaudiorolecontrol_p.h" #include "mmrenderermediaplayercontrol_p.h" -#include "mmrenderermetadatareadercontrol_p.h" #include "mmrendererplayervideorenderercontrol_p.h" #include "mmrendererutil_p.h" #include "mmrenderervideowindowcontrol_p.h" @@ -599,11 +598,6 @@ void MmRendererMediaPlayerControl::setVideoWindowControl(MmRendererVideoWindowCo m_videoWindowControl = videoControl; } -void MmRendererMediaPlayerControl::setMetaDataReaderControl(MmRendererMetaDataReaderControl *metaDataReaderControl) -{ - m_metaDataReaderControl = metaDataReaderControl; -} - void MmRendererMediaPlayerControl::setMmPosition(qint64 newPosition) { if (newPosition != 0 && newPosition != m_position) { @@ -635,9 +629,7 @@ void MmRendererMediaPlayerControl::updateMetaData(const strm_dict *dict) if (m_videoWindowControl) m_videoWindowControl->setMetaData(m_metaData); - if (m_metaDataReaderControl) - m_metaDataReaderControl->setMetaData(m_metaData); - + // ### convert to QMediaMetaData and notify the player about metadata changes emit durationChanged(m_metaData.duration()); emit audioAvailableChanged(m_metaData.hasAudio()); emit videoAvailableChanged(m_metaData.hasVideo()); diff --git a/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol_p.h b/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol_p.h index d6a75c597..f65db2eb4 100644 --- a/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol_p.h +++ b/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayercontrol_p.h @@ -65,7 +65,6 @@ QT_BEGIN_NAMESPACE class MmRendererAudioRoleControl; class MmRendererCustomAudioRoleControl; -class MmRendererMetaDataReaderControl; class MmRendererPlayerVideoRendererControl; class MmRendererVideoWindowControl; @@ -121,7 +120,6 @@ public: MmRendererVideoWindowControl *videoWindowControl() const; void setVideoWindowControl(MmRendererVideoWindowControl *videoControl); - void setMetaDataReaderControl(MmRendererMetaDataReaderControl *metaDataReaderControl); protected: virtual void startMonitoring() = 0; @@ -178,7 +176,6 @@ private: qreal m_rate; QPointer<MmRendererPlayerVideoRendererControl> m_videoRendererControl; QPointer<MmRendererVideoWindowControl> m_videoWindowControl; - QPointer<MmRendererMetaDataReaderControl> m_metaDataReaderControl; MmRendererMetaData m_metaData; qint64 m_position; QMediaPlayer::MediaStatus m_mediaStatus; diff --git a/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayerservice.cpp b/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayerservice.cpp index 407a54c83..00b4e76bb 100644 --- a/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayerservice.cpp +++ b/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayerservice.cpp @@ -39,7 +39,6 @@ #include "mmrenderermediaplayerservice_p.h" #include "mmrenderermediaplayercontrol_p.h" -#include "mmrenderermetadatareadercontrol_p.h" #include "mmrendererplayervideorenderercontrol_p.h" #include "mmrendererutil_p.h" #include "mmrenderervideowindowcontrol_p.h" @@ -53,7 +52,6 @@ MmRendererMediaPlayerService::MmRendererMediaPlayerService(QObject *parent) m_videoRendererControl(0), m_videoWindowControl(0), m_mediaPlayerControl(0), - m_metaDataReaderControl(0), m_appHasDrmPermission(false), m_appHasDrmPermissionChecked(false) { @@ -65,7 +63,6 @@ MmRendererMediaPlayerService::~MmRendererMediaPlayerService() delete m_videoRendererControl; delete m_videoWindowControl; delete m_mediaPlayerControl; - delete m_metaDataReaderControl; } QObject *MmRendererMediaPlayerService::requestControl(const char *name) @@ -76,12 +73,6 @@ QObject *MmRendererMediaPlayerService::requestControl(const char *name) updateControls(); } return m_mediaPlayerControl; - } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) { - if (!m_metaDataReaderControl) { - m_metaDataReaderControl = new MmRendererMetaDataReaderControl(); - updateControls(); - } - return m_metaDataReaderControl; } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) { if (!m_appHasDrmPermissionChecked) { m_appHasDrmPermission = checkForDrmPermission(); @@ -118,8 +109,6 @@ void MmRendererMediaPlayerService::releaseControl(QObject *control) m_videoWindowControl = 0; if (control == m_mediaPlayerControl) m_mediaPlayerControl = 0; - if (control == m_metaDataReaderControl) - m_metaDataReaderControl = 0; delete control; } @@ -130,9 +119,6 @@ void MmRendererMediaPlayerService::updateControls() if (m_videoWindowControl && m_mediaPlayerControl) m_mediaPlayerControl->setVideoWindowControl(m_videoWindowControl); - - if (m_metaDataReaderControl && m_mediaPlayerControl) - m_mediaPlayerControl->setMetaDataReaderControl(m_metaDataReaderControl); } QMediaPlayerControl *MmRendererMediaPlayerService::player() @@ -140,11 +126,6 @@ QMediaPlayerControl *MmRendererMediaPlayerService::player() return m_mediaPlayerControl; } -QMetaDataReaderControl *MmRendererMediaPlayerService::dataReader() -{ - return m_metaDataReaderControl; -} - QVideoRendererControl *MmRendererMediaPlayerService::createVideoRenderer() { return m_videoRendererControl; diff --git a/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayerservice_p.h b/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayerservice_p.h index eeb3b024a..441ebfd61 100644 --- a/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayerservice_p.h +++ b/src/multimedia/platform/qnx/mediaplayer/mmrenderermediaplayerservice_p.h @@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE class MmRendererMediaPlayerControl; -class MmRendererMetaDataReaderControl; class MmRendererPlayerVideoRendererControl; class MmRendererVideoWindowControl; @@ -72,7 +71,6 @@ public: // QMediaPlatformPlayerInterface QMediaPlayerControl *player() override; - QMetaDataReaderControl *dataReader() override; // QMediaStreamsControl *streams() override; QVideoRendererControl *createVideoRenderer() override; @@ -84,7 +82,6 @@ private: QPointer<MmRendererPlayerVideoRendererControl> m_videoRendererControl; QPointer<MmRendererVideoWindowControl> m_videoWindowControl; QPointer<MmRendererMediaPlayerControl> m_mediaPlayerControl; - QPointer<MmRendererMetaDataReaderControl> m_metaDataReaderControl; bool m_appHasDrmPermission : 1; bool m_appHasDrmPermissionChecked : 1; diff --git a/src/multimedia/platform/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp b/src/multimedia/platform/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp deleted file mode 100644 index 76ad98cb3..000000000 --- a/src/multimedia/platform/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Research In Motion -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "mmrenderermetadatareadercontrol_p.h" -#include <QtMultimedia/qmediametadata.h> - -QT_BEGIN_NAMESPACE - -MmRendererMetaDataReaderControl::MmRendererMetaDataReaderControl(QObject *parent) - : QMetaDataReaderControl(parent) -{ -} - -bool MmRendererMetaDataReaderControl::isMetaDataAvailable() const -{ - return !availableMetaData().isEmpty(); -} - -QVariant MmRendererMetaDataReaderControl::metaData(const QString &key) const -{ - if (key == QMediaMetaData::Title) - return m_metaData.title(); - else if (key == QMediaMetaData::AlbumArtist) - return m_metaData.artist(); - else if (key == QMediaMetaData::Comment) - return m_metaData.comment(); - else if (key == QMediaMetaData::Genre) - return m_metaData.genre(); - else if (key == QMediaMetaData::Year) - return m_metaData.year(); - else if (key == QMediaMetaData::MediaType) - return m_metaData.mediaType(); - else if (key == QMediaMetaData::Duration) - return m_metaData.duration(); - else if (key == QMediaMetaData::AudioBitRate) - return m_metaData.audioBitRate(); - else if (key == QMediaMetaData::SampleRate) - return m_metaData.sampleRate(); - else if (key == QMediaMetaData::AlbumTitle) - return m_metaData.album(); - else if (key == QMediaMetaData::TrackNumber) - return m_metaData.track(); - else if (key == QMediaMetaData::Resolution) - return m_metaData.resolution(); - - return QVariant(); -} - -QStringList MmRendererMetaDataReaderControl::availableMetaData() const -{ - QStringList metaData; - - if (!m_metaData.title().isEmpty()) - metaData << QMediaMetaData::Title; - if (!m_metaData.artist().isEmpty()) - metaData << QMediaMetaData::Author; - if (!m_metaData.comment().isEmpty()) - metaData << QMediaMetaData::Comment; - if (!m_metaData.genre().isEmpty()) - metaData << QMediaMetaData::Genre; - if (m_metaData.year() != 0) - metaData << QMediaMetaData::Year; - if (!m_metaData.mediaType().isEmpty()) - metaData << QMediaMetaData::MediaType; - if (m_metaData.duration() != 0) - metaData << QMediaMetaData::Duration; - if (m_metaData.audioBitRate() != 0) - metaData << QMediaMetaData::AudioBitRate; - if (m_metaData.sampleRate() != 0) - metaData << QMediaMetaData::SampleRate; - if (!m_metaData.album().isEmpty()) - metaData << QMediaMetaData::AlbumTitle; - if (m_metaData.track() != 0) - metaData << QMediaMetaData::TrackNumber; - if (m_metaData.resolution().isValid()) - metaData << QMediaMetaData::Resolution; - - return metaData; -} - -void MmRendererMetaDataReaderControl::setMetaData(const MmRendererMetaData &data) -{ - const MmRendererMetaData oldMetaData = m_metaData; - const bool oldMetaDataAvailable = isMetaDataAvailable(); - - m_metaData = data; - - bool changed = false; - if (m_metaData.title() != oldMetaData.title()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Title, m_metaData.title()); - } else if (m_metaData.artist() != oldMetaData.artist()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Author, m_metaData.artist()); - } else if (m_metaData.comment() != oldMetaData.comment()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Comment, m_metaData.comment()); - } else if (m_metaData.genre() != oldMetaData.genre()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Genre, m_metaData.genre()); - } else if (m_metaData.year() != oldMetaData.year()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Year, m_metaData.year()); - } else if (m_metaData.mediaType() != oldMetaData.mediaType()) { - changed = true; - emit metaDataChanged(QMediaMetaData::MediaType, m_metaData.mediaType()); - } else if (m_metaData.duration() != oldMetaData.duration()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Duration, m_metaData.duration()); - } else if (m_metaData.audioBitRate() != oldMetaData.audioBitRate()) { - changed = true; - emit metaDataChanged(QMediaMetaData::AudioBitRate, m_metaData.audioBitRate()); - } else if (m_metaData.sampleRate() != oldMetaData.sampleRate()) { - changed = true; - emit metaDataChanged(QMediaMetaData::SampleRate, m_metaData.sampleRate()); - } else if (m_metaData.album() != oldMetaData.album()) { - changed = true; - emit metaDataChanged(QMediaMetaData::AlbumTitle, m_metaData.album()); - } else if (m_metaData.track() != oldMetaData.track()) { - changed = true; - emit metaDataChanged(QMediaMetaData::TrackNumber, m_metaData.track()); - } else if (m_metaData.resolution() != oldMetaData.resolution()) { - changed = true; - emit metaDataChanged(QMediaMetaData::Resolution, m_metaData.resolution()); - } - - if (changed) - emit metaDataChanged(); - - const bool metaDataAvailable = isMetaDataAvailable(); - if (metaDataAvailable != oldMetaDataAvailable) - emit metaDataAvailableChanged(metaDataAvailable); -} - -QT_END_NAMESPACE diff --git a/src/multimedia/platform/windows/player/mfmetadata.cpp b/src/multimedia/platform/windows/player/mfmetadata.cpp new file mode 100644 index 000000000..632ba3686 --- /dev/null +++ b/src/multimedia/platform/windows/player/mfmetadata.cpp @@ -0,0 +1,337 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <qmediametadata.h> +#include <qdatetime.h> +#include <qimage.h> + +#include "mfmetadata_p.h" +#include "mfplayerservice_p.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"); +} + +static QVariant convertValue(const PROPVARIANT& var) +{ + QVariant value; + switch (var.vt) { + case VT_LPWSTR: + value = QString::fromUtf16(reinterpret_cast<const char16_t *>(var.pwszVal)); + break; + case VT_UI4: + value = uint(var.ulVal); + break; + case VT_UI8: + value = qulonglong(var.uhVal.QuadPart); + break; + 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<const char16_t *>(var.calpwstr.pElems[i]))); + value = vList; + break; + } + return value; +} + +static QVariant metaDataValue(IPropertyStore *m_content, const PROPERTYKEY &key) +{ + QVariant value; + + PROPVARIANT var; + PropVariantInit(&var); + HRESULT hr = S_FALSE; + if (m_content) + hr = m_content->GetValue(key, &var); + + if (SUCCEEDED(hr)) { + value = convertValue(var); + + // some metadata needs to be reformatted + if (value.isValid() && m_content) { + if (key == PKEY_Media_ClassPrimaryID /*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 == PKEY_Media_Duration) { + // duration is provided in 100-nanosecond units, convert to milliseconds + value = (value.toLongLong() + 10000) / 10000; + } else if (key == PKEY_Audio_Format || key == PKEY_Video_Compression) { + GUID guid; + if (SUCCEEDED(CLSIDFromString((const WCHAR*)value.toString().utf16(), &guid))) + value = nameForGUID(guid); + } else if (key == PKEY_Video_FrameHeight /*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 == PKEY_Video_Orientation) { + uint orientation = 0; + if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_Orientation, &var))) + orientation = convertValue(var).toUInt(); + value = orientation; + } else if (key == PKEY_Video_FrameRate) { + value = value.toReal() / 1000.f; + } + } + } + + PropVariantClear(&var); + return value; +} + +QMediaMetaData MFMetaData::fromNative(IMFMediaSource* mediaSource) +{ + QMediaMetaData metaData; + + IPropertyStore *m_content = nullptr; + if (!SUCCEEDED(MFGetService(mediaSource, MF_PROPERTY_HANDLER_SERVICE, IID_PPV_ARGS(&m_content)))) + return metaData; + + Q_ASSERT(m_content); + DWORD cProps; + if (SUCCEEDED(m_content->GetCount(&cProps))) { + for (DWORD i = 0; i < cProps; i++) + { + PROPERTYKEY key; + if (FAILED(m_content->GetAt(i, &key))) + continue; + QMediaMetaData::Key mediaKey; + if (key == PKEY_Author) { + mediaKey = QMediaMetaData::Author; + } else if (key == PKEY_Title) { + mediaKey = QMediaMetaData::Title; +// } else if (key == PKEY_Media_SubTitle) { +// mediaKey = QMediaMetaData::SubTitle; +// } else if (key == PKEY_ParentalRating) { +// mediaKey = QMediaMetaData::ParentalRating; + } else if (key == PKEY_Media_EncodingSettings) { + mediaKey = QMediaMetaData::Description; + } else if (key == PKEY_Copyright) { + mediaKey = QMediaMetaData::Copyright; + } else if (key == PKEY_Comment) { + mediaKey = QMediaMetaData::Comment; + } else if (key == PKEY_Media_ProviderStyle) { + mediaKey = QMediaMetaData::Genre; + } else if (key == PKEY_Media_Year) { + mediaKey = QMediaMetaData::Year; + } else if (key == PKEY_Media_DateEncoded) { + mediaKey = QMediaMetaData::Date; +// } else if (key == PKEY_Rating) { +// mediaKey = QMediaMetaData::UserRating; +// } else if (key == PKEY_Keywords) { +// mediaKey = QMediaMetaData::Keywords; + } else if (key == PKEY_Language) { + mediaKey = QMediaMetaData::Language; + } else if (key == PKEY_Media_Publisher) { + mediaKey = QMediaMetaData::Publisher; + } else if (key == PKEY_Media_ClassPrimaryID) { + mediaKey = QMediaMetaData::MediaType; + } else if (key == PKEY_Media_Duration) { + mediaKey = QMediaMetaData::Duration; + } else if (key == PKEY_Audio_EncodingBitrate) { + mediaKey = QMediaMetaData::AudioBitRate; + } else if (key == PKEY_Audio_Format) { + mediaKey = QMediaMetaData::AudioCodec; +// } else if (key == PKEY_Media_AverageLevel) { +// mediaKey = QMediaMetaData::AverageLevel; +// } else if (key == PKEY_Audio_ChannelCount) { +// mediaKey = QMediaMetaData::ChannelCount; +// } else if (key == PKEY_Audio_PeakValue) { +// mediaKey = QMediaMetaData::PeakValue; +// } else if (key == PKEY_Audio_SampleRate) { +// mediaKey = QMediaMetaData::SampleRate; + } else if (key == PKEY_Music_AlbumTitle) { + mediaKey = QMediaMetaData::AlbumTitle; + } else if (key == PKEY_Music_AlbumArtist) { + mediaKey = QMediaMetaData::AlbumArtist; + } else if (key == PKEY_Music_Artist) { + mediaKey = QMediaMetaData::ContributingArtist; + } else if (key == PKEY_Music_Composer) { + mediaKey = QMediaMetaData::Composer; +// } else if (key == PKEY_Music_Conductor) { +// mediaKey = QMediaMetaData::Conductor; +// } else if (key == PKEY_Music_Lyrics) { +// mediaKey = QMediaMetaData::Lyrics; +// } else if (key == PKEY_Music_Mood) { +// mediaKey = QMediaMetaData::Mood; + } else if (key == PKEY_Music_TrackNumber) { + mediaKey = QMediaMetaData::TrackNumber; + } else if (key == PKEY_Music_Genre) { + mediaKey = QMediaMetaData::Genre; + } else if (key == PKEY_ThumbnailStream) { + mediaKey = QMediaMetaData::ThumbnailImage; + } else if (key == PKEY_Video_FrameHeight) { + mediaKey = QMediaMetaData::Resolution; + } else if (key == PKEY_Video_Orientation) { + mediaKey = QMediaMetaData::Orientation; +// } else if (key == PKEY_Video_HorizontalAspectRatio) { +// mediaKey = QMediaMetaData::PixelAspectRatio; +// } else if (key == PKEY_Video_FrameRate) { +// mediaKey = QMediaMetaData::VideoFrameRate; + } else if (key == PKEY_Video_EncodingBitrate) { + mediaKey = QMediaMetaData::VideoBitRate; + } else if (key == PKEY_Video_Compression) { + mediaKey = QMediaMetaData::VideoCodec; +// } else if (key == PKEY_Video_Director) { +// mediaKey = QMediaMetaData::Director; +// } else if (key == PKEY_Media_Writer) { +// mediaKey = QMediaMetaData::Writer; + } else { + continue; + } + metaData.insert(mediaKey, metaDataValue(m_content, key)); + } + } + + m_content->Release(); + + return metaData; +} diff --git a/src/multimedia/platform/windows/player/mfmetadatacontrol_p.h b/src/multimedia/platform/windows/player/mfmetadata_p.h index dcce5bb1d..813b42cf3 100644 --- a/src/multimedia/platform/windows/player/mfmetadatacontrol_p.h +++ b/src/multimedia/platform/windows/player/mfmetadata_p.h @@ -51,33 +51,15 @@ // We mean it. // -#include <qmetadatareadercontrol.h> +#include <qmediametadata.h> #include "Mfidl.h" QT_USE_NAMESPACE -class MFMetaDataControl : public QMetaDataReaderControl +class MFMetaData { - Q_OBJECT public: - MFMetaDataControl(QObject *parent = 0); - ~MFMetaDataControl(); - - bool isMetaDataAvailable() const; - - QVariant metaData(const QString &key) const; - QStringList availableMetaData() const; - - void updateSource(IMFPresentationDescriptor* sourcePD, IMFMediaSource* mediaSource); - -private: - QVariant convertValue(const PROPVARIANT& var) const; - IPropertyStore *m_content; //for Windows7 - IMFMetadata *m_metaData; //for Vista - - QStringList m_availableMetaDatas; - QList<PROPERTYKEY> m_commonKeys; //for Windows7 - QStringList m_commonNames; //for Vista + static QMediaMetaData fromNative(IMFMediaSource* mediaSource); }; #endif diff --git a/src/multimedia/platform/windows/player/mfmetadatacontrol.cpp b/src/multimedia/platform/windows/player/mfmetadatacontrol.cpp deleted file mode 100644 index b7cf771e8..000000000 --- a/src/multimedia/platform/windows/player/mfmetadatacontrol.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Mobility Components. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qmediametadata.h> -#include <qdatetime.h> -#include <qimage.h> - -#include "mfmetadatacontrol_p.h" -#include "mfplayerservice_p.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) - , m_content(0) -{ -} - -MFMetaDataControl::~MFMetaDataControl() -{ - if (m_metaData) - m_metaData->Release(); - if (m_content) - m_content->Release(); -} - -bool MFMetaDataControl::isMetaDataAvailable() const -{ - return m_content || m_metaData; -} - -QVariant MFMetaDataControl::metaData(const QString &key) const -{ - QVariant value; - if (!isMetaDataAvailable()) - return value; - - int index = m_availableMetaDatas.indexOf(key); - if (index < 0) - return value; - - PROPVARIANT var; - PropVariantInit(&var); - HRESULT hr = S_FALSE; - if (m_content) - hr = m_content->GetValue(m_commonKeys[index], &var); - else if (m_metaData) - hr = m_metaData->GetProperty(reinterpret_cast<LPCWSTR>(m_commonNames[index].utf16()), &var); - - 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::Orientation) { - uint orientation = 0; - if (m_content && SUCCEEDED(m_content->GetValue(PKEY_Video_Orientation, &var))) - orientation = convertValue(var).toUInt(); - value = orientation; - } 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; -} - -QVariant MFMetaDataControl::convertValue(const PROPVARIANT& var) const -{ - QVariant value; - switch (var.vt) { - case VT_LPWSTR: - value = QString::fromUtf16(reinterpret_cast<const ushort*>(var.pwszVal)); - break; - case VT_UI4: - value = uint(var.ulVal); - break; - case VT_UI8: - value = qulonglong(var.uhVal.QuadPart); - break; - 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<const ushort*>(var.calpwstr.pElems[i]))); - value = vList; - break; - } - return value; -} - -QStringList MFMetaDataControl::availableMetaData() const -{ - return m_availableMetaDatas; -} - -void MFMetaDataControl::updateSource(IMFPresentationDescriptor* sourcePD, IMFMediaSource* mediaSource) -{ - if (m_metaData) { - m_metaData->Release(); - m_metaData = 0; - } - - if (m_content) { - m_content->Release(); - m_content = 0; - } - - m_availableMetaDatas.clear(); - m_commonKeys.clear(); - m_commonNames.clear(); - - if (SUCCEEDED(MFGetService(mediaSource, MF_PROPERTY_HANDLER_SERVICE, IID_PPV_ARGS(&m_content)))) { - DWORD cProps; - if (SUCCEEDED(m_content->GetCount(&cProps))) { - for (DWORD i = 0; i < cProps; i++) - { - PROPERTYKEY key; - if (FAILED(m_content->GetAt(i, &key))) - continue; - bool common = true; - if (key == PKEY_Author) { - 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_Media_EncodingSettings) { - m_availableMetaDatas.push_back(QMediaMetaData::Description); - } else if (key == PKEY_Copyright) { - m_availableMetaDatas.push_back(QMediaMetaData::Copyright); - } 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_Orientation) { - m_availableMetaDatas.push_back(QMediaMetaData::Orientation); - } 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 - } - if (common) - m_commonKeys.push_back(key); - } - } else { - m_content->Release(); - m_content = NULL; - } - } - - if (!m_content) { - //fallback to Vista approach - IMFMetadataProvider *provider = NULL; - if (SUCCEEDED(MFGetService(mediaSource, MF_METADATA_PROVIDER_SERVICE, IID_PPV_ARGS(&provider)))) { - if (SUCCEEDED(provider->GetMFMetadata(sourcePD, 0, 0, &m_metaData))) { - PROPVARIANT varNames; - PropVariantInit(&varNames); - if (SUCCEEDED(m_metaData->GetAllPropertyNames(&varNames)) && varNames.vt == (VT_VECTOR | VT_LPWSTR)) { - ULONG cElements = varNames.calpwstr.cElems; - for (ULONG i = 0; i < cElements; i++) - { - const WCHAR* sName = varNames.calpwstr.pElems[i]; -#ifdef DEBUG_MEDIAFOUNDATION - qDebug() << "metadata: " << QString::fromUtf16(sName); -#endif - if (wcscmp(sName, L"Author") == 0) { - m_availableMetaDatas.push_back(QMediaMetaData::Author); - } else if (wcscmp(sName, L"Title") == 0) { - m_availableMetaDatas.push_back(QMediaMetaData::Title); - } else if (wcscmp(sName, L"Rating") == 0) { - m_availableMetaDatas.push_back(QMediaMetaData::ParentalRating); - } else if (wcscmp(sName, L"Description") == 0) { - m_availableMetaDatas.push_back(QMediaMetaData::Description); - } else if (wcscmp(sName, L"Copyright") == 0) { - m_availableMetaDatas.push_back(QMediaMetaData::Copyright); - //TODO: add more common keys - } else { - m_availableMetaDatas.push_back(QString::fromUtf16(reinterpret_cast<const ushort*>(sName))); - } - m_commonNames.push_back(QString::fromUtf16(reinterpret_cast<const ushort*>(sName))); - } - } - PropVariantClear(&varNames); - } else { - qWarning("Failed to get IMFMetadata"); - } - provider->Release(); - } else { - qWarning("Failed to get IMFMetadataProvider from source"); - } - } - - emit metaDataChanged(); - emit metaDataAvailableChanged(m_metaData || m_content); -} diff --git a/src/multimedia/platform/windows/player/mfplayerservice.cpp b/src/multimedia/platform/windows/player/mfplayerservice.cpp index 0a0096fb1..5099a1706 100644 --- a/src/multimedia/platform/windows/player/mfplayerservice.cpp +++ b/src/multimedia/platform/windows/player/mfplayerservice.cpp @@ -46,13 +46,11 @@ #include "mfvideorenderercontrol_p.h" #include "mfplayerservice_p.h" #include "mfplayersession_p.h" -#include "mfmetadatacontrol_p.h" MFPlayerService::MFPlayerService() { m_session = new MFPlayerSession(this); m_player = new MFPlayerControl(m_session); - m_metaDataControl = new MFMetaDataControl(this); } MFPlayerService::~MFPlayerService() @@ -72,8 +70,6 @@ QObject *MFPlayerService::requestControl(const char *name) { if (qstrcmp(name, QMediaPlayerControl_iid) == 0) { return m_player; - } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) { - return m_metaDataControl; } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) { if (!m_videoRendererControl && !m_videoWindowControl) { m_videoRendererControl = new MFVideoRendererControl; @@ -111,11 +107,6 @@ QMediaPlayerControl *MFPlayerService::player() return m_player; } -QMetaDataReaderControl *MFPlayerService::dataReader() -{ - return m_metaDataControl; -} - QVideoRendererControl *MFPlayerService::createVideoRenderer() { return m_videoRendererControl; @@ -135,8 +126,3 @@ MFEvrVideoWindowControl* MFPlayerService::videoWindowControl() const { return m_videoWindowControl; } - -MFMetaDataControl* MFPlayerService::metaDataControl() const -{ - return m_metaDataControl; -} diff --git a/src/multimedia/platform/windows/player/mfplayerservice_p.h b/src/multimedia/platform/windows/player/mfplayerservice_p.h index e896660d5..7c0685a78 100644 --- a/src/multimedia/platform/windows/player/mfplayerservice_p.h +++ b/src/multimedia/platform/windows/player/mfplayerservice_p.h @@ -68,7 +68,6 @@ QT_USE_NAMESPACE class MFEvrVideoWindowControl; class MFVideoRendererControl; class MFPlayerControl; -class MFMetaDataControl; class MFPlayerSession; class MFPlayerService : public QMediaPlatformPlayerInterface @@ -82,7 +81,6 @@ public: void releaseControl(QObject *control) override; QMediaPlayerControl *player() override; - QMetaDataReaderControl *dataReader() override; // ### QMediaStreamsControl *streams() override; virtual QVideoRendererControl *createVideoRenderer() override; @@ -90,14 +88,12 @@ public: MFVideoRendererControl* videoRendererControl() const; MFEvrVideoWindowControl* videoWindowControl() const; - MFMetaDataControl* metaDataControl() const; private: MFPlayerSession *m_session = nullptr; MFVideoRendererControl *m_videoRendererControl = nullptr; MFEvrVideoWindowControl *m_videoWindowControl = nullptr; MFPlayerControl *m_player = nullptr; - MFMetaDataControl *m_metaDataControl = nullptr; }; #endif diff --git a/src/multimedia/platform/windows/player/mfplayersession.cpp b/src/multimedia/platform/windows/player/mfplayersession.cpp index 359748832..7972ffd5b 100644 --- a/src/multimedia/platform/windows/player/mfplayersession.cpp +++ b/src/multimedia/platform/windows/player/mfplayersession.cpp @@ -50,10 +50,10 @@ #include "mfplayercontrol_p.h" #include "mfevrvideowindowcontrol_p.h" #include "mfvideorenderercontrol_p.h" +#include "mfmetadata_p.h" #include "mfplayersession_p.h" #include "mfplayerservice_p.h" -#include "mfmetadatacontrol_p.h" #include <mferror.h> #include <nserror.h> #include "private/sourceresolver_p.h" @@ -67,8 +67,8 @@ //#define DEBUG_MEDIAFOUNDATION MFPlayerSession::MFPlayerSession(MFPlayerService *playerService) - : m_playerService(playerService) - , m_cRef(1) + : m_cRef(1) + , m_playerService(playerService) , m_session(0) , m_presentationClock(0) , m_rateControl(0) @@ -235,7 +235,8 @@ void MFPlayerSession::handleMediaSourceReady() hr = mediaSource->CreatePresentationDescriptor(&sourcePD); if (SUCCEEDED(hr)) { m_duration = 0; - m_playerService->metaDataControl()->updateSource(sourcePD, mediaSource); + m_metaData = MFMetaData::fromNative(mediaSource); + emit metaDataChanged(); sourcePD->GetUINT64(MF_PD_DURATION, &m_duration); //convert from 100 nanosecond to milisecond emit durationUpdate(qint64(m_duration / 10000)); diff --git a/src/multimedia/platform/windows/player/mfplayersession_p.h b/src/multimedia/platform/windows/player/mfplayersession_p.h index 302f22556..adc3c392b 100644 --- a/src/multimedia/platform/windows/player/mfplayersession_p.h +++ b/src/multimedia/platform/windows/player/mfplayersession_p.h @@ -75,7 +75,6 @@ QT_USE_NAMESPACE class SourceResolver; class MFVideoRendererControl; class MFPlayerControl; -class MFMetaDataControl; class MFPlayerService; class AudioSampleGrabberCallback; class MFTransform; @@ -127,6 +126,8 @@ public: bool setAudioOutput(const QAudioDeviceInfo &device); QAudioDeviceInfo audioOutput() const { return m_audioOutput; } + QMediaMetaData metaData() const { return m_metaData; } + Q_SIGNALS: void error(QMediaPlayer::Error error, QString errorString, bool isFatal); void sessionEvent(IMFMediaEvent *sessionEvent); @@ -140,6 +141,7 @@ Q_SIGNALS: void volumeChanged(int volume); void mutedChanged(bool muted); void bufferStatusChanged(int percentFilled); + void metaDataChanged(); private Q_SLOTS: void handleMediaSourceReady(); @@ -221,6 +223,7 @@ private: bool m_muted; QAudioDeviceInfo m_audioOutput; + QMediaMetaData m_metaData; IMFActivate *m_currentAudioActivate = nullptr; diff --git a/src/multimedia/platform/windows/player/player.pri b/src/multimedia/platform/windows/player/player.pri index b7990b21d..2008bc092 100644 --- a/src/multimedia/platform/windows/player/player.pri +++ b/src/multimedia/platform/windows/player/player.pri @@ -8,7 +8,7 @@ HEADERS += \ $$PWD/mfplayersession_p.h \ $$PWD/mfplayercontrol_p.h \ $$PWD/mfvideorenderercontrol_p.h \ - $$PWD/mfmetadatacontrol_p.h \ + $$PWD/mfmetadata_p.h \ $$PWD/mfevrvideowindowcontrol_p.h \ $$PWD/samplegrabber_p.h \ $$PWD/mftvideo_p.h \ @@ -19,7 +19,7 @@ SOURCES += \ $$PWD/mfplayersession.cpp \ $$PWD/mfplayercontrol.cpp \ $$PWD/mfvideorenderercontrol.cpp \ - $$PWD/mfmetadatacontrol.cpp \ + $$PWD/mfmetadata.cpp \ $$PWD/mfevrvideowindowcontrol.cpp \ $$PWD/samplegrabber.cpp \ $$PWD/mftvideo.cpp \ |