From c949a98c422d80234f7776e33a92a21732edbaee Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Tue, 28 Jan 2014 11:28:19 +1000 Subject: Fix gstreamer crash when meta-data is of incorrect type. GStreamer tags are typed and the correct type must be used when inserting a value into a GstTagList or subsequent merges or data accesses can crash because of invalid casts. Found while adding additional mappings for GPS values. Change-Id: I95ab40a480a4685bf4e69064315557faa9de288e Reviewed-by: Yoann Lopes --- .../gstreamer/camerabin/camerabinmetadata.cpp | 122 +++++++++++---------- 1 file changed, 66 insertions(+), 56 deletions(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp index 1e55e9e84..4dd4c7501 100644 --- a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp @@ -46,12 +46,15 @@ #include #include +#include + QT_BEGIN_NAMESPACE struct QGstreamerMetaDataKeyLookup { QString key; const char *token; + QVariant::Type type; }; static QVariant fromGStreamerOrientation(const QVariant &value) @@ -86,74 +89,77 @@ static QVariant toGStreamerOrientation(const QVariant &value) static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] = { - { QMediaMetaData::Title, GST_TAG_TITLE }, - //{ QMediaMetaData::SubTitle, 0 }, - //{ QMediaMetaData::Author, 0 }, - { QMediaMetaData::Comment, GST_TAG_COMMENT }, - { QMediaMetaData::Date, GST_TAG_DATE_TIME }, - { QMediaMetaData::Description, GST_TAG_DESCRIPTION }, - //{ QMediaMetaData::Category, 0 }, - { QMediaMetaData::Genre, GST_TAG_GENRE }, - //{ QMediaMetaData::Year, 0 }, - //{ QMediaMetaData::UserRating, 0 }, - - { QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE }, - - { QMediaMetaData::Publisher, GST_TAG_ORGANIZATION }, - { QMediaMetaData::Copyright, GST_TAG_COPYRIGHT }, - //{ QMediaMetaData::ParentalRating, 0 }, - //{ QMediaMetaData::RatingOrganisation, 0 }, + { QMediaMetaData::Title, GST_TAG_TITLE, QVariant::String }, + //{ QMediaMetaData::SubTitle, 0, QVariant::String }, + //{ QMediaMetaData::Author, 0, QVariant::String }, + { QMediaMetaData::Comment, GST_TAG_COMMENT, QVariant::String }, + { QMediaMetaData::Date, GST_TAG_DATE_TIME, QVariant::DateTime }, + { QMediaMetaData::Description, GST_TAG_DESCRIPTION, QVariant::String }, + //{ QMediaMetaData::Category, 0, QVariant::String }, + { QMediaMetaData::Genre, GST_TAG_GENRE, QVariant::String }, + //{ QMediaMetaData::Year, 0, QVariant::Int }, + //{ QMediaMetaData::UserRating, , QVariant::Int }, + + { QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE, QVariant::String }, + + { QMediaMetaData::Publisher, GST_TAG_ORGANIZATION, QVariant::String }, + { QMediaMetaData::Copyright, GST_TAG_COPYRIGHT, QVariant::String }, + //{ QMediaMetaData::ParentalRating, 0, QVariant::String }, + //{ QMediaMetaData::RatingOrganisation, 0, QVariant::String }, // Media - //{ QMediaMetaData::Size, 0 }, - //{ QMediaMetaData::MediaType, 0 }, - { QMediaMetaData::Duration, GST_TAG_DURATION }, + //{ QMediaMetaData::Size, 0, QVariant::Int }, + //{ QMediaMetaData::MediaType, 0, QVariant::String }, + { QMediaMetaData::Duration, GST_TAG_DURATION, QVariant::Int }, // Audio - { QMediaMetaData::AudioBitRate, GST_TAG_BITRATE }, - { QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC }, - //{ QMediaMetaData::ChannelCount, 0 }, - //{ QMediaMetaData::SampleRate, 0 }, + { QMediaMetaData::AudioBitRate, GST_TAG_BITRATE, QVariant::Int }, + { QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC, QVariant::String }, + //{ QMediaMetaData::ChannelCount, 0, QVariant::Int }, + //{ QMediaMetaData::SampleRate, 0, QVariant::Int }, // Music - { QMediaMetaData::AlbumTitle, GST_TAG_ALBUM }, - { QMediaMetaData::AlbumArtist, GST_TAG_ARTIST}, - { QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER }, + { QMediaMetaData::AlbumTitle, GST_TAG_ALBUM, QVariant::String }, + { QMediaMetaData::AlbumArtist, GST_TAG_ARTIST, QVariant::String}, + { QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER, QVariant::String }, #if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19) - { QMediaMetaData::Composer, GST_TAG_COMPOSER }, + { QMediaMetaData::Composer, GST_TAG_COMPOSER, QVariant::String }, #endif - //{ QMediaMetaData::Conductor, 0 }, - //{ QMediaMetaData::Lyrics, 0 }, - //{ QMediaMetaData::Mood, 0 }, - { QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER }, + //{ QMediaMetaData::Conductor, 0, QVariant::String }, + //{ QMediaMetaData::Lyrics, 0, QVariant::String }, + //{ QMediaMetaData::Mood, 0, QVariant::String }, + { QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER, QVariant::Int }, - //{ QMediaMetaData::CoverArtUrlSmall, 0 }, - //{ QMediaMetaData::CoverArtUrlLarge, 0 }, + //{ QMediaMetaData::CoverArtUrlSmall, 0, QVariant::String }, + //{ QMediaMetaData::CoverArtUrlLarge, 0, QVariant::String }, // Image/Video - //{ QMediaMetaData::Resolution, 0 }, - //{ QMediaMetaData::PixelAspectRatio, 0 }, + //{ QMediaMetaData::Resolution, 0, QVariant::Size }, + //{ QMediaMetaData::PixelAspectRatio, 0, QVariant::Size }, // Video - //{ QMediaMetaData::VideoFrameRate, 0 }, - //{ QMediaMetaData::VideoBitRate, 0 }, - { QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC }, + //{ QMediaMetaData::VideoFrameRate, 0, QVariant::String }, + //{ QMediaMetaData::VideoBitRate, 0, QVariant::Double }, + { QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC, QVariant::String }, - //{ QMediaMetaData::PosterUrl, 0 }, + //{ QMediaMetaData::PosterUrl, 0, QVariant::String }, // Movie - //{ QMediaMetaData::ChapterNumber, 0 }, - //{ QMediaMetaData::Director, 0 }, - { QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER }, - //{ QMediaMetaData::Writer, 0 }, + //{ QMediaMetaData::ChapterNumber, 0, QVariant::Int }, + //{ QMediaMetaData::Director, 0, QVariant::String }, + { QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER, QVariant::String }, + //{ QMediaMetaData::Writer, 0, QVariant::String }, +#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 30) // Photos - //{ QMediaMetaData::CameraManufacturer, 0 }, - //{ QMediaMetaData::CameraModel, 0 }, - //{ QMediaMetaData::Event, 0 }, - //{ QMediaMetaData::Subject, 0 }, + { QMediaMetaData::CameraManufacturer, 0, QVariant::String }, + { QMediaMetaData::CameraModel, 0, QVariant::String }, + //{ QMediaMetaData::Event, 0, QVariant::String }, + //{ QMediaMetaData::Subject, 0, QVariant::String }, + + { QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION, QVariant::String }, - { QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION } +#endif }; CameraBinMetaData::CameraBinMetaData(QObject *parent) @@ -165,6 +171,9 @@ QVariant CameraBinMetaData::metaData(const QString &key) const { if (key == QMediaMetaData::Orientation) { return fromGStreamerOrientation(m_values.value(QByteArray(GST_TAG_IMAGE_ORIENTATION))); + } else if (key == QMediaMetaData::GPSSpeed) { + const double metersPerSec = m_values.value(QByteArray(GST_TAG_GEO_LOCATION_MOVEMENT_SPEED)).toDouble(); + return (metersPerSec * 3600) / 1000; } static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); @@ -181,13 +190,12 @@ QVariant CameraBinMetaData::metaData(const QString &key) const void CameraBinMetaData::setMetaData(const QString &key, const QVariant &value) { + QVariant correctedValue = value; if (key == QMediaMetaData::Orientation) { - m_values.insert(QByteArray(GST_TAG_IMAGE_ORIENTATION), toGStreamerOrientation(value)); - - emit QMetaDataWriterControl::metaDataChanged(); - emit metaDataChanged(m_values); - - return; + correctedValue = toGStreamerOrientation(value); + } else if (key == QMediaMetaData::GPSSpeed) { + // kilometers per hour to meters per second. + correctedValue = (value.toDouble() * 1000) / 3600; } static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); @@ -196,7 +204,9 @@ void CameraBinMetaData::setMetaData(const QString &key, const QVariant &value) if (qt_gstreamerMetaDataKeys[i].key == key) { const char *name = qt_gstreamerMetaDataKeys[i].token; - m_values.insert(QByteArray::fromRawData(name, qstrlen(name)), value); + correctedValue.convert(qt_gstreamerMetaDataKeys[i].type); + + m_values.insert(QByteArray::fromRawData(name, qstrlen(name)), correctedValue); emit QMetaDataWriterControl::metaDataChanged(); emit metaDataChanged(m_values); -- cgit v1.2.3