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 <yoann.lopes@digia.com>
This commit is contained in:
committed by
The Qt Project
parent
87b8b4489a
commit
c949a98c42
@@ -46,12 +46,15 @@
|
|||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/gstversion.h>
|
#include <gst/gstversion.h>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
struct QGstreamerMetaDataKeyLookup
|
struct QGstreamerMetaDataKeyLookup
|
||||||
{
|
{
|
||||||
QString key;
|
QString key;
|
||||||
const char *token;
|
const char *token;
|
||||||
|
QVariant::Type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QVariant fromGStreamerOrientation(const QVariant &value)
|
static QVariant fromGStreamerOrientation(const QVariant &value)
|
||||||
@@ -86,74 +89,77 @@ static QVariant toGStreamerOrientation(const QVariant &value)
|
|||||||
|
|
||||||
static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] =
|
static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] =
|
||||||
{
|
{
|
||||||
{ QMediaMetaData::Title, GST_TAG_TITLE },
|
{ QMediaMetaData::Title, GST_TAG_TITLE, QVariant::String },
|
||||||
//{ QMediaMetaData::SubTitle, 0 },
|
//{ QMediaMetaData::SubTitle, 0, QVariant::String },
|
||||||
//{ QMediaMetaData::Author, 0 },
|
//{ QMediaMetaData::Author, 0, QVariant::String },
|
||||||
{ QMediaMetaData::Comment, GST_TAG_COMMENT },
|
{ QMediaMetaData::Comment, GST_TAG_COMMENT, QVariant::String },
|
||||||
{ QMediaMetaData::Date, GST_TAG_DATE_TIME },
|
{ QMediaMetaData::Date, GST_TAG_DATE_TIME, QVariant::DateTime },
|
||||||
{ QMediaMetaData::Description, GST_TAG_DESCRIPTION },
|
{ QMediaMetaData::Description, GST_TAG_DESCRIPTION, QVariant::String },
|
||||||
//{ QMediaMetaData::Category, 0 },
|
//{ QMediaMetaData::Category, 0, QVariant::String },
|
||||||
{ QMediaMetaData::Genre, GST_TAG_GENRE },
|
{ QMediaMetaData::Genre, GST_TAG_GENRE, QVariant::String },
|
||||||
//{ QMediaMetaData::Year, 0 },
|
//{ QMediaMetaData::Year, 0, QVariant::Int },
|
||||||
//{ QMediaMetaData::UserRating, 0 },
|
//{ QMediaMetaData::UserRating, , QVariant::Int },
|
||||||
|
|
||||||
{ QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE },
|
{ QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE, QVariant::String },
|
||||||
|
|
||||||
{ QMediaMetaData::Publisher, GST_TAG_ORGANIZATION },
|
{ QMediaMetaData::Publisher, GST_TAG_ORGANIZATION, QVariant::String },
|
||||||
{ QMediaMetaData::Copyright, GST_TAG_COPYRIGHT },
|
{ QMediaMetaData::Copyright, GST_TAG_COPYRIGHT, QVariant::String },
|
||||||
//{ QMediaMetaData::ParentalRating, 0 },
|
//{ QMediaMetaData::ParentalRating, 0, QVariant::String },
|
||||||
//{ QMediaMetaData::RatingOrganisation, 0 },
|
//{ QMediaMetaData::RatingOrganisation, 0, QVariant::String },
|
||||||
|
|
||||||
// Media
|
// Media
|
||||||
//{ QMediaMetaData::Size, 0 },
|
//{ QMediaMetaData::Size, 0, QVariant::Int },
|
||||||
//{ QMediaMetaData::MediaType, 0 },
|
//{ QMediaMetaData::MediaType, 0, QVariant::String },
|
||||||
{ QMediaMetaData::Duration, GST_TAG_DURATION },
|
{ QMediaMetaData::Duration, GST_TAG_DURATION, QVariant::Int },
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
{ QMediaMetaData::AudioBitRate, GST_TAG_BITRATE },
|
{ QMediaMetaData::AudioBitRate, GST_TAG_BITRATE, QVariant::Int },
|
||||||
{ QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC },
|
{ QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC, QVariant::String },
|
||||||
//{ QMediaMetaData::ChannelCount, 0 },
|
//{ QMediaMetaData::ChannelCount, 0, QVariant::Int },
|
||||||
//{ QMediaMetaData::SampleRate, 0 },
|
//{ QMediaMetaData::SampleRate, 0, QVariant::Int },
|
||||||
|
|
||||||
// Music
|
// Music
|
||||||
{ QMediaMetaData::AlbumTitle, GST_TAG_ALBUM },
|
{ QMediaMetaData::AlbumTitle, GST_TAG_ALBUM, QVariant::String },
|
||||||
{ QMediaMetaData::AlbumArtist, GST_TAG_ARTIST},
|
{ QMediaMetaData::AlbumArtist, GST_TAG_ARTIST, QVariant::String},
|
||||||
{ QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER },
|
{ QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER, QVariant::String },
|
||||||
#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19)
|
#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
|
#endif
|
||||||
//{ QMediaMetaData::Conductor, 0 },
|
//{ QMediaMetaData::Conductor, 0, QVariant::String },
|
||||||
//{ QMediaMetaData::Lyrics, 0 },
|
//{ QMediaMetaData::Lyrics, 0, QVariant::String },
|
||||||
//{ QMediaMetaData::Mood, 0 },
|
//{ QMediaMetaData::Mood, 0, QVariant::String },
|
||||||
{ QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER },
|
{ QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER, QVariant::Int },
|
||||||
|
|
||||||
//{ QMediaMetaData::CoverArtUrlSmall, 0 },
|
//{ QMediaMetaData::CoverArtUrlSmall, 0, QVariant::String },
|
||||||
//{ QMediaMetaData::CoverArtUrlLarge, 0 },
|
//{ QMediaMetaData::CoverArtUrlLarge, 0, QVariant::String },
|
||||||
|
|
||||||
// Image/Video
|
// Image/Video
|
||||||
//{ QMediaMetaData::Resolution, 0 },
|
//{ QMediaMetaData::Resolution, 0, QVariant::Size },
|
||||||
//{ QMediaMetaData::PixelAspectRatio, 0 },
|
//{ QMediaMetaData::PixelAspectRatio, 0, QVariant::Size },
|
||||||
|
|
||||||
// Video
|
// Video
|
||||||
//{ QMediaMetaData::VideoFrameRate, 0 },
|
//{ QMediaMetaData::VideoFrameRate, 0, QVariant::String },
|
||||||
//{ QMediaMetaData::VideoBitRate, 0 },
|
//{ QMediaMetaData::VideoBitRate, 0, QVariant::Double },
|
||||||
{ QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC },
|
{ QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC, QVariant::String },
|
||||||
|
|
||||||
//{ QMediaMetaData::PosterUrl, 0 },
|
//{ QMediaMetaData::PosterUrl, 0, QVariant::String },
|
||||||
|
|
||||||
// Movie
|
// Movie
|
||||||
//{ QMediaMetaData::ChapterNumber, 0 },
|
//{ QMediaMetaData::ChapterNumber, 0, QVariant::Int },
|
||||||
//{ QMediaMetaData::Director, 0 },
|
//{ QMediaMetaData::Director, 0, QVariant::String },
|
||||||
{ QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER },
|
{ QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER, QVariant::String },
|
||||||
//{ QMediaMetaData::Writer, 0 },
|
//{ QMediaMetaData::Writer, 0, QVariant::String },
|
||||||
|
|
||||||
|
#if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 30)
|
||||||
// Photos
|
// Photos
|
||||||
//{ QMediaMetaData::CameraManufacturer, 0 },
|
{ QMediaMetaData::CameraManufacturer, 0, QVariant::String },
|
||||||
//{ QMediaMetaData::CameraModel, 0 },
|
{ QMediaMetaData::CameraModel, 0, QVariant::String },
|
||||||
//{ QMediaMetaData::Event, 0 },
|
//{ QMediaMetaData::Event, 0, QVariant::String },
|
||||||
//{ QMediaMetaData::Subject, 0 },
|
//{ QMediaMetaData::Subject, 0, QVariant::String },
|
||||||
|
|
||||||
{ QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION }
|
{ QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION, QVariant::String },
|
||||||
|
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
CameraBinMetaData::CameraBinMetaData(QObject *parent)
|
CameraBinMetaData::CameraBinMetaData(QObject *parent)
|
||||||
@@ -165,6 +171,9 @@ QVariant CameraBinMetaData::metaData(const QString &key) const
|
|||||||
{
|
{
|
||||||
if (key == QMediaMetaData::Orientation) {
|
if (key == QMediaMetaData::Orientation) {
|
||||||
return fromGStreamerOrientation(m_values.value(QByteArray(GST_TAG_IMAGE_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);
|
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)
|
void CameraBinMetaData::setMetaData(const QString &key, const QVariant &value)
|
||||||
{
|
{
|
||||||
|
QVariant correctedValue = value;
|
||||||
if (key == QMediaMetaData::Orientation) {
|
if (key == QMediaMetaData::Orientation) {
|
||||||
m_values.insert(QByteArray(GST_TAG_IMAGE_ORIENTATION), toGStreamerOrientation(value));
|
correctedValue = toGStreamerOrientation(value);
|
||||||
|
} else if (key == QMediaMetaData::GPSSpeed) {
|
||||||
emit QMetaDataWriterControl::metaDataChanged();
|
// kilometers per hour to meters per second.
|
||||||
emit metaDataChanged(m_values);
|
correctedValue = (value.toDouble() * 1000) / 3600;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup);
|
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) {
|
if (qt_gstreamerMetaDataKeys[i].key == key) {
|
||||||
const char *name = qt_gstreamerMetaDataKeys[i].token;
|
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 QMetaDataWriterControl::metaDataChanged();
|
||||||
emit metaDataChanged(m_values);
|
emit metaDataChanged(m_values);
|
||||||
|
|||||||
Reference in New Issue
Block a user