diff options
Diffstat (limited to 'src/multimedia/platform/gstreamer')
23 files changed, 349 insertions, 666 deletions
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/gstreamer/mediaplayer/qgstreamermetadataprovider_p.h b/src/multimedia/platform/gstreamer/common/qgstreamermetadata_p.h index 468ab060b..9088215a5 100644 --- a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamermetadataprovider_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstreamermetadata_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QGSTREAMERMETADATAPROVIDER_H -#define QGSTREAMERMETADATAPROVIDER_H +#ifndef QGSTREAMERMETADATA_H +#define QGSTREAMERMETADATA_H // // W A R N I N G @@ -51,34 +51,25 @@ // We mean it. // -#include <qmetadatareadercontrol.h> +#include <qmediametadata.h> #include <qvariant.h> +#include <gst/gst.h> + QT_BEGIN_NAMESPACE class QGstreamerPlayerSession; -class QGstreamerMetaDataProvider : public QMetaDataReaderControl +class QGstreamerMetaData : public QMediaMetaData { - 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(); + static QGstreamerMetaData fromGstTagList(const GstTagList *tags); + GstTagList *toGstTagList() const; -private: - QGstreamerPlayerSession *m_session = nullptr; - QVariantMap m_tags; + void setMetaData(GstBin *bin); + void setMetaData(GstElement *element); }; QT_END_NAMESPACE -#endif // QGSTREAMERMETADATAPROVIDER_H +#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/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; |