Fix writing orientation and date exif tags in camerabin.

Orientation tags need to be transformed from the string tag returned
by gstreamer to the orientation in degrees.  Date tags need to be
inserted with gst_date_time_new_local_time.  Finally setting a tag
value shouldn't clear all other tags.

Change-Id: I28922148251084c12cf6c93d9b097fa5df41da9d
Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
This commit is contained in:
Andrew den Exter
2013-12-05 17:30:04 +10:00
committed by The Qt Project
parent 0be45b5669
commit 4565cf26af
2 changed files with 63 additions and 4 deletions

View File

@@ -54,12 +54,43 @@ struct QGstreamerMetaDataKeyLookup
const char *token; const char *token;
}; };
static QVariant fromGStreamerOrientation(const QVariant &value)
{
// Note gstreamer tokens either describe the counter clockwise rotation of the
// image or the clockwise transform to apply to correct the image. The orientation
// value returned is the clockwise rotation of the image.
const QString token = value.toString();
if (token == QStringLiteral("rotate-90"))
return 270;
else if (token == QStringLiteral("rotate-180"))
return 180;
else if (token == QStringLiteral("rotate-270"))
return 90;
else
return 0;
}
static QVariant toGStreamerOrientation(const QVariant &value)
{
switch (value.toInt()) {
case 90:
return QStringLiteral("rotate-270");
case 180:
return QStringLiteral("rotate-180");
case 270:
return QStringLiteral("rotate-90");
default:
return QStringLiteral("rotate-0");
}
}
static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] = static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] =
{ {
{ QMediaMetaData::Title, GST_TAG_TITLE }, { QMediaMetaData::Title, GST_TAG_TITLE },
//{ QMediaMetaData::SubTitle, 0 }, //{ QMediaMetaData::SubTitle, 0 },
//{ QMediaMetaData::Author, 0 }, //{ QMediaMetaData::Author, 0 },
{ QMediaMetaData::Comment, GST_TAG_COMMENT }, { QMediaMetaData::Comment, GST_TAG_COMMENT },
{ QMediaMetaData::Date, GST_TAG_DATE_TIME },
{ QMediaMetaData::Description, GST_TAG_DESCRIPTION }, { QMediaMetaData::Description, GST_TAG_DESCRIPTION },
//{ QMediaMetaData::Category, 0 }, //{ QMediaMetaData::Category, 0 },
{ QMediaMetaData::Genre, GST_TAG_GENRE }, { QMediaMetaData::Genre, GST_TAG_GENRE },
@@ -120,7 +151,9 @@ static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] =
//{ QMediaMetaData::CameraManufacturer, 0 }, //{ QMediaMetaData::CameraManufacturer, 0 },
//{ QMediaMetaData::CameraModel, 0 }, //{ QMediaMetaData::CameraModel, 0 },
//{ QMediaMetaData::Event, 0 }, //{ QMediaMetaData::Event, 0 },
//{ QMediaMetaData::Subject, 0 } //{ QMediaMetaData::Subject, 0 },
{ QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION }
}; };
CameraBinMetaData::CameraBinMetaData(QObject *parent) CameraBinMetaData::CameraBinMetaData(QObject *parent)
@@ -130,6 +163,10 @@ CameraBinMetaData::CameraBinMetaData(QObject *parent)
QVariant CameraBinMetaData::metaData(const QString &key) const QVariant CameraBinMetaData::metaData(const QString &key) const
{ {
if (key == QMediaMetaData::Orientation) {
return fromGStreamerOrientation(m_values.value(QByteArray(GST_TAG_IMAGE_ORIENTATION)));
}
static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
@@ -144,6 +181,15 @@ 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)
{ {
if (key == QMediaMetaData::Orientation) {
m_values.insert(QByteArray(GST_TAG_IMAGE_ORIENTATION), toGStreamerOrientation(value));
emit QMetaDataWriterControl::metaDataChanged();
emit metaDataChanged(m_values);
return;
}
static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {

View File

@@ -76,6 +76,7 @@
#include <QtGui/qdesktopservices.h> #include <QtGui/qdesktopservices.h>
#include <QtGui/qimage.h> #include <QtGui/qimage.h>
#include <QtCore/qdatetime.h>
//#define CAMERABIN_DEBUG 1 //#define CAMERABIN_DEBUG 1
//#define CAMERABIN_DEBUG_DUMP_BIN 1 //#define CAMERABIN_DEBUG_DUMP_BIN 1
@@ -737,7 +738,7 @@ void CameraBinSession::setMetaData(const QMap<QByteArray, QVariant> &data)
switch(tagValue.type()) { switch(tagValue.type()) {
case QVariant::String: case QVariant::String:
gst_tag_setter_add_tags(GST_TAG_SETTER(element), gst_tag_setter_add_tags(GST_TAG_SETTER(element),
GST_TAG_MERGE_REPLACE_ALL, GST_TAG_MERGE_REPLACE,
tagName.toUtf8().constData(), tagName.toUtf8().constData(),
tagValue.toString().toUtf8().constData(), tagValue.toString().toUtf8().constData(),
NULL); NULL);
@@ -745,18 +746,29 @@ void CameraBinSession::setMetaData(const QMap<QByteArray, QVariant> &data)
case QVariant::Int: case QVariant::Int:
case QVariant::LongLong: case QVariant::LongLong:
gst_tag_setter_add_tags(GST_TAG_SETTER(element), gst_tag_setter_add_tags(GST_TAG_SETTER(element),
GST_TAG_MERGE_REPLACE_ALL, GST_TAG_MERGE_REPLACE,
tagName.toUtf8().constData(), tagName.toUtf8().constData(),
tagValue.toInt(), tagValue.toInt(),
NULL); NULL);
break; break;
case QVariant::Double: case QVariant::Double:
gst_tag_setter_add_tags(GST_TAG_SETTER(element), gst_tag_setter_add_tags(GST_TAG_SETTER(element),
GST_TAG_MERGE_REPLACE_ALL, GST_TAG_MERGE_REPLACE,
tagName.toUtf8().constData(), tagName.toUtf8().constData(),
tagValue.toDouble(), tagValue.toDouble(),
NULL); NULL);
break; break;
case QVariant::DateTime: {
QDateTime date = tagValue.toDateTime().toLocalTime();
gst_tag_setter_add_tags(GST_TAG_SETTER(element),
GST_TAG_MERGE_REPLACE,
tagName.toUtf8().constData(),
gst_date_time_new_local_time(
date.date().year(), date.date().month(), date.date().day(),
date.time().hour(), date.time().minute(), date.time().second()),
NULL);
break;
}
default: default:
break; break;
} }
@@ -932,6 +944,7 @@ bool CameraBinSession::processBusMessage(const QGstreamerMessage &message)
emit stateChanged(m_state = QCamera::UnloadedState); emit stateChanged(m_state = QCamera::UnloadedState);
break; break;
case GST_STATE_READY: case GST_STATE_READY:
setMetaData(m_metaData);
if (m_state != QCamera::LoadedState) if (m_state != QCamera::LoadedState)
emit stateChanged(m_state = QCamera::LoadedState); emit stateChanged(m_state = QCamera::LoadedState);
break; break;