diff options
-rw-r--r-- | tests/auto/mediaobject/dummy/README | 1 | ||||
-rw-r--r-- | tests/auto/mediaobject/dummy/audiooutput.cpp | 53 | ||||
-rw-r--r-- | tests/auto/mediaobject/dummy/audiooutput.h | 41 | ||||
-rw-r--r-- | tests/auto/mediaobject/dummy/backend.cpp | 149 | ||||
-rw-r--r-- | tests/auto/mediaobject/dummy/backend.h | 55 | ||||
-rw-r--r-- | tests/auto/mediaobject/dummy/dummy.pro | 23 | ||||
-rw-r--r-- | tests/auto/mediaobject/dummy/mediaobject.cpp | 397 | ||||
-rw-r--r-- | tests/auto/mediaobject/dummy/mediaobject.h | 169 | ||||
-rw-r--r-- | tests/auto/mediaobject/dummy/videowidget.cpp | 205 | ||||
-rw-r--r-- | tests/auto/mediaobject/dummy/videowidget.h | 70 |
10 files changed, 1163 insertions, 0 deletions
diff --git a/tests/auto/mediaobject/dummy/README b/tests/auto/mediaobject/dummy/README new file mode 100644 index 0000000..43f69d9 --- /dev/null +++ b/tests/auto/mediaobject/dummy/README @@ -0,0 +1 @@ +This is a dummy backend for phonon, used for testing purposes. diff --git a/tests/auto/mediaobject/dummy/audiooutput.cpp b/tests/auto/mediaobject/dummy/audiooutput.cpp new file mode 100644 index 0000000..41b473d --- /dev/null +++ b/tests/auto/mediaobject/dummy/audiooutput.cpp @@ -0,0 +1,53 @@ +#include "audiooutput.h" +#include "backend.h" +#include <phonon/audiooutput.h> + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace Dummy +{ +AudioOutput::AudioOutput(Backend *backend, QObject *parent) + : QObject(parent) +{ + Q_UNUSED(backend) + + m_volumeLevel = 100; +} + +AudioOutput::~AudioOutput() +{ +} + +qreal AudioOutput::volume() const +{ + return m_volumeLevel; +} + +int AudioOutput::outputDevice() const +{ + return m_device; +} + +void AudioOutput::setVolume(qreal newVolume) +{ + m_volumeLevel = newVolume; + emit volumeChanged(newVolume); +} + +bool AudioOutput::setOutputDevice(int newDevice) +{ + return (newDevice == 0); +} + +bool AudioOutput::setOutputDevice(const AudioOutputDevice &newDevice) +{ + return setOutputDevice(newDevice.index()); +} + +} +} //namespace Phonon::Dummy + +QT_END_NAMESPACE +#include "moc_audiooutput.cpp" diff --git a/tests/auto/mediaobject/dummy/audiooutput.h b/tests/auto/mediaobject/dummy/audiooutput.h new file mode 100644 index 0000000..39efb55 --- /dev/null +++ b/tests/auto/mediaobject/dummy/audiooutput.h @@ -0,0 +1,41 @@ +#ifndef PHONON_DUMMY_AUDIOOUTPUT_H +#define PHONON_DUMMY_AUDIOOUTPUT_H + +#include "backend.h" +#include <phonon/audiooutputinterface.h> +#include <phonon/phononnamespace.h> + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace Dummy +{ +class AudioOutput : public QObject, public AudioOutputInterface +{ + Q_OBJECT + Q_INTERFACES(Phonon::AudioOutputInterface) +public: + AudioOutput(Backend *backend, QObject *parent); + ~AudioOutput(); + + qreal volume() const; + int outputDevice() const; + void setVolume(qreal newVolume); + bool setOutputDevice(int newDevice); + bool setOutputDevice(const AudioOutputDevice &newDevice); + +Q_SIGNALS: + void volumeChanged(qreal newVolume); + void audioDeviceFailed(); + +private: + qreal m_volumeLevel; + int m_device; +}; +} +} //namespace Phonon::Dummy + +QT_END_NAMESPACE + +#endif // PHONON_DUMMY_AUDIOOUTPUT_H diff --git a/tests/auto/mediaobject/dummy/backend.cpp b/tests/auto/mediaobject/dummy/backend.cpp new file mode 100644 index 0000000..53f3896 --- /dev/null +++ b/tests/auto/mediaobject/dummy/backend.cpp @@ -0,0 +1,149 @@ +#include "audiooutput.h" +#include "mediaobject.h" +#include "videowidget.h" + +#include "backend.h" + +#include <QtCore/QSet> +#include <QtCore/QVariant> +#include <QtCore/QtPlugin> + +QT_BEGIN_NAMESPACE + +Q_EXPORT_PLUGIN2(phonon_dummy, Phonon::Dummy::Backend) + +namespace Phonon +{ +namespace Dummy +{ + +Backend::Backend(QObject *parent, const QVariantList &) + : QObject(parent) +{ + qWarning()<<"Using TEST Phonon backend"; +} + +Backend::~Backend() +{ +} + +/*** + * !reimp + */ +QObject *Backend::createObject(BackendInterface::Class c, QObject *parent, const QList<QVariant> &args) +{ + Q_UNUSED(args) + + switch (c) { + case MediaObjectClass: + return new MediaObject(this, parent); + + case AudioOutputClass: { + AudioOutput *ao = new AudioOutput(this, parent); + m_audioOutputs.append(ao); + return ao; + } + case VideoWidgetClass: { + QWidget *widget = qobject_cast<QWidget*>(parent); + return new VideoWidget(this, widget); + } + default: + qWarning("createObject() : Backend object not available"); + } + return 0; +} + +/*** + * !reimp + */ +QStringList Backend::availableMimeTypes() const +{ + QStringList availableMimeTypes; + // audio *.wav and *.mp3 files + availableMimeTypes << QLatin1String("audio/x-mp3"); + availableMimeTypes << QLatin1String("audio/x-wav"); + + // video *.ogv, *.mp4, *.avi (some) + + availableMimeTypes << QLatin1String("video/mpeg"); + availableMimeTypes << QLatin1String("video/ogg"); + availableMimeTypes << QLatin1String("video/mp4"); + + return availableMimeTypes; +} + +/*** + * !reimp + */ +QList<int> Backend::objectDescriptionIndexes(ObjectDescriptionType type) const +{ + QList<int> list; + + if(type == Phonon::AudioOutputDeviceType) + list.append(0); + + return list; +} + +/*** + * !reimp + */ +QHash<QByteArray, QVariant> Backend::objectDescriptionProperties(ObjectDescriptionType type, int index) const +{ + Q_UNUSED(index); + QHash<QByteArray, QVariant> ret; + + if(type == Phonon::AudioOutputDeviceType) + ret["name"] = QLatin1String("default audio device"); + + return ret; +} + +/*** + * !reimp + */ +bool Backend::startConnectionChange(QSet<QObject *> objects) +{ + Q_UNUSED(objects) + + return true; +} + +/*** + * !reimp + */ +bool Backend::connectNodes(QObject *source, QObject *sink) +{ + Q_UNUSED(source) + Q_UNUSED(sink) + + return true; +} + +/*** + * !reimp + */ +bool Backend::disconnectNodes(QObject *source, QObject *sink) +{ + Q_UNUSED(source) + Q_UNUSED(sink) + + return true; +} + +/*** + * !reimp + */ +bool Backend::endConnectionChange(QSet<QObject *> objects) +{ + Q_UNUSED(objects) + + return true; +} + +} +} + +QT_END_NAMESPACE + +#include "moc_backend.cpp" diff --git a/tests/auto/mediaobject/dummy/backend.h b/tests/auto/mediaobject/dummy/backend.h new file mode 100644 index 0000000..20af216 --- /dev/null +++ b/tests/auto/mediaobject/dummy/backend.h @@ -0,0 +1,55 @@ +#ifndef PHONON_DUMMY_BACKEND_H +#define PHONON_DUMMY_BACKEND_H + +#include <phonon/objectdescription.h> +#include <phonon/backendinterface.h> + +#include <phonon/medianode.h> + +#include <QtCore/QList> +#include <QtCore/QPointer> +#include <QtCore/QStringList> +#include <QtCore/QTimer> + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace Dummy +{ +class AudioOutput; +class MediaObject; + +class Backend : public QObject, public BackendInterface +{ + Q_OBJECT + Q_INTERFACES(Phonon::BackendInterface) + +public: + Backend(QObject *parent = 0, const QVariantList & = QVariantList()); + virtual ~Backend(); + + QObject *createObject(BackendInterface::Class, QObject *parent, const QList<QVariant> &args); + + QStringList availableMimeTypes() const; + + QList<int> objectDescriptionIndexes(ObjectDescriptionType type) const; + QHash<QByteArray, QVariant> objectDescriptionProperties(ObjectDescriptionType type, int index) const; + + bool startConnectionChange(QSet<QObject *>); + bool connectNodes(QObject *, QObject *); + bool disconnectNodes(QObject *, QObject *); + bool endConnectionChange(QSet<QObject *>); + +Q_SIGNALS: + void objectDescriptionChanged(ObjectDescriptionType); + +private: + QList<QPointer<AudioOutput> > m_audioOutputs; +}; +} +} // namespace Phonon::Dummy + +QT_END_NAMESPACE + +#endif // PHONON_DUMMY_BACKEND_H diff --git a/tests/auto/mediaobject/dummy/dummy.pro b/tests/auto/mediaobject/dummy/dummy.pro new file mode 100644 index 0000000..b4f6109 --- /dev/null +++ b/tests/auto/mediaobject/dummy/dummy.pro @@ -0,0 +1,23 @@ +TEMPLATE = lib + +isEmpty(QT_MAJOR_VERSION) { + VERSION=4.5.2 +} else { + VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} +} +CONFIG += qt plugin + +TARGET = phonon_dummy +DESTDIR = $$QT_BUILD_TREE/plugins/phonon_backend +DEPENDPATH += . +INCLUDEPATH += . + +QT += phonon + + +# Input +HEADERS += backend.h audiooutput.h mediaobject.h videowidget.h +SOURCES += backend.cpp audiooutput.cpp mediaobject.cpp videowidget.cpp + +target.path = $$[QT_INSTALL_PLUGINS]/phonon_backend +INSTALLS += target diff --git a/tests/auto/mediaobject/dummy/mediaobject.cpp b/tests/auto/mediaobject/dummy/mediaobject.cpp new file mode 100644 index 0000000..521e3a6 --- /dev/null +++ b/tests/auto/mediaobject/dummy/mediaobject.cpp @@ -0,0 +1,397 @@ +#include "mediaobject.h" +#include "backend.h" + +#include <QtCore> +#include <QtCore/QTimer> +#include <QtCore/QVector> +#include <QtCore/QFile> +#include <QtCore/QByteRef> +#include <QtCore/QStringList> +#include <QtCore/QEvent> +#include <QApplication> + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace Dummy +{ + +static const char* riffId = "RIFF"; + +MediaObject::MediaObject(Backend *backend, QObject *parent) + : QObject(parent) + , m_resumeState(false) + , m_oldState(Phonon::LoadingState) + , m_oldPos(0) + , currentPos(0) +{ + Q_UNUSED(backend) + + m_error = Phonon::NoError; + m_tickInterval = 100; // 100ms + m_totalTime = 26000; // 26s + m_prefinishMark = 0; + m_transitionTime = 100; //100ms + m_hasVideo = false; + m_prefinishMarkReachedNotEmitted = true; + m_aboutToFinishEmitted = false; + m_pendingState = Phonon::LoadingState; + m_state = Phonon::LoadingState; + m_pendingState = Phonon::LoadingState; + m_tickTimer = new QTimer(this); + connect(m_tickTimer, SIGNAL(timeout()), SLOT(emitTick())); +} + +MediaObject::~MediaObject() +{ + delete m_tickTimer; +} + +QString stateString(const Phonon::State &state) +{ + switch (state) { + case Phonon::LoadingState: + return QString("LoadingState"); + case Phonon::StoppedState: + return QString("StoppedState"); + case Phonon::PlayingState: + return QString("PlayingState"); + case Phonon::BufferingState: + return QString("BufferingState"); + case Phonon::PausedState: + return QString("PausedState"); + case Phonon::ErrorState: + return QString("ErrorState"); + } + return QString(); +} + +void MediaObject::saveState() +{ + if (m_resumeState) + return; + + if (m_pendingState == Phonon::PlayingState || m_pendingState == Phonon::PausedState) { + m_resumeState = true; + m_oldState = m_pendingState; + m_oldPos = currentPos; + } +} + +void MediaObject::resumeState() +{ + if (m_resumeState) + QMetaObject::invokeMethod(this, "setState", Qt::QueuedConnection, Q_ARG(State, m_oldState)); +} + +/** + * !reimp + */ +State MediaObject::state() const +{ + return m_state; +} + +/** + * !reimp + */ +bool MediaObject::hasVideo() const +{ + return m_hasVideo; +} + +/** + * !reimp + */ +bool MediaObject::isSeekable() const +{ + return true; +} + +/** + * !reimp + */ +qint64 MediaObject::currentTime() const +{ + if (m_resumeState) + return m_oldPos; + + switch (state()) { + case Phonon::PausedState: + case Phonon::BufferingState: + case Phonon::PlayingState: + return currentPos; + case Phonon::StoppedState: + case Phonon::LoadingState: + return 0; + case Phonon::ErrorState: + break; + } + return -1; +} + +/** + * !reimp + */ +qint32 MediaObject::tickInterval() const +{ + return m_tickInterval; +} + +/** + * !reimp + */ +void MediaObject::setTickInterval(qint32 newTickInterval) +{ + m_tickInterval = newTickInterval; + if (m_tickInterval <= 0) { + m_tickTimer->setInterval(100); + } else + m_tickTimer->setInterval(newTickInterval); +} + +/** + * !reimp + */ +void MediaObject::play() +{ + if(m_state == Phonon::PlayingState) + return; + if(m_state == Phonon::ErrorState) + return; + + if(m_state != Phonon::PausedState) + m_tickTimer->stop(); + + m_prefinishMarkReachedNotEmitted = true; + m_aboutToFinishEmitted = false; + + setState(Phonon::PlayingState); + m_resumeState = false; + m_tickTimer->start(); +} + +/** + * !reimp + */ +QString MediaObject::errorString() const +{ + return m_errorString; +} + +/** + * !reimp + */ +Phonon::ErrorType MediaObject::errorType() const +{ + return m_error; +} + +void MediaObject::setState(State newstate) +{ + if (m_state == newstate) + return; + + switch (newstate) { + case Phonon::PausedState: + m_pendingState = Phonon::PausedState; + emit stateChanged(newstate, m_state); + m_state = newstate; + break; + case Phonon::StoppedState: + m_pendingState = Phonon::StoppedState; + emit stateChanged(newstate, m_state); + m_state = newstate; + break; + case Phonon::PlayingState: + m_pendingState = Phonon::PlayingState; + emit stateChanged(newstate, m_state); + m_state = newstate; + break; + case Phonon::ErrorState: + emit stateChanged(newstate, m_state); + m_state = newstate; + break; + case Phonon::BufferingState: + case Phonon::LoadingState: + emit stateChanged(newstate, m_state); + m_state = newstate; + break; + } +} + +qint64 MediaObject::totalTime() const +{ + return m_totalTime; +} + +qint32 MediaObject::prefinishMark() const +{ + return m_prefinishMark; +} + +qint32 MediaObject::transitionTime() const +{ + return m_transitionTime; +} + +void MediaObject::setTransitionTime(qint32 time) +{ + m_transitionTime = time; +} + +qint64 MediaObject::remainingTime() const +{ + if(currentTime() > totalTime()) + return 0; + + return totalTime() - currentTime(); +} + +MediaSource MediaObject::source() const +{ + return m_source; +} + +void MediaObject::setNextSource(const MediaSource &source) +{ + if (source.type() == MediaSource::Invalid && + source.type() == MediaSource::Empty) + return; + m_nextSource = source; +} + +/* + * !reimp + */ +void MediaObject::setSource(const MediaSource &source) +{ + QMultiMap<QString, QString> ret; + + ret.insert(QLatin1String("ARTIST"), "Nokia Dude"); + ret.insert(QLatin1String("ALBUM"), "Sound of silence"); + ret.insert(QLatin1String("DATE"), "2009"); + + m_error = Phonon::NoError; + setState(Phonon::LoadingState); + + m_source = source; + currentPos = 0; + + if((source.fileName().contains(".avi")) || + (source.fileName().contains(".mp4"))) { + m_hasVideo = true; + emit hasVideoChanged(m_hasVideo); + } + if(source.fileName().contains(".wav")) { + QFile file(source.fileName()); + if (file.open(QIODevice::ReadOnly)) { + int len = file.read((char*)&header, sizeof(CombinedHeader)); + if(len == sizeof(CombinedHeader)) { + if(memcmp(&header.riff.descriptor.id, riffId, 4) != 0) { + // Not a valid wav file, to satisfy unit test for mediaobject + m_error = Phonon::FatalError; + //m_state = Phonon::ErrorState; + m_errorString = "Invalid wav file"; + setState(Phonon::ErrorState); + file.close(); + return; + } + } + file.close(); + } + } + emit metaDataChanged(ret); + emit currentSourceChanged(source); + emit totalTimeChanged(m_totalTime); + + setState(Phonon::StoppedState); +} + +void MediaObject::setPrefinishMark(qint32 newPrefinishMark) +{ + m_prefinishMark = newPrefinishMark; + if (currentTime() < totalTime() - m_prefinishMark) // not about to finish + m_prefinishMarkReachedNotEmitted = true; +} + +void MediaObject::pause() +{ + if (state() != Phonon::PausedState) + setState(Phonon::PausedState); + m_resumeState = false; + m_tickTimer->stop(); +} + +void MediaObject::stop() +{ + if (state() != Phonon::StoppedState) { + if(m_state != Phonon::ErrorState) { + setState(Phonon::StoppedState); + } + m_prefinishMarkReachedNotEmitted = true; + } + m_resumeState = false; + m_tickTimer->stop(); +} + +void MediaObject::emitTick() +{ + if (m_resumeState) { + return; + } + if(m_tickInterval > 0) + currentPos += m_tickInterval; + else + currentPos += 100; + + qint64 currentTime = currentPos; + qint64 totalTime = m_totalTime; + + if (m_tickInterval > 0 && currentTime != m_previousTickTime) { + emit tick(currentTime); + m_previousTickTime = currentTime; + } + if (m_state == Phonon::PlayingState) { + if (currentTime >= totalTime - m_prefinishMark) { + if (m_prefinishMarkReachedNotEmitted) { + m_prefinishMarkReachedNotEmitted = false; + emit prefinishMarkReached(totalTime - currentTime); + } + } + // Prepare load of next source + if (currentTime >= totalTime - 500) { + if (!m_aboutToFinishEmitted) { + m_aboutToFinishEmitted = true; // track is about to finish + emit aboutToFinish(); + } + } + if(currentTime >= totalTime) { + m_tickTimer->stop(); + if(m_nextSource.type() != MediaSource::Invalid && + m_nextSource.type() != MediaSource::Empty) { + setSource(m_nextSource); + m_nextSource = MediaSource(); + m_pendingState = Phonon::PlayingState; + } else { + setState(Phonon::PausedState); + currentPos = 0; + emit finished(); + } + } + } +} + +void MediaObject::seek(qint64 time) +{ + // We will assume no buffering in the object so this is not needed. + currentPos = time; +} + +} // ns Dummy +} // ns Phonon + +QT_END_NAMESPACE + +#include "moc_mediaobject.cpp" diff --git a/tests/auto/mediaobject/dummy/mediaobject.h b/tests/auto/mediaobject/dummy/mediaobject.h new file mode 100644 index 0000000..a87b32f --- /dev/null +++ b/tests/auto/mediaobject/dummy/mediaobject.h @@ -0,0 +1,169 @@ +#ifndef PHONON_DUMMY_MEDIAOBJECT_H +#define PHONON_DUMMY_MEDIAOBJECT_H + +#include "backend.h" +#include <phonon/mediaobjectinterface.h> +#include <phonon/addoninterface.h> + +#include <QtCore/QHash> +#include <QtCore/QString> +#include <QtCore/QVariant> +#include <QtCore/QObject> +#include <QtCore/QDate> +#include <QtCore/QEvent> +#include <QtCore/QUrl> + +QT_BEGIN_NAMESPACE + +class QTimer; +typedef QMultiMap<QString, QString> TagMap; + +namespace Phonon +{ +namespace Dummy +{ + +class VideoWidget; +class AudioPath; +class VideoPath; +class AudioOutput; + +class MediaObject : public QObject, public MediaObjectInterface +{ + friend class Stream; + Q_OBJECT + Q_INTERFACES(Phonon::MediaObjectInterface + ) + +public: + + MediaObject(Backend *backend, QObject *parent); + ~MediaObject(); + Phonon::State state() const; + + bool hasVideo() const; + bool isSeekable() const; + + qint64 currentTime() const; + qint32 tickInterval() const; + + void setTickInterval(qint32 newTickInterval); + + void play(); + void pause(); + void stop(); + void seek(qint64 time); + + QString errorString() const; + Phonon::ErrorType errorType() const; + + QUrl url() const; + qint64 totalTime() const; + + qint32 prefinishMark() const; + void setPrefinishMark(qint32 newPrefinishMark); + + qint32 transitionTime() const; + void setTransitionTime(qint32); + qint64 remainingTime() const; + + void setSource(const MediaSource &source); + void setNextSource(const MediaSource &source); + MediaSource source() const; + + void saveState(); + void resumeState(); + +public Q_SLOTS: + void setState(State); + +Q_SIGNALS: + void currentSourceChanged(const MediaSource &newSource); + void stateChanged(Phonon::State newstate, Phonon::State oldstate); + void tick(qint64 time); + void metaDataChanged(QMultiMap<QString, QString>); + void seekableChanged(bool); + void hasVideoChanged(bool); + + void finished(); + void prefinishMarkReached(qint32); + void aboutToFinish(); + void totalTimeChanged(qint64 length); + void bufferStatus(int percentFilled); + + QMultiMap<QString, QString> metaData(); + void setMetaData(QMultiMap<QString, QString> newData); + +private Q_SLOTS: + void emitTick(); + +private: + bool m_resumeState; + State m_oldState; + quint64 m_oldPos; + quint64 currentPos; + bool m_hasVideo; + qint32 m_tickInterval; + QTimer *m_tickTimer; + Phonon::ErrorType m_error; + QString m_errorString; + qint64 m_totalTime; + qint32 m_prefinishMark; + qint32 m_transitionTime; + MediaSource m_source; + MediaSource m_nextSource; + bool m_prefinishMarkReachedNotEmitted; + bool m_aboutToFinishEmitted; + int m_previousTickTime; + + State m_state; + State m_pendingState; + + struct chunk + { + char id[4]; + quint32 size; + }; + + struct RIFFHeader + { + chunk descriptor; + char type[4]; + }; + + struct WAVEHeader + { + chunk descriptor; + quint16 audioFormat; // PCM = 1 + quint16 numChannels; + quint32 sampleRate; + quint32 byteRate; + quint16 blockAlign; + quint16 bitsPerSample; + quint32 xFreq1; + chunk fact; + quint32 xfact; + chunk data; + }; + + struct DATAHeader + { + chunk descriptor; + quint8 data[]; + }; + + struct CombinedHeader + { + RIFFHeader riff; + WAVEHeader wave; + DATAHeader data; + }; + + CombinedHeader header; +}; +} +} //namespace Phonon::Dummy + +QT_END_NAMESPACE + +#endif // PHONON_DUMMY_MEDIAOBJECT_H diff --git a/tests/auto/mediaobject/dummy/videowidget.cpp b/tests/auto/mediaobject/dummy/videowidget.cpp new file mode 100644 index 0000000..890363f --- /dev/null +++ b/tests/auto/mediaobject/dummy/videowidget.cpp @@ -0,0 +1,205 @@ +#include "videowidget.h" +#include <QtCore/QEvent> +#include <QtGui/QResizeEvent> +#include <QtGui/QPalette> +#include <QtGui/QImage> +#include <QtGui/QPainter> +#include <QtGui/QBoxLayout> +#include <QApplication> +#include "mediaobject.h" + +QT_BEGIN_NAMESPACE + +namespace Phonon +{ +namespace Dummy +{ + +VideoWidget::VideoWidget(Backend *backend, QWidget *parent) : + QWidget(parent), + m_aspectRatio(Phonon::VideoWidget::AspectRatioAuto), + m_brightness(0.0), + m_hue(0.0), + m_contrast(0.0), + m_saturation(0.0), + m_scaleMode(Phonon::VideoWidget::FitInView) +{ + Q_UNUSED(backend) + +} + +VideoWidget::~VideoWidget() +{ +} + +void VideoWidget::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) +} + +void VideoWidget::setVisible(bool val) +{ + Q_UNUSED(val) +} + +Phonon::VideoWidget::AspectRatio VideoWidget::aspectRatio() const +{ + return m_aspectRatio; +} + +QSize VideoWidget::sizeHint() const +{ + return QSize(640, 480); +} + +void VideoWidget::setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio) +{ + Q_UNUSED(aspectRatio) +} + +Phonon::VideoWidget::ScaleMode VideoWidget::scaleMode() const +{ + return m_scaleMode; +} + +QRect VideoWidget::scaleToAspect(QRect srcRect, int w, int h) const +{ + float width = srcRect.width(); + float height = srcRect.width() * (float(h) / float(w)); + if (height > srcRect.height()) { + height = srcRect.height(); + width = srcRect.height() * (float(w) / float(h)); + } + return QRect(0, 0, (int)width, (int)height); +} + +/*** + * Calculates the actual rectangle the movie will be presented with + **/ +QRect VideoWidget::calculateDrawFrameRect() const +{ + QRect widgetRect = rect(); + QRect drawFrameRect; + // Set m_drawFrameRect to be the size of the smallest possible + // rect conforming to the aspect and containing the whole frame: + switch (aspectRatio()) { + + case Phonon::VideoWidget::AspectRatioWidget: + drawFrameRect = widgetRect; + // No more calculations needed. + return drawFrameRect; + + case Phonon::VideoWidget::AspectRatio4_3: + drawFrameRect = scaleToAspect(widgetRect, 4, 3); + break; + + case Phonon::VideoWidget::AspectRatio16_9: + drawFrameRect = scaleToAspect(widgetRect, 16, 9); + break; + + case Phonon::VideoWidget::AspectRatioAuto: + default: + drawFrameRect = QRect(0, 0, movieSize().width(), movieSize().height()); + break; + } + + // Scale m_drawFrameRect to fill the widget + // without breaking aspect: + float widgetWidth = widgetRect.width(); + float widgetHeight = widgetRect.height(); + float frameWidth = widgetWidth; + float frameHeight = drawFrameRect.height() * float(widgetWidth) / float(drawFrameRect.width()); + + switch (scaleMode()) { + case Phonon::VideoWidget::ScaleAndCrop: + if (frameHeight < widgetHeight) { + frameWidth *= float(widgetHeight) / float(frameHeight); + frameHeight = widgetHeight; + } + break; + case Phonon::VideoWidget::FitInView: + default: + if (frameHeight > widgetHeight) { + frameWidth *= float(widgetHeight) / float(frameHeight); + frameHeight = widgetHeight; + } + break; + } + drawFrameRect.setSize(QSize(int(frameWidth), int(frameHeight))); + drawFrameRect.moveTo(int((widgetWidth - frameWidth) / 2.0f), + int((widgetHeight - frameHeight) / 2.0f)); + return drawFrameRect; +} + +void VideoWidget::setScaleMode(Phonon::VideoWidget::ScaleMode scaleMode) +{ + Q_UNUSED(scaleMode) +} + +qreal VideoWidget::brightness() const +{ + return m_brightness; +} + +qreal clampedValue(qreal val) +{ + if (val > 1.0 ) + return 1.0; + else if (val < -1.0) + return -1.0; + else return val; +} + +void VideoWidget::setBrightness(qreal newValue) +{ + Q_UNUSED(newValue) +} + +qreal VideoWidget::contrast() const +{ + return m_contrast; +} + +void VideoWidget::setContrast(qreal newValue) +{ + Q_UNUSED(newValue) +} + +qreal VideoWidget::hue() const +{ + return m_hue; +} + +void VideoWidget::setHue(qreal newValue) +{ + Q_UNUSED(newValue) +} + +qreal VideoWidget::saturation() const +{ + return m_saturation; +} + +void VideoWidget::setSaturation(qreal newValue) +{ + Q_UNUSED(newValue) +} + +bool VideoWidget::event(QEvent *event) +{ + return QWidget::event(event); +} + +void VideoWidget::setMovieSize(const QSize &size) +{ + m_movieSize = size; + widget()->updateGeometry(); + widget()->update(); +} + +} +} //namespace Phonon::Dummy + +QT_END_NAMESPACE + +#include "moc_videowidget.cpp" diff --git a/tests/auto/mediaobject/dummy/videowidget.h b/tests/auto/mediaobject/dummy/videowidget.h new file mode 100644 index 0000000..2e5a2b8 --- /dev/null +++ b/tests/auto/mediaobject/dummy/videowidget.h @@ -0,0 +1,70 @@ +#ifndef PHONON_DUMMY_VIDEOWIDGET_H +#define PHONON_DUMMY_VIDEOWIDGET_H + +#include <phonon/videowidget.h> +#include <phonon/videowidgetinterface.h> + +#include "backend.h" + +QT_BEGIN_NAMESPACE + +class QString; + +namespace Phonon +{ +namespace Dummy +{ + +class VideoWidget : public QWidget, public Phonon::VideoWidgetInterface +{ + Q_OBJECT + Q_INTERFACES(Phonon::VideoWidgetInterface) +public: + VideoWidget(Backend *backend, QWidget *parent = 0); + ~VideoWidget(); + + void paintEvent(QPaintEvent *event); + void setVisible(bool); + + Phonon::VideoWidget::AspectRatio aspectRatio() const; + void setAspectRatio(Phonon::VideoWidget::AspectRatio aspectRatio); + Phonon::VideoWidget::ScaleMode scaleMode() const; + void setScaleMode(Phonon::VideoWidget::ScaleMode); + qreal brightness() const; + void setBrightness(qreal); + qreal contrast() const; + void setContrast(qreal); + qreal hue() const; + void setHue(qreal); + qreal saturation() const; + void setSaturation(qreal); + void setMovieSize(const QSize &size); + QSize sizeHint() const; + QRect scaleToAspect(QRect srcRect, int w, int h) const; + QRect calculateDrawFrameRect() const; + + QSize movieSize() const { + return m_movieSize; + } + + bool event(QEvent *); + + QWidget *widget() { + return this; + } + +protected: + QSize m_movieSize; + +private: + Phonon::VideoWidget::AspectRatio m_aspectRatio; + qreal m_brightness, m_hue, m_contrast, m_saturation; + Phonon::VideoWidget::ScaleMode m_scaleMode; +}; + +} +} //namespace Phonon::Dummy + +QT_END_NAMESPACE + +#endif // PHONON_DUMMY_VIDEOWIDGET_H |