Add a metaData property to QVideoFrame.
Change-Id: I6614cd86e3e1e170277bfc751222b5b42cb657eb Reviewed-by: Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com>
This commit is contained in:
committed by
Qt by Nokia
parent
41ff2e6829
commit
c8f48841ef
@@ -115,6 +115,7 @@ public:
|
|||||||
QAbstractVideoBuffer *buffer;
|
QAbstractVideoBuffer *buffer;
|
||||||
int mappedCount;
|
int mappedCount;
|
||||||
QMutex mapMutex;
|
QMutex mapMutex;
|
||||||
|
QVariantMap metadata;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_DISABLE_COPY(QVideoFramePrivate)
|
Q_DISABLE_COPY(QVideoFramePrivate)
|
||||||
@@ -753,6 +754,45 @@ void QVideoFrame::setEndTime(qint64 time)
|
|||||||
d->endTime = time;
|
d->endTime = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns any extra metadata associated with this frame.
|
||||||
|
*/
|
||||||
|
QVariantMap QVideoFrame::availableMetaData() const
|
||||||
|
{
|
||||||
|
return d->metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns any metadata for this frame for the given \a key.
|
||||||
|
|
||||||
|
This might include frame specific information from
|
||||||
|
a camera, or subtitles from a decoded video stream.
|
||||||
|
|
||||||
|
See the documentation for the relevant video frame
|
||||||
|
producer for further information about available metadata.
|
||||||
|
*/
|
||||||
|
QVariant QVideoFrame::metaData(const QString &key) const
|
||||||
|
{
|
||||||
|
return d->metadata.value(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the metadata for the given \a key to \a value.
|
||||||
|
|
||||||
|
If \a value is a null variant, any metadata for this key will be removed.
|
||||||
|
|
||||||
|
The producer of the video frame might use this to associate
|
||||||
|
certain data with this frame, or for an intermediate processor
|
||||||
|
to add information for a consumer of this frame.
|
||||||
|
*/
|
||||||
|
void QVideoFrame::setMetaData(const QString &key, const QVariant &value)
|
||||||
|
{
|
||||||
|
if (!value.isNull())
|
||||||
|
d->metadata.insert(key, value);
|
||||||
|
else
|
||||||
|
d->metadata.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns a video pixel format equivalent to an image \a format. If there is no equivalent
|
Returns a video pixel format equivalent to an image \a format. If there is no equivalent
|
||||||
format QVideoFrame::InvalidType is returned instead.
|
format QVideoFrame::InvalidType is returned instead.
|
||||||
@@ -843,6 +883,9 @@ QImage::Format QVideoFrame::imageFormatFromPixelFormat(PixelFormat format)
|
|||||||
return QImage::Format_Invalid;
|
return QImage::Format_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
QDebug operator<<(QDebug dbg, QVideoFrame::PixelFormat pf)
|
QDebug operator<<(QDebug dbg, QVideoFrame::PixelFormat pf)
|
||||||
{
|
{
|
||||||
@@ -1005,12 +1048,16 @@ static QString qFormatTimeStamps(qint64 start, qint64 end)
|
|||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const QVideoFrame& f)
|
QDebug operator<<(QDebug dbg, const QVideoFrame& f)
|
||||||
{
|
{
|
||||||
return dbg << "QVideoFrame(" << f.size() << ","
|
dbg.nospace() << "QVideoFrame(" << f.size() << ","
|
||||||
<< f.pixelFormat() << ", "
|
<< f.pixelFormat() << ", "
|
||||||
<< f.handleType() << ", "
|
<< f.handleType() << ", "
|
||||||
<< f.mapMode() << ", "
|
<< f.mapMode() << ", "
|
||||||
<< qFormatTimeStamps(f.startTime(), f.endTime()).toLatin1().constData()
|
<< qFormatTimeStamps(f.startTime(), f.endTime()).toLatin1().constData();
|
||||||
<< ")";
|
if (f.availableMetaData().count()) {
|
||||||
|
dbg.nospace() << ", metaData: ";
|
||||||
|
dbg.nospace() << f.availableMetaData();
|
||||||
|
}
|
||||||
|
return dbg.nospace() << ")";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include <QtCore/qshareddata.h>
|
#include <QtCore/qshareddata.h>
|
||||||
#include <QtGui/qimage.h>
|
#include <QtGui/qimage.h>
|
||||||
#include <qabstractvideobuffer.h>
|
#include <qabstractvideobuffer.h>
|
||||||
|
#include <QtCore/qvariant.h>
|
||||||
|
|
||||||
QT_BEGIN_HEADER
|
QT_BEGIN_HEADER
|
||||||
|
|
||||||
@@ -54,7 +55,6 @@ QT_BEGIN_NAMESPACE
|
|||||||
QT_MODULE(Multimedia)
|
QT_MODULE(Multimedia)
|
||||||
|
|
||||||
class QSize;
|
class QSize;
|
||||||
class QVariant;
|
|
||||||
|
|
||||||
class QVideoFramePrivate;
|
class QVideoFramePrivate;
|
||||||
|
|
||||||
@@ -156,6 +156,10 @@ public:
|
|||||||
qint64 endTime() const;
|
qint64 endTime() const;
|
||||||
void setEndTime(qint64 time);
|
void setEndTime(qint64 time);
|
||||||
|
|
||||||
|
QVariantMap availableMetaData() const;
|
||||||
|
QVariant metaData(const QString &key) const;
|
||||||
|
void setMetaData(const QString &key, const QVariant &value);
|
||||||
|
|
||||||
static PixelFormat pixelFormatFromImageFormat(QImage::Format format);
|
static PixelFormat pixelFormatFromImageFormat(QImage::Format format);
|
||||||
static QImage::Format imageFormatFromPixelFormat(PixelFormat format);
|
static QImage::Format imageFormatFromPixelFormat(PixelFormat format);
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ private slots:
|
|||||||
void formatConversion_data();
|
void formatConversion_data();
|
||||||
void formatConversion();
|
void formatConversion();
|
||||||
|
|
||||||
|
void metadata();
|
||||||
|
|
||||||
void debugType_data();
|
void debugType_data();
|
||||||
void debugType();
|
void debugType();
|
||||||
|
|
||||||
@@ -903,6 +905,35 @@ void tst_QVideoFrame::formatConversion()
|
|||||||
pixelFormat != QVideoFrame::Format_Invalid);
|
pixelFormat != QVideoFrame::Format_Invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QVideoFrame::metadata()
|
||||||
|
{
|
||||||
|
// Simple metadata test
|
||||||
|
QVideoFrame f;
|
||||||
|
|
||||||
|
QCOMPARE(f.availableMetaData(), QVariantMap());
|
||||||
|
f.setMetaData("frob", QVariant("string"));
|
||||||
|
f.setMetaData("bar", QVariant(42));
|
||||||
|
QCOMPARE(f.metaData("frob"), QVariant("string"));
|
||||||
|
QCOMPARE(f.metaData("bar"), QVariant(42));
|
||||||
|
|
||||||
|
QVariantMap map;
|
||||||
|
map.insert("frob", QVariant("string"));
|
||||||
|
map.insert("bar", QVariant(42));
|
||||||
|
|
||||||
|
QCOMPARE(f.availableMetaData(), map);
|
||||||
|
|
||||||
|
f.setMetaData("frob", QVariant(56));
|
||||||
|
QCOMPARE(f.metaData("frob"), QVariant(56));
|
||||||
|
|
||||||
|
f.setMetaData("frob", QVariant());
|
||||||
|
QCOMPARE(f.metaData("frob"), QVariant());
|
||||||
|
|
||||||
|
QCOMPARE(f.availableMetaData().count(), 1);
|
||||||
|
|
||||||
|
f.setMetaData("frob", QVariant("")); // empty but not null
|
||||||
|
QCOMPARE(f.availableMetaData().count(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
#define TEST_MAPPED(frame, mode) \
|
#define TEST_MAPPED(frame, mode) \
|
||||||
do { \
|
do { \
|
||||||
QVERIFY(frame.bits()); \
|
QVERIFY(frame.bits()); \
|
||||||
@@ -1023,56 +1054,61 @@ void tst_QVideoFrame::debug_data()
|
|||||||
QTest::addColumn<QString>("stringized");
|
QTest::addColumn<QString>("stringized");
|
||||||
|
|
||||||
QVideoFrame f;
|
QVideoFrame f;
|
||||||
QTest::newRow("default") << f << QString::fromLatin1("QVideoFrame( QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
|
QTest::newRow("default") << f << QString::fromLatin1("QVideoFrame(QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
|
||||||
|
|
||||||
QVideoFrame f2;
|
QVideoFrame f2;
|
||||||
f2.setStartTime(12345);
|
f2.setStartTime(12345);
|
||||||
f2.setEndTime(8000000000LL);
|
f2.setEndTime(8000000000LL);
|
||||||
QTest::newRow("times") << f2 << QString::fromLatin1("QVideoFrame( QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, 0:00:00.12345 - 2:13:20.00)");
|
QTest::newRow("times") << f2 << QString::fromLatin1("QVideoFrame(QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, 0:00:00.12345 - 2:13:20.00)");
|
||||||
|
|
||||||
QVideoFrame f3;
|
QVideoFrame f3;
|
||||||
f3.setFieldType(QVideoFrame::ProgressiveFrame);
|
f3.setFieldType(QVideoFrame::ProgressiveFrame);
|
||||||
QTest::newRow("times prog") << f3 << QString::fromLatin1("QVideoFrame( QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
|
QTest::newRow("times prog") << f3 << QString::fromLatin1("QVideoFrame(QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
|
||||||
|
|
||||||
QVideoFrame f4;
|
QVideoFrame f4;
|
||||||
f4.setFieldType(QVideoFrame::TopField);
|
f4.setFieldType(QVideoFrame::TopField);
|
||||||
QTest::newRow("times top") << f4 << QString::fromLatin1("QVideoFrame( QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
|
QTest::newRow("times top") << f4 << QString::fromLatin1("QVideoFrame(QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
|
||||||
|
|
||||||
QVideoFrame f5;
|
QVideoFrame f5;
|
||||||
f5.setFieldType(QVideoFrame::TopField);
|
f5.setFieldType(QVideoFrame::TopField);
|
||||||
f5.setEndTime(90000000000LL);
|
f5.setEndTime(90000000000LL);
|
||||||
QTest::newRow("end but no start") << f5 << QString::fromLatin1("QVideoFrame( QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
|
QTest::newRow("end but no start") << f5 << QString::fromLatin1("QVideoFrame(QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
|
||||||
|
|
||||||
QVideoFrame f6;
|
QVideoFrame f6;
|
||||||
f6.setStartTime(12345000000LL);
|
f6.setStartTime(12345000000LL);
|
||||||
f6.setEndTime(80000000000LL);
|
f6.setEndTime(80000000000LL);
|
||||||
QTest::newRow("times big") << f6 << QString::fromLatin1("QVideoFrame( QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, 3:25:45.00 - 22:13:20.00)");
|
QTest::newRow("times big") << f6 << QString::fromLatin1("QVideoFrame(QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, 3:25:45.00 - 22:13:20.00)");
|
||||||
|
|
||||||
QVideoFrame g(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
QVideoFrame g(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
||||||
QTest::newRow("more valid") << g << QString::fromLatin1("QVideoFrame( QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, [no timestamp])");
|
QTest::newRow("more valid") << g << QString::fromLatin1("QVideoFrame(QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, [no timestamp])");
|
||||||
|
|
||||||
QVideoFrame g2(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
QVideoFrame g2(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
||||||
g2.setStartTime(9000000000LL);
|
g2.setStartTime(9000000000LL);
|
||||||
g2.setEndTime(9000000000LL);
|
g2.setEndTime(9000000000LL);
|
||||||
QTest::newRow("more valid") << g2 << QString::fromLatin1("QVideoFrame( QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, @2:30:00.00)");
|
QTest::newRow("more valid") << g2 << QString::fromLatin1("QVideoFrame(QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, @2:30:00.00)");
|
||||||
|
|
||||||
QVideoFrame g3(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
QVideoFrame g3(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
||||||
g3.setStartTime(900000LL);
|
g3.setStartTime(900000LL);
|
||||||
g3.setEndTime(900000LL);
|
g3.setEndTime(900000LL);
|
||||||
QTest::newRow("more valid single timestamp") << g3 << QString::fromLatin1("QVideoFrame( QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, @00:00.900000)");
|
QTest::newRow("more valid single timestamp") << g3 << QString::fromLatin1("QVideoFrame(QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, @00:00.900000)");
|
||||||
|
|
||||||
QVideoFrame g4(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
QVideoFrame g4(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
||||||
g4.setStartTime(200000000LL);
|
g4.setStartTime(200000000LL);
|
||||||
g4.setEndTime(300000000LL);
|
g4.setEndTime(300000000LL);
|
||||||
QTest::newRow("more valid") << g4 << QString::fromLatin1("QVideoFrame( QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, 03:20.00 - 05:00.00)");
|
QTest::newRow("more valid") << g4 << QString::fromLatin1("QVideoFrame(QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, 03:20.00 - 05:00.00)");
|
||||||
|
|
||||||
QVideoFrame g5(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
QVideoFrame g5(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
||||||
g5.setStartTime(200000000LL);
|
g5.setStartTime(200000000LL);
|
||||||
QTest::newRow("more valid until forever") << g5 << QString::fromLatin1("QVideoFrame( QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, 03:20.00 - forever)");
|
QTest::newRow("more valid until forever") << g5 << QString::fromLatin1("QVideoFrame(QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, 03:20.00 - forever)");
|
||||||
|
|
||||||
QVideoFrame g6(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
QVideoFrame g6(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
||||||
g6.setStartTime(9000000000LL);
|
g6.setStartTime(9000000000LL);
|
||||||
QTest::newRow("more valid for long forever") << g6 << QString::fromLatin1("QVideoFrame( QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, 2:30:00.00 - forever)");
|
QTest::newRow("more valid for long forever") << g6 << QString::fromLatin1("QVideoFrame(QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, 2:30:00.00 - forever)");
|
||||||
|
|
||||||
|
QVideoFrame g7(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
|
||||||
|
g7.setStartTime(9000000000LL);
|
||||||
|
g7.setMetaData("bar", 42);
|
||||||
|
QTest::newRow("more valid for long forever + metadata") << g7 << QString::fromLatin1("QVideoFrame(QSize(320, 240) , Format_ARGB32, NoHandle, NotMapped, 2:30:00.00 - forever, metaData: QMap((\"bar\", QVariant(int, 42) ) ) )");
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QVideoFrame::debug()
|
void tst_QVideoFrame::debug()
|
||||||
|
|||||||
Reference in New Issue
Block a user