Declare more metatypes and debug operators.

Nearly all of the multimedia metatypes used in the auto tests are
now declared properly, and a large number of the types have debug
operators as well.

Removed the superfluous decls as well.

Change-Id: I42cfe37562db0c71d9811b4577fc326a3326ccc9
Reviewed-by: Jonas Rabbe <jonas.rabbe@nokia.com>
This commit is contained in:
Michael Goddard
2011-11-01 12:46:48 +10:00
committed by Qt by Nokia
parent 6a3a442ea6
commit 7dfb883df6
30 changed files with 720 additions and 168 deletions

View File

@@ -63,18 +63,6 @@ const int NotifyIntervalMs = 100;
// Size of the level calculation window in microseconds
const int LevelWindowUs = 0.1 * 1000000;
//-----------------------------------------------------------------------------
// Helper functions
//-----------------------------------------------------------------------------
QDebug& operator<<(QDebug &debug, const QAudioFormat &format)
{
debug << format.frequency() << "Hz"
<< format.channels() << "channels";
return debug;
}
//-----------------------------------------------------------------------------
// Constructor and destructor
//-----------------------------------------------------------------------------

View File

@@ -57,9 +57,6 @@
//#define DEBUG_VIDEO_SURFACE_SINK
Q_DECLARE_METATYPE(QVideoSurfaceFormat)
QVideoSurfaceGstDelegate::QVideoSurfaceGstDelegate(
QAbstractVideoSurface *surface)
: m_surface(surface)

View File

@@ -41,7 +41,7 @@
#include <qaudio.h>
#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -98,6 +98,48 @@ public:
\value AudioInput audio input device
*/
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, QAudio::Error error)
{
switch (error) {
case QAudio::NoError:
return dbg.nospace() << "NoError";
case QAudio::OpenError:
return dbg.nospace() << "OpenError";
case QAudio::IOError:
return dbg.nospace() << "IOError";
case QAudio::UnderrunError:
return dbg.nospace() << "UnderrunError";
case QAudio::FatalError:
return dbg.nospace() << "FatalError";
}
}
QDebug operator<<(QDebug dbg, QAudio::State state)
{
switch (state) {
case QAudio::ActiveState:
return dbg.nospace() << "ActiveState";
case QAudio::SuspendedState:
return dbg.nospace() << "SuspendedState";
case QAudio::StoppedState:
return dbg.nospace() << "StoppedState";
case QAudio::IdleState:
return dbg.nospace() << "IdleState";
}
}
QDebug operator<<(QDebug dbg, QAudio::Mode mode)
{
switch (mode) {
case QAudio::AudioInput:
return dbg.nospace() << "AudioInput";
case QAudio::AudioOutput:
return dbg.nospace() << "AudioOutput";
}
}
#endif
QT_END_NAMESPACE

View File

@@ -63,12 +63,18 @@ namespace QAudio
enum Mode { AudioInput, AudioOutput };
}
QT_END_NAMESPACE
#ifndef QT_NO_DEBUG_STREAM
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::Error error);
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::State state);
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug dbg, QAudio::Mode mode);
#endif
QT_END_HEADER
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QAudio::Error)
Q_DECLARE_METATYPE(QAudio::State)
Q_DECLARE_METATYPE(QAudio::Mode)
QT_END_HEADER
#endif // QAUDIO_H

View File

@@ -44,21 +44,6 @@
QT_BEGIN_NAMESPACE
// Debugging
QDebug operator<<(QDebug dbg, const QAudioFormat& audioFormat)
{
dbg.nospace() << "QAudioFormat(" <<
audioFormat.frequency() << "," <<
audioFormat.channels() << "," <<
audioFormat.sampleSize()<< "," <<
audioFormat.codec() << "," <<
audioFormat.byteOrder() << "," <<
audioFormat.sampleType() << ")";
return dbg.space();
}
// Conversion
QAudioFormat toQAudioFormat(AudioStreamBasicDescription const& sf)
{

View File

@@ -67,10 +67,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Multimedia)
extern QDebug operator<<(QDebug dbg, const QAudioFormat& audioFormat);
extern QAudioFormat toQAudioFormat(const AudioStreamBasicDescription& streamFormat);
extern AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const& audioFormat);

View File

@@ -109,8 +109,8 @@ private:
QT_END_NAMESPACE
QT_END_HEADER
Q_DECLARE_METATYPE(QAudioDeviceInfo)
QT_END_HEADER
#endif // QAUDIODEVICEINFO_H

View File

@@ -403,5 +403,46 @@ QAudioFormat::SampleType QAudioFormat::sampleType() const
\value LittleEndian Samples are little endian byte order
*/
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, QAudioFormat::Endian endian)
{
switch (endian) {
case QAudioFormat::BigEndian:
return dbg.nospace() << "BigEndian";
case QAudioFormat::LittleEndian:
return dbg.nospace() << "LittleEndian";
}
}
QDebug operator<<(QDebug dbg, QAudioFormat::SampleType type)
{
switch (type) {
case QAudioFormat::SignedInt:
return dbg.nospace() << "SignedInt";
case QAudioFormat::UnSignedInt:
return dbg.nospace() << "UnSignedInt";
case QAudioFormat::Float:
return dbg.nospace() << "Float";
default:
return dbg.nospace() << "Unknown";
}
}
QDebug operator<<(QDebug dbg, const QAudioFormat &f)
{
dbg.nospace() << "QAudioFormat(" << f.sampleRate();
dbg.nospace() << "Hz, " << f.sampleSize();
dbg.nospace() << "bit, channelCount=" << f.channelCount();
dbg.nospace() << ", sampleType=" << f.sampleType();
dbg.nospace() << ", byteOrder=" << f.byteOrder();
dbg.nospace() << ", codec=" << f.codec();
dbg.nospace() << ")";
return dbg.space();
}
#endif
QT_END_NAMESPACE

View File

@@ -55,8 +55,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Multimedia)
class QAudioFormatPrivate;
class Q_MULTIMEDIA_EXPORT QAudioFormat
@@ -101,9 +99,18 @@ private:
QSharedDataPointer<QAudioFormatPrivate> d;
};
#ifndef QT_NO_DEBUG_STREAM
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, const QAudioFormat &);
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QAudioFormat::SampleType);
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QAudioFormat::Endian);
#endif
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QAudioFormat)
Q_DECLARE_METATYPE(QAudioFormat::SampleType)
Q_DECLARE_METATYPE(QAudioFormat::Endian)
QT_END_HEADER
#endif // QAUDIOFORMAT_H

View File

@@ -219,6 +219,20 @@ QDebug operator<<(QDebug dbg, QAbstractVideoBuffer::HandleType type)
return dbg.nospace() << QString(QLatin1String("UserHandle(%1)")).arg(int(type)).toAscii().constData();
}
}
QDebug operator<<(QDebug dbg, QAbstractVideoBuffer::MapMode mode)
{
switch (mode) {
case QAbstractVideoBuffer::ReadOnly:
return dbg.nospace() << "ReadOnly";
case QAbstractVideoBuffer::ReadWrite:
return dbg.nospace() << "ReadWrite";
case QAbstractVideoBuffer::WriteOnly:
return dbg.nospace() << "WriteOnly";
default:
return dbg.nospace() << "NotMapped";
}
}
#endif
QT_END_NAMESPACE

View File

@@ -104,6 +104,7 @@ private:
#ifndef QT_NO_DEBUG_STREAM
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QAbstractVideoBuffer::HandleType);
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QAbstractVideoBuffer::MapMode);
#endif
QT_END_NAMESPACE

View File

@@ -46,12 +46,10 @@
#include "qvideosurfaceformat.h"
#include <QtCore/qvariant.h>
#include <QDebug>
QT_BEGIN_NAMESPACE
Q_DECLARE_METATYPE(QVideoSurfaceFormat)
Q_DECLARE_METATYPE(QAbstractVideoSurface::Error)
class QAbstractVideoSurfacePrivate {
@@ -340,6 +338,25 @@ void QAbstractVideoSurface::setNativeResolution(const QSize &resolution)
\since 1.1
*/
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QAbstractVideoSurface::Error& error)
{
switch (error) {
case QAbstractVideoSurface::UnsupportedFormatError:
return dbg.nospace() << "UnsupportedFormatError";
case QAbstractVideoSurface::IncorrectFormatError:
return dbg.nospace() << "IncorrectFormatError";
case QAbstractVideoSurface::StoppedError:
return dbg.nospace() << "StoppedError";
case QAbstractVideoSurface::ResourceError:
return dbg.nospace() << "ResourceError";
default:
return dbg.nospace() << "NoError";
}
}
#endif
QT_END_NAMESPACE
#include "moc_qabstractvideosurface.cpp"

View File

@@ -51,7 +51,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Multimedia)
class QRectF;
class QVideoSurfaceFormat;
@@ -107,8 +106,14 @@ private:
QScopedPointer<QAbstractVideoSurfacePrivate> d_ptr;
};
#ifndef QT_NO_DEBUG_STREAM
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, const QAbstractVideoSurface::Error &);
#endif
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QAbstractVideoSurface::Error)
QT_END_HEADER
#endif

View File

@@ -640,7 +640,10 @@ QVariant QVideoFrame::handle() const
}
/*!
Returns the presentation time when the frame should be displayed.
Returns the presentation time (in microseconds) when the frame should be displayed.
An invalid time is represented as -1.
\since 1.0
*/
qint64 QVideoFrame::startTime() const
@@ -649,7 +652,10 @@ qint64 QVideoFrame::startTime() const
}
/*!
Sets the presentation \a time when the frame should be displayed.
Sets the presentation \a time (in microseconds) when the frame should initially be displayed.
An invalid time is represented as -1.
\since 1.0
*/
void QVideoFrame::setStartTime(qint64 time)
@@ -658,7 +664,9 @@ void QVideoFrame::setStartTime(qint64 time)
}
/*!
Returns the presentation time when a frame should stop being displayed.
Returns the presentation time (in microseconds) when a frame should stop being displayed.
An invalid time is represented as -1.
\since 1.0
*/
@@ -668,7 +676,10 @@ qint64 QVideoFrame::endTime() const
}
/*!
Sets the presentation \a time when a frame should stop being displayed.
Sets the presentation \a time (in microseconds) when a frame should stop being displayed.
An invalid time is represented as -1.
\since 1.0
*/
void QVideoFrame::setEndTime(qint64 time)
@@ -761,7 +772,6 @@ QImage::Format QVideoFrame::imageFormatFromPixelFormat(PixelFormat format)
}
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, QVideoFrame::PixelFormat pf)
{
switch (pf) {
@@ -837,6 +847,99 @@ QDebug operator<<(QDebug dbg, QVideoFrame::PixelFormat pf)
}
}
QDebug operator<<(QDebug dbg, QVideoFrame::FieldType f)
{
switch (f) {
case QVideoFrame::TopField:
return dbg.nospace() << "TopField";
case QVideoFrame::BottomField:
return dbg.nospace() << "BottomField";
case QVideoFrame::InterlacedFrame:
return dbg.nospace() << "InterlacedFrame";
default:
return dbg.nospace() << "ProgressiveFrame";
}
}
static QString qFormatTimeStamps(qint64 start, qint64 end)
{
// Early out for invalid.
if (start < 0)
return QLatin1String("[no timestamp]");
bool onlyOne = (start == end);
// [hh:]mm:ss.ms
const int s_millis = start % 1000000;
start /= 1000000;
const int s_seconds = start % 60;
start /= 60;
const int s_minutes = start % 60;
start /= 60;
if (onlyOne) {
if (start > 0)
return QString::fromLatin1("@%1:%2:%3.%4")
.arg(start, 1, 10, QLatin1Char('0'))
.arg(s_minutes, 2, 10, QLatin1Char('0'))
.arg(s_seconds, 2, 10, QLatin1Char('0'))
.arg(s_millis, 2, 10, QLatin1Char('0'));
else
return QString::fromLatin1("@%1:%2.%3")
.arg(s_minutes, 2, 10, QLatin1Char('0'))
.arg(s_seconds, 2, 10, QLatin1Char('0'))
.arg(s_millis, 2, 10, QLatin1Char('0'));
} else if (end == -1) {
// Similar to start-start, except it means keep displaying it?
if (start > 0)
return QString::fromLatin1("%1:%2:%3.%4 - forever")
.arg(start, 1, 10, QLatin1Char('0'))
.arg(s_minutes, 2, 10, QLatin1Char('0'))
.arg(s_seconds, 2, 10, QLatin1Char('0'))
.arg(s_millis, 2, 10, QLatin1Char('0'));
else
return QString::fromLatin1("%1:%2.%3 - forever")
.arg(s_minutes, 2, 10, QLatin1Char('0'))
.arg(s_seconds, 2, 10, QLatin1Char('0'))
.arg(s_millis, 2, 10, QLatin1Char('0'));
} else {
const int e_millis = end % 1000000;
end /= 1000000;
const int e_seconds = end % 60;
end /= 60;
const int e_minutes = end % 60;
end /= 60;
if (start > 0 || end > 0)
return QString::fromLatin1("%1:%2:%3.%4 - %5:%6:%7.%8")
.arg(start, 1, 10, QLatin1Char('0'))
.arg(s_minutes, 2, 10, QLatin1Char('0'))
.arg(s_seconds, 2, 10, QLatin1Char('0'))
.arg(s_millis, 2, 10, QLatin1Char('0'))
.arg(end, 1, 10, QLatin1Char('0'))
.arg(e_minutes, 2, 10, QLatin1Char('0'))
.arg(e_seconds, 2, 10, QLatin1Char('0'))
.arg(e_millis, 2, 10, QLatin1Char('0'));
else
return QString::fromLatin1("%1:%2.%3 - %4:%5.%6")
.arg(s_minutes, 2, 10, QLatin1Char('0'))
.arg(s_seconds, 2, 10, QLatin1Char('0'))
.arg(s_millis, 2, 10, QLatin1Char('0'))
.arg(e_minutes, 2, 10, QLatin1Char('0'))
.arg(e_seconds, 2, 10, QLatin1Char('0'))
.arg(e_millis, 2, 10, QLatin1Char('0'));
}
}
QDebug operator<<(QDebug dbg, const QVideoFrame& f)
{
return dbg << "QVideoFrame(" << f.size() << ","
<< f.pixelFormat() << ", "
<< f.handleType() << ", "
<< f.mapMode() << ", "
<< qFormatTimeStamps(f.startTime(), f.endTime()).toLatin1().constData()
<< ")";
}
#endif
QT_END_NAMESPACE

View File

@@ -164,11 +164,14 @@ private:
};
#ifndef QT_NO_DEBUG_STREAM
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, const QVideoFrame&);
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QVideoFrame::FieldType);
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QVideoFrame::PixelFormat);
#endif
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QVideoFrame)
Q_DECLARE_METATYPE(QVideoFrame::FieldType)
Q_DECLARE_METATYPE(QVideoFrame::PixelFormat)

View File

@@ -591,7 +591,6 @@ void QVideoSurfaceFormat::setProperty(const char *name, const QVariant &value)
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, QVideoSurfaceFormat::YCbCrColorSpace cs)
{
switch (cs) {
@@ -612,6 +611,16 @@ QDebug operator<<(QDebug dbg, QVideoSurfaceFormat::YCbCrColorSpace cs)
}
}
QDebug operator<<(QDebug dbg, QVideoSurfaceFormat::Direction dir)
{
switch (dir) {
case QVideoSurfaceFormat::BottomToTop:
return dbg.nospace() << "BottomToTop";
case QVideoSurfaceFormat::TopToBottom:
return dbg.nospace() << "TopToBottom";
}
}
QDebug operator<<(QDebug dbg, const QVideoSurfaceFormat &f)
{
dbg.nospace() << "QVideoSurfaceFormat(" << f.pixelFormat();

View File

@@ -135,11 +135,13 @@ private:
#ifndef QT_NO_DEBUG_STREAM
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, const QVideoSurfaceFormat &);
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QVideoSurfaceFormat::Direction);
Q_MULTIMEDIA_EXPORT QDebug operator<<(QDebug, QVideoSurfaceFormat::YCbCrColorSpace);
#endif
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QVideoSurfaceFormat)
Q_DECLARE_METATYPE(QVideoSurfaceFormat::Direction)
Q_DECLARE_METATYPE(QVideoSurfaceFormat::YCbCrColorSpace)

View File

@@ -54,8 +54,6 @@
#include <QtOpenGL/qgl.h>
#endif
Q_DECLARE_METATYPE(QVideoSurfaceFormat)
QT_BEGIN_NAMESPACE
class QGraphicsVideoItemPrivate

View File

@@ -7,6 +7,7 @@ SUBDIRS += \
qaudiodeviceinfo \
qaudioformat \
qaudioinput \
qaudionamespace \
qaudiooutput \
qmediabindableinterface \
qmediacontainercontrol \

View File

@@ -45,6 +45,12 @@
#include <qabstractvideobuffer.h>
// Adds an enum, and the stringized version
#define ADD_ENUM_TEST(x) \
QTest::newRow(#x) \
<< QAbstractVideoBuffer::x \
<< QString(QLatin1String(#x));
class tst_QAbstractVideoBuffer : public QObject
{
Q_OBJECT
@@ -63,6 +69,8 @@ private slots:
void handleType();
void handle();
void mapMode();
void mapModeDebug_data();
void mapModeDebug();
};
class QtTestVideoBuffer : public QAbstractVideoBuffer
@@ -100,21 +108,16 @@ void tst_QAbstractVideoBuffer::cleanup()
{
}
#define ADD_HANDLE_TEST(x) \
QTest::newRow(#x) \
<< QAbstractVideoBuffer::x \
<< QString(QLatin1String(#x));
void tst_QAbstractVideoBuffer::handleType_data()
{
QTest::addColumn<QAbstractVideoBuffer::HandleType>("type");
QTest::addColumn<QString>("stringized");
ADD_HANDLE_TEST(NoHandle);
ADD_HANDLE_TEST(GLTextureHandle);
ADD_HANDLE_TEST(XvShmImageHandle);
ADD_HANDLE_TEST(QPixmapHandle);
ADD_HANDLE_TEST(CoreImageHandle);
ADD_ENUM_TEST(NoHandle);
ADD_ENUM_TEST(GLTextureHandle);
ADD_ENUM_TEST(XvShmImageHandle);
ADD_ENUM_TEST(QPixmapHandle);
ADD_ENUM_TEST(CoreImageHandle);
// User handles are different
@@ -150,6 +153,26 @@ void tst_QAbstractVideoBuffer::mapMode()
QVERIFY2(maptest.mapMode() == QAbstractVideoBuffer::ReadWrite, "ReadWrite Failed");
}
void tst_QAbstractVideoBuffer::mapModeDebug_data()
{
QTest::addColumn<QAbstractVideoBuffer::MapMode>("mapMode");
QTest::addColumn<QString>("stringized");
ADD_ENUM_TEST(NotMapped);
ADD_ENUM_TEST(ReadOnly);
ADD_ENUM_TEST(WriteOnly);
ADD_ENUM_TEST(ReadWrite);
}
void tst_QAbstractVideoBuffer::mapModeDebug()
{
QFETCH(QAbstractVideoBuffer::MapMode, mapMode);
QFETCH(QString, stringized);
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << mapMode;
}
QTEST_MAIN(tst_QAbstractVideoBuffer)
#include "tst_qabstractvideobuffer.moc"

View File

@@ -74,8 +74,6 @@ private slots:
typedef QMap<QAbstractVideoBuffer::HandleType, QVideoFrame::PixelFormat> SupportedFormatMap;
Q_DECLARE_METATYPE(SupportedFormatMap)
Q_DECLARE_METATYPE(QVideoSurfaceFormat)
Q_DECLARE_METATYPE(QAbstractVideoSurface::Error);
class QtTestVideoSurface : public QAbstractVideoSurface
{
@@ -144,21 +142,33 @@ void tst_QAbstractVideoSurface::setError()
QtTestVideoSurface surface;
QCOMPARE(surface.error(), QAbstractVideoSurface::NoError);
QTest::ignoreMessage(QtDebugMsg, "NoError");
qDebug() << QAbstractVideoSurface::NoError;
surface.setError(QAbstractVideoSurface::StoppedError);
QCOMPARE(surface.error(), QAbstractVideoSurface::StoppedError);
QTest::ignoreMessage(QtDebugMsg, "StoppedError");
qDebug() << QAbstractVideoSurface::StoppedError;
surface.setError(QAbstractVideoSurface::ResourceError);
QCOMPARE(surface.error(), QAbstractVideoSurface::ResourceError);
QTest::ignoreMessage(QtDebugMsg, "ResourceError");
qDebug() << QAbstractVideoSurface::ResourceError;
surface.setError(QAbstractVideoSurface::NoError);
QCOMPARE(surface.error(), QAbstractVideoSurface::NoError);
QTest::ignoreMessage(QtDebugMsg, "NoError");
qDebug() << QAbstractVideoSurface::NoError;
surface.setError(QAbstractVideoSurface::UnsupportedFormatError);
QCOMPARE(surface.error(), QAbstractVideoSurface::UnsupportedFormatError);
QTest::ignoreMessage(QtDebugMsg, "UnsupportedFormatError");
qDebug() << QAbstractVideoSurface::UnsupportedFormatError;
surface.setError(QAbstractVideoSurface::IncorrectFormatError);
QCOMPARE(surface.error(), QAbstractVideoSurface::IncorrectFormatError);
QTest::ignoreMessage(QtDebugMsg, "IncorrectFormatError");
qDebug() << QAbstractVideoSurface::IncorrectFormatError;
}
void tst_QAbstractVideoSurface::isFormatSupported_data()

View File

@@ -67,6 +67,9 @@ private slots:
void checkAssignment();
void checkSampleRate();
void checkChannelCount();
void debugOperator();
void debugOperator_data();
};
void tst_QAudioFormat::checkNull()
@@ -114,8 +117,14 @@ void tst_QAudioFormat::checkByteOrder()
audioFormat.setByteOrder(QAudioFormat::LittleEndian);
QVERIFY(audioFormat.byteOrder() == QAudioFormat::LittleEndian);
QTest::ignoreMessage(QtDebugMsg, "LittleEndian");
qDebug() << QAudioFormat::LittleEndian;
audioFormat.setByteOrder(QAudioFormat::BigEndian);
QVERIFY(audioFormat.byteOrder() == QAudioFormat::BigEndian);
QTest::ignoreMessage(QtDebugMsg, "BigEndian");
qDebug() << QAudioFormat::BigEndian;
}
void tst_QAudioFormat::checkSampleType()
@@ -123,12 +132,23 @@ void tst_QAudioFormat::checkSampleType()
QAudioFormat audioFormat;
audioFormat.setSampleType(QAudioFormat::SignedInt);
QVERIFY(audioFormat.sampleType() == QAudioFormat::SignedInt);
QTest::ignoreMessage(QtDebugMsg, "SignedInt");
qDebug() << QAudioFormat::SignedInt;
audioFormat.setSampleType(QAudioFormat::Unknown);
QVERIFY(audioFormat.sampleType() == QAudioFormat::Unknown);
QTest::ignoreMessage(QtDebugMsg, "Unknown");
qDebug() << QAudioFormat::Unknown;
audioFormat.setSampleType(QAudioFormat::UnSignedInt);
QVERIFY(audioFormat.sampleType() == QAudioFormat::UnSignedInt);
QTest::ignoreMessage(QtDebugMsg, "UnSignedInt");
qDebug() << QAudioFormat::UnSignedInt;
audioFormat.setSampleType(QAudioFormat::Float);
QVERIFY(audioFormat.sampleType() == QAudioFormat::Float);
QTest::ignoreMessage(QtDebugMsg, "Float");
qDebug() << QAudioFormat::Float;
}
void tst_QAudioFormat::checkEquality()
@@ -210,6 +230,42 @@ void tst_QAudioFormat::checkChannelCount()
QVERIFY(audioFormat.channels() == 5);
}
void tst_QAudioFormat::debugOperator_data()
{
QTest::addColumn<QAudioFormat>("format");
QTest::addColumn<QString>("stringized");
// A small sampling
QAudioFormat f;
QTest::newRow("plain") << f << QString::fromLatin1("QAudioFormat(-1Hz, -1bit, channelCount=-1, sampleType=Unknown, byteOrder=LittleEndian, codec=\"\") ");
f.setSampleRate(22050);
f.setByteOrder(QAudioFormat::LittleEndian);
f.setChannelCount(4);
f.setCodec("audio/pcm");
f.setSampleType(QAudioFormat::Float);
QTest::newRow("float") << f << QString::fromLatin1("QAudioFormat(22050Hz, -1bit, channelCount=4, sampleType=Float, byteOrder=LittleEndian, codec=\"audio/pcm\") ");
f.setSampleType(QAudioFormat::UnSignedInt);
QTest::newRow("unsigned") << f << QString::fromLatin1("QAudioFormat(22050Hz, -1bit, channelCount=4, sampleType=UnSignedInt, byteOrder=LittleEndian, codec=\"audio/pcm\") ");
f.setSampleRate(44100);
QTest::newRow("44.1 unsigned") << f << QString::fromLatin1("QAudioFormat(44100Hz, -1bit, channelCount=4, sampleType=UnSignedInt, byteOrder=LittleEndian, codec=\"audio/pcm\") ");
f.setByteOrder(QAudioFormat::BigEndian);
QTest::newRow("44.1 big unsigned") << f << QString::fromLatin1("QAudioFormat(44100Hz, -1bit, channelCount=4, sampleType=UnSignedInt, byteOrder=BigEndian, codec=\"audio/pcm\") ");
}
void tst_QAudioFormat::debugOperator()
{
QFETCH(QAudioFormat, format);
QFETCH(QString, stringized);
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << format;
}
QTEST_MAIN(tst_QAudioFormat)
#include "tst_qaudioformat.moc"

View File

@@ -68,8 +68,6 @@
} while(0)
#endif
Q_DECLARE_METATYPE(QAudioFormat)
class tst_QAudioInput : public QObject
{
Q_OBJECT

View File

@@ -0,0 +1,8 @@
CONFIG += testcase
TARGET = tst_qaudionamespace
QT += core multimedia-private testlib
CONFIG += no_private_qt_headers_warning
SOURCES += tst_qaudionamespace.cpp

View File

@@ -0,0 +1,127 @@
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
//TESTED_COMPONENT=src/multimedia
#include <QtTest/QtTest>
#include "qaudio.h"
// Adds an enum, and the stringized version
#define ADD_ENUM_TEST(x) \
QTest::newRow(#x) \
<< QAudio::x \
<< QString(QLatin1String(#x));
class tst_QAudioNamespace : public QObject
{
Q_OBJECT
private slots:
void debugError();
void debugError_data();
void debugState();
void debugState_data();
void debugMode();
void debugMode_data();
};
void tst_QAudioNamespace::debugError_data()
{
QTest::addColumn<QAudio::Error>("error");
QTest::addColumn<QString>("stringized");
ADD_ENUM_TEST(NoError);
ADD_ENUM_TEST(OpenError);
ADD_ENUM_TEST(IOError);
ADD_ENUM_TEST(UnderrunError);
ADD_ENUM_TEST(FatalError);
}
void tst_QAudioNamespace::debugError()
{
QFETCH(QAudio::Error, error);
QFETCH(QString, stringized);
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << error;
}
void tst_QAudioNamespace::debugState_data()
{
QTest::addColumn<QAudio::State>("state");
QTest::addColumn<QString>("stringized");
ADD_ENUM_TEST(ActiveState);
ADD_ENUM_TEST(SuspendedState);
ADD_ENUM_TEST(StoppedState);
ADD_ENUM_TEST(IdleState);
}
void tst_QAudioNamespace::debugState()
{
QFETCH(QAudio::State, state);
QFETCH(QString, stringized);
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << state;
}
void tst_QAudioNamespace::debugMode_data()
{
QTest::addColumn<QAudio::Mode>("mode");
QTest::addColumn<QString>("stringized");
ADD_ENUM_TEST(AudioInput);
ADD_ENUM_TEST(AudioOutput);
}
void tst_QAudioNamespace::debugMode()
{
QFETCH(QAudio::Mode, mode);
QFETCH(QString, stringized);
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << mode;
}
QTEST_MAIN(tst_QAudioNamespace)
#include "tst_qaudionamespace.moc"

View File

@@ -68,8 +68,6 @@
} while(0)
#endif
Q_DECLARE_METATYPE(QAudioFormat)
class tst_QAudioOutput : public QObject
{
Q_OBJECT

View File

@@ -120,9 +120,6 @@ QT_USE_NAMESPACE
it may be less stable.
*/
Q_DECLARE_METATYPE(QVideoFrame)
class tst_QCameraBackend: public QObject
{
Q_OBJECT

View File

@@ -47,6 +47,13 @@
#include <QtGui/QImage>
#include <QtCore/QPointer>
// Adds an enum, and the stringized version
#define ADD_ENUM_TEST(x) \
QTest::newRow(#x) \
<< QVideoFrame::x \
<< QString(QLatin1String(#x));
class tst_QVideoFrame : public QObject
{
Q_OBJECT
@@ -84,13 +91,21 @@ private slots:
void formatConversion_data();
void formatConversion();
void debugType_data();
void debugType();
void debug_data();
void debug();
void debugFormat_data();
void debugFormat();
void isMapped();
void isReadable();
void isWritable();
};
Q_DECLARE_METATYPE(QImage::Format)
Q_DECLARE_METATYPE(QVideoFrame)
class QtTestVideoBuffer : public QObject, public QAbstractVideoBuffer
{
@@ -963,6 +978,148 @@ void tst_QVideoFrame::isWritable()
frame.unmap();
}
void tst_QVideoFrame::debugType_data()
{
QTest::addColumn<QVideoFrame::FieldType>("fieldType");
QTest::addColumn<QString>("stringized");
ADD_ENUM_TEST(ProgressiveFrame);
ADD_ENUM_TEST(InterlacedFrame);
ADD_ENUM_TEST(TopField);
ADD_ENUM_TEST(BottomField);
}
void tst_QVideoFrame::debugType()
{
QFETCH(QVideoFrame::FieldType, fieldType);
QFETCH(QString, stringized);
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << fieldType;
}
void tst_QVideoFrame::debug_data()
{
QTest::addColumn<QVideoFrame>("frame");
QTest::addColumn<QString>("stringized");
QVideoFrame f;
QTest::newRow("default") << f << QString::fromLatin1("QVideoFrame( QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
QVideoFrame f2;
f2.setStartTime(12345);
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)");
QVideoFrame f3;
f3.setFieldType(QVideoFrame::ProgressiveFrame);
QTest::newRow("times prog") << f3 << QString::fromLatin1("QVideoFrame( QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
QVideoFrame f4;
f4.setFieldType(QVideoFrame::TopField);
QTest::newRow("times top") << f4 << QString::fromLatin1("QVideoFrame( QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
QVideoFrame f5;
f5.setFieldType(QVideoFrame::TopField);
f5.setEndTime(90000000000LL);
QTest::newRow("end but no start") << f5 << QString::fromLatin1("QVideoFrame( QSize(-1, -1) , Format_Invalid, NoHandle, NotMapped, [no timestamp])");
QVideoFrame f6;
f6.setStartTime(12345000000LL);
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)");
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])");
QVideoFrame g2(0, QSize(320,240), 640, QVideoFrame::Format_ARGB32);
g2.setStartTime(9000000000LL);
g2.setEndTime(9000000000LL);
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);
g3.setStartTime(900000LL);
g3.setEndTime(900000LL);
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);
g4.setStartTime(200000000LL);
g4.setEndTime(300000000LL);
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);
g5.setStartTime(200000000LL);
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);
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)");
}
void tst_QVideoFrame::debug()
{
QFETCH(QVideoFrame, frame);
QFETCH(QString, stringized);
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << frame;
}
void tst_QVideoFrame::debugFormat_data()
{
QTest::addColumn<QVideoFrame::PixelFormat>("format");
QTest::addColumn<QString>("stringized");
ADD_ENUM_TEST(Format_Invalid);
ADD_ENUM_TEST(Format_ARGB32);
ADD_ENUM_TEST(Format_ARGB32_Premultiplied);
ADD_ENUM_TEST(Format_RGB32);
ADD_ENUM_TEST(Format_RGB24);
ADD_ENUM_TEST(Format_RGB565);
ADD_ENUM_TEST(Format_RGB555);
ADD_ENUM_TEST(Format_ARGB8565_Premultiplied);
ADD_ENUM_TEST(Format_BGRA32);
ADD_ENUM_TEST(Format_BGRA32_Premultiplied);
ADD_ENUM_TEST(Format_BGR32);
ADD_ENUM_TEST(Format_BGR24);
ADD_ENUM_TEST(Format_BGR565);
ADD_ENUM_TEST(Format_BGR555);
ADD_ENUM_TEST(Format_BGRA5658_Premultiplied);
ADD_ENUM_TEST(Format_AYUV444);
ADD_ENUM_TEST(Format_AYUV444_Premultiplied);
ADD_ENUM_TEST(Format_YUV444);
ADD_ENUM_TEST(Format_YUV420P);
ADD_ENUM_TEST(Format_YV12);
ADD_ENUM_TEST(Format_UYVY);
ADD_ENUM_TEST(Format_YUYV);
ADD_ENUM_TEST(Format_NV12);
ADD_ENUM_TEST(Format_NV21);
ADD_ENUM_TEST(Format_IMC1);
ADD_ENUM_TEST(Format_IMC2);
ADD_ENUM_TEST(Format_IMC3);
ADD_ENUM_TEST(Format_IMC4);
ADD_ENUM_TEST(Format_Y8);
ADD_ENUM_TEST(Format_Y16);
ADD_ENUM_TEST(Format_Jpeg);
ADD_ENUM_TEST(Format_CameraRaw);
ADD_ENUM_TEST(Format_AdobeDng);
// User enums are formatted differently
QTest::newRow("user 1000") << QVideoFrame::Format_User << QString::fromLatin1("UserType(1000)");
QTest::newRow("user 1005") << QVideoFrame::PixelFormat(QVideoFrame::Format_User + 5) << QString::fromLatin1("UserType(1005)");
}
void tst_QVideoFrame::debugFormat()
{
QFETCH(QVideoFrame::PixelFormat, format);
QFETCH(QString, stringized);
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << format;
}
QTEST_MAIN(tst_QVideoFrame)

View File

@@ -45,6 +45,12 @@
#include <qvideosurfaceformat.h>
// Adds an enum, and the stringized version
#define ADD_ENUM_TEST(x) \
QTest::newRow(#x) \
<< QVideoSurfaceFormat::x \
<< QString(QLatin1String(#x));
class tst_QVideoSurfaceFormat : public QObject
{
Q_OBJECT
@@ -70,12 +76,12 @@ private slots:
void scanLineDirection();
void frameRate_data();
void frameRate();
void yCbCrColorSpace_data();
void yCbCrColorSpace();
void pixelAspectRatio_data();
void pixelAspectRatio();
void sizeHint_data();
void sizeHint();
void yCbCrColorSpaceEnum_data();
void yCbCrColorSpaceEnum ();
void staticPropertyNames();
void dynamicProperty();
void compare();
@@ -83,8 +89,6 @@ private slots:
void assign();
void isValid();
void yCbCrColorSpaceEnum_data();
void yCbCrColorSpaceEnum ();
void copyAllParameters ();
void assignAllParameters ();
@@ -308,17 +312,16 @@ void tst_QVideoSurfaceFormat::viewport()
void tst_QVideoSurfaceFormat::scanLineDirection_data()
{
QTest::addColumn<QVideoSurfaceFormat::Direction>("direction");
QTest::addColumn<QString>("stringized");
QTest::newRow("top to bottom")
<< QVideoSurfaceFormat::TopToBottom;
QTest::newRow("bottom to top")
<< QVideoSurfaceFormat::BottomToTop;
ADD_ENUM_TEST(TopToBottom);
ADD_ENUM_TEST(BottomToTop);
}
void tst_QVideoSurfaceFormat::scanLineDirection()
{
QFETCH(QVideoSurfaceFormat::Direction, direction);
QFETCH(QString, stringized);
{
QVideoSurfaceFormat format(QSize(16, 16), QVideoFrame::Format_RGB32);
@@ -340,8 +343,53 @@ void tst_QVideoSurfaceFormat::scanLineDirection()
qvariant_cast<QVideoSurfaceFormat::Direction>(format.property("scanLineDirection")),
direction);
}
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << direction;
}
void tst_QVideoSurfaceFormat::yCbCrColorSpaceEnum_data()
{
QTest::addColumn<QVideoSurfaceFormat::YCbCrColorSpace>("colorspace");
QTest::addColumn<QString>("stringized");
ADD_ENUM_TEST(YCbCr_BT601);
ADD_ENUM_TEST(YCbCr_BT709);
ADD_ENUM_TEST(YCbCr_xvYCC601);
ADD_ENUM_TEST(YCbCr_xvYCC709);
ADD_ENUM_TEST(YCbCr_JPEG);
ADD_ENUM_TEST(YCbCr_CustomMatrix);
ADD_ENUM_TEST(YCbCr_Undefined);
}
/* Test case for Enum YCbCr_BT601, YCbCr_xvYCC709 */
void tst_QVideoSurfaceFormat::yCbCrColorSpaceEnum()
{
QFETCH(QVideoSurfaceFormat::YCbCrColorSpace, colorspace);
QFETCH(QString, stringized);
{
QVideoSurfaceFormat format(QSize(64, 64), QVideoFrame::Format_RGB32);
format.setYCbCrColorSpace(colorspace);
QCOMPARE(format.yCbCrColorSpace(), colorspace);
QCOMPARE(qvariant_cast<QVideoSurfaceFormat::YCbCrColorSpace>(format.property("yCbCrColorSpace")),
colorspace);
}
{
QVideoSurfaceFormat format(QSize(64, 64), QVideoFrame::Format_RGB32);
format.setProperty("yCbCrColorSpace", qVariantFromValue(colorspace));
QCOMPARE(format.yCbCrColorSpace(), colorspace);
QCOMPARE(qvariant_cast<QVideoSurfaceFormat::YCbCrColorSpace>(format.property("yCbCrColorSpace")),
colorspace);
}
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << colorspace;
}
void tst_QVideoSurfaceFormat::frameRate_data()
{
QTest::addColumn<qreal>("frameRate");
@@ -379,42 +427,6 @@ void tst_QVideoSurfaceFormat::frameRate()
}
}
void tst_QVideoSurfaceFormat::yCbCrColorSpace_data()
{
QTest::addColumn<QVideoSurfaceFormat::YCbCrColorSpace>("colorspace");
QTest::newRow("undefined")
<< QVideoSurfaceFormat::YCbCr_Undefined;
QTest::newRow("bt709")
<< QVideoSurfaceFormat::YCbCr_BT709;
QTest::newRow("xvYCC601")
<< QVideoSurfaceFormat::YCbCr_xvYCC601;
QTest::newRow("JPEG")
<< QVideoSurfaceFormat::YCbCr_JPEG;
}
void tst_QVideoSurfaceFormat::yCbCrColorSpace()
{
QFETCH(QVideoSurfaceFormat::YCbCrColorSpace, colorspace);
{
QVideoSurfaceFormat format(QSize(64, 64), QVideoFrame::Format_RGB32);
format.setYCbCrColorSpace(colorspace);
QCOMPARE(format.yCbCrColorSpace(), colorspace);
QCOMPARE(qvariant_cast<QVideoSurfaceFormat::YCbCrColorSpace>(format.property("yCbCrColorSpace")),
colorspace);
}
{
QVideoSurfaceFormat format(QSize(64, 64), QVideoFrame::Format_RGB32);
format.setProperty("yCbCrColorSpace", qVariantFromValue(colorspace));
QCOMPARE(format.yCbCrColorSpace(), colorspace);
QCOMPARE(qvariant_cast<QVideoSurfaceFormat::YCbCrColorSpace>(format.property("yCbCrColorSpace")),
colorspace);
}
}
void tst_QVideoSurfaceFormat::pixelAspectRatio_data()
{
QTest::addColumn<QSize>("aspectRatio");
@@ -768,54 +780,6 @@ void tst_QVideoSurfaceFormat::assign()
QCOMPARE(original != copy, true);
}
/* Test case for Enum YCbCr_BT601, YCbCr_xvYCC709 */
#define ADD_YCBCR_TEST(x) \
QTest::newRow(#x) \
<< QVideoSurfaceFormat::x \
<< QString(QLatin1String(#x));
void tst_QVideoSurfaceFormat::yCbCrColorSpaceEnum_data()
{
QTest::addColumn<QVideoSurfaceFormat::YCbCrColorSpace>("colorspace");
QTest::addColumn<QString>("stringized");
ADD_YCBCR_TEST(YCbCr_BT601);
ADD_YCBCR_TEST(YCbCr_BT709);
ADD_YCBCR_TEST(YCbCr_xvYCC601);
ADD_YCBCR_TEST(YCbCr_xvYCC709);
ADD_YCBCR_TEST(YCbCr_JPEG);
ADD_YCBCR_TEST(YCbCr_CustomMatrix);
ADD_YCBCR_TEST(YCbCr_Undefined);
}
/* Test case for Enum YCbCr_BT601, YCbCr_xvYCC709 */
void tst_QVideoSurfaceFormat::yCbCrColorSpaceEnum()
{
QFETCH(QVideoSurfaceFormat::YCbCrColorSpace, colorspace);
QFETCH(QString, stringized);
{
QVideoSurfaceFormat format(QSize(64, 64), QVideoFrame::Format_RGB32);
format.setYCbCrColorSpace(colorspace);
QCOMPARE(format.yCbCrColorSpace(), colorspace);
QCOMPARE(qvariant_cast<QVideoSurfaceFormat::YCbCrColorSpace>(format.property("yCbCrColorSpace")),
colorspace);
}
{
QVideoSurfaceFormat format(QSize(64, 64), QVideoFrame::Format_RGB32);
format.setProperty("yCbCrColorSpace", qVariantFromValue(colorspace));
QCOMPARE(format.yCbCrColorSpace(), colorspace);
QCOMPARE(qvariant_cast<QVideoSurfaceFormat::YCbCrColorSpace>(format.property("yCbCrColorSpace")),
colorspace);
}
QTest::ignoreMessage(QtDebugMsg, stringized.toLatin1().constData());
qDebug() << colorspace;
}
/* Test case for api isValid */
void tst_QVideoSurfaceFormat::isValid()
{

View File

@@ -319,7 +319,6 @@ void tst_QWaveDecoder::readPerByte()
}
Q_DECLARE_METATYPE(tst_QWaveDecoder::Corruption)
Q_DECLARE_METATYPE(QAudioFormat::Endian)
QTEST_MAIN(tst_QWaveDecoder)