summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames McDonnell <jmcdonnell@blackberry.com>2017-09-19 12:39:48 -0400
committerJames McDonnell <jmcdonnell@blackberry.com>2018-01-16 22:11:16 +0000
commit950e9b472890478f0460a060ae08cc16a06ac659 (patch)
tree56b3e141d77a642d3165fc690ca60c09ae2800a6
parentec576ef2a004fc291eb6475c15907f82d425e88e (diff)
QNX 7.0.0 audio management support
[ChangeLog][QNX] Added support for QNX 7.0.0 audio management. Change-Id: Ia9f1740577527126bf666627647084382e4d7ce9 Reviewed-by: Christian Stromme <christian.stromme@qt.io>
-rw-r--r--examples/multimediawidgets/player/player.cpp50
-rw-r--r--examples/multimediawidgets/player/player.h3
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp53
-rw-r--r--src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h7
-rw-r--r--src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.cpp88
-rw-r--r--src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.h12
6 files changed, 182 insertions, 31 deletions
diff --git a/examples/multimediawidgets/player/player.cpp b/examples/multimediawidgets/player/player.cpp
index 4d3340855..89246e65c 100644
--- a/examples/multimediawidgets/player/player.cpp
+++ b/examples/multimediawidgets/player/player.cpp
@@ -174,6 +174,15 @@ Player::Player(QWidget *parent)
layout->addLayout(hLayout);
layout->addLayout(controlLayout);
layout->addLayout(histogramLayout);
+#if defined(Q_OS_QNX)
+ // On QNX, the main window doesn't have a title bar (or any other decorations).
+ // Create a status bar for the status information instead.
+ m_statusLabel = new QLabel;
+ m_statusBar = new QStatusBar;
+ m_statusBar->addPermanentWidget(m_statusLabel);
+ m_statusBar->setSizeGripEnabled(false); // Without mouse grabbing, it doesn't work very well.
+ layout->addWidget(m_statusBar);
+#endif
setLayout(layout);
@@ -308,15 +317,17 @@ void Player::statusChanged(QMediaPlayer::MediaStatus status)
case QMediaPlayer::UnknownMediaStatus:
case QMediaPlayer::NoMedia:
case QMediaPlayer::LoadedMedia:
- case QMediaPlayer::BufferingMedia:
- case QMediaPlayer::BufferedMedia:
setStatusInfo(QString());
break;
case QMediaPlayer::LoadingMedia:
setStatusInfo(tr("Loading..."));
break;
+ case QMediaPlayer::BufferingMedia:
+ case QMediaPlayer::BufferedMedia:
+ setStatusInfo(tr("Buffering %1%").arg(m_player->bufferStatus()));
+ break;
case QMediaPlayer::StalledMedia:
- setStatusInfo(tr("Media Stalled"));
+ setStatusInfo(tr("Stalled %1%").arg(m_player->bufferStatus()));
break;
case QMediaPlayer::EndOfMedia:
QApplication::alert(this);
@@ -347,7 +358,10 @@ void Player::handleCursor(QMediaPlayer::MediaStatus status)
void Player::bufferingProgress(int progress)
{
- setStatusInfo(tr("Buffering %4%").arg(progress));
+ if (m_player->mediaStatus() == QMediaPlayer::StalledMedia)
+ setStatusInfo(tr("Stalled %1%").arg(progress));
+ else
+ setStatusInfo(tr("Buffering %1%").arg(progress));
}
void Player::videoAvailableChanged(bool available)
@@ -369,19 +383,31 @@ void Player::videoAvailableChanged(bool available)
void Player::setTrackInfo(const QString &info)
{
m_trackInfo = info;
- if (!m_statusInfo.isEmpty())
- setWindowTitle(QString("%1 | %2").arg(m_trackInfo).arg(m_statusInfo));
- else
- setWindowTitle(m_trackInfo);
+
+ if (m_statusBar) {
+ m_statusBar->showMessage(m_trackInfo);
+ m_statusLabel->setText(m_statusInfo);
+ } else {
+ if (!m_statusInfo.isEmpty())
+ setWindowTitle(QString("%1 | %2").arg(m_trackInfo).arg(m_statusInfo));
+ else
+ setWindowTitle(m_trackInfo);
+ }
}
void Player::setStatusInfo(const QString &info)
{
m_statusInfo = info;
- if (!m_statusInfo.isEmpty())
- setWindowTitle(QString("%1 | %2").arg(m_trackInfo).arg(m_statusInfo));
- else
- setWindowTitle(m_trackInfo);
+
+ if (m_statusBar) {
+ m_statusBar->showMessage(m_trackInfo);
+ m_statusLabel->setText(m_statusInfo);
+ } else {
+ if (!m_statusInfo.isEmpty())
+ setWindowTitle(QString("%1 | %2").arg(m_trackInfo).arg(m_statusInfo));
+ else
+ setWindowTitle(m_trackInfo);
+ }
}
void Player::displayErrorMessage()
diff --git a/examples/multimediawidgets/player/player.h b/examples/multimediawidgets/player/player.h
index a15d27bd7..3002c9811 100644
--- a/examples/multimediawidgets/player/player.h
+++ b/examples/multimediawidgets/player/player.h
@@ -62,6 +62,7 @@ class QMediaPlayer;
class QModelIndex;
class QPushButton;
class QSlider;
+class QStatusBar;
class QVideoProbe;
class QVideoWidget;
class QAudioProbe;
@@ -123,6 +124,8 @@ private:
QPushButton *m_fullScreenButton = nullptr;
QPushButton *m_colorButton = nullptr;
QDialog *m_colorDialog = nullptr;
+ QLabel *m_statusLabel = nullptr;
+ QStatusBar *m_statusBar = nullptr;
QLabel *m_labelHistogram = nullptr;
HistogramWidget *m_videoHistogram = nullptr;
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
index be2739941..c66ac937d 100644
--- a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
+++ b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
@@ -121,6 +121,40 @@ void MmRendererMediaPlayerControl::handleMmStopped()
}
}
+void MmRendererMediaPlayerControl::handleMmSuspend(const QString &reason)
+{
+ if (m_state == QMediaPlayer::StoppedState)
+ return;
+
+ Q_UNUSED(reason);
+ setMediaStatus(QMediaPlayer::StalledMedia);
+}
+
+void MmRendererMediaPlayerControl::handleMmSuspendRemoval(const QString &bufferStatus)
+{
+ if (m_state == QMediaPlayer::StoppedState)
+ return;
+
+ if (bufferStatus == QLatin1String("buffering"))
+ setMediaStatus(QMediaPlayer::BufferingMedia);
+ else
+ setMediaStatus(QMediaPlayer::BufferedMedia);
+}
+
+void MmRendererMediaPlayerControl::handleMmPause()
+{
+ if (m_state == QMediaPlayer::PlayingState) {
+ setState(QMediaPlayer::PausedState);
+ }
+}
+
+void MmRendererMediaPlayerControl::handleMmPlay()
+{
+ if (m_state == QMediaPlayer::PausedState) {
+ setState(QMediaPlayer::PlayingState);
+ }
+}
+
void MmRendererMediaPlayerControl::closeConnection()
{
stopMonitoring();
@@ -167,6 +201,8 @@ void MmRendererMediaPlayerControl::attach()
return;
}
+ resetMonitoring();
+
if (m_videoRendererControl)
m_videoRendererControl->attachDisplay(m_context);
@@ -338,6 +374,7 @@ void MmRendererMediaPlayerControl::setState(QMediaPlayer::State state)
void MmRendererMediaPlayerControl::stopInternal(StopCommand stopCommand)
{
+ resetMonitoring();
setPosition(0);
if (m_state != QMediaPlayer::StoppedState) {
@@ -500,6 +537,7 @@ void MmRendererMediaPlayerControl::play()
if (m_mediaStatus == QMediaPlayer::EndOfMedia)
m_position = 0;
+ resetMonitoring();
setPositionInternal(m_position);
setVolumeInternal(m_muted ? 0 : m_volume);
setPlaybackRateInternal(m_rate);
@@ -573,18 +611,11 @@ void MmRendererMediaPlayerControl::setMmBufferStatus(const QString &bufferStatus
// ignore "idle" buffer status
}
-void MmRendererMediaPlayerControl::setMmBufferLevel(const QString &bufferLevel)
+void MmRendererMediaPlayerControl::setMmBufferLevel(int level, int capacity)
{
- // buffer level has format level/capacity, e.g. "91319/124402"
- const int slashPos = bufferLevel.indexOf('/');
- if (slashPos != -1) {
- const int fill = bufferLevel.leftRef(slashPos).toInt();
- const int capacity = bufferLevel.midRef(slashPos + 1).toInt();
- if (capacity != 0) {
- m_bufferLevel = fill / static_cast<float>(capacity) * 100.0f;
- emit bufferStatusChanged(m_bufferLevel);
- }
- }
+ m_bufferLevel = capacity == 0 ? 0 : level / static_cast<float>(capacity) * 100.0f;
+ m_bufferLevel = qBound(0, m_bufferLevel, 100);
+ emit bufferStatusChanged(m_bufferLevel);
}
void MmRendererMediaPlayerControl::updateMetaData(const strm_dict *dict)
diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h
index e1530689e..3426ef2f2 100644
--- a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h
+++ b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h
@@ -111,14 +111,19 @@ public:
protected:
virtual void startMonitoring() = 0;
virtual void stopMonitoring() = 0;
+ virtual void resetMonitoring() = 0;
void openConnection();
void emitMmError(const QString &msg);
void emitPError(const QString &msg);
void setMmPosition(qint64 newPosition);
void setMmBufferStatus(const QString &bufferStatus);
- void setMmBufferLevel(const QString &bufferLevel);
+ void setMmBufferLevel(int level, int capacity);
void handleMmStopped();
+ void handleMmSuspend(const QString &reason);
+ void handleMmSuspendRemoval(const QString &bufferStatus);
+ void handleMmPause();
+ void handleMmPlay();
void updateMetaData(const strm_dict_t *dict);
// must be called from subclass dtors (calls virtual function stopMonitoring())
diff --git a/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.cpp
index a0bac1261..c050c03c5 100644
--- a/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.cpp
+++ b/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.cpp
@@ -42,13 +42,39 @@
#include "mmrenderervideowindowcontrol.h"
#include <mm/renderer.h>
+#include <tuple>
QT_BEGIN_NAMESPACE
+static std::tuple<int, int, bool> parseBufferLevel(const QByteArray &value)
+{
+ const int slashPos = value.indexOf('/');
+ if (slashPos <= 0)
+ return std::make_tuple(0, 0, false);
+
+ bool ok = false;
+ const int level = value.left(slashPos).toInt(&ok);
+ if (!ok || level < 0)
+ return std::make_tuple(0, 0, false);
+
+ const int capacity = value.mid(slashPos + 1).toInt(&ok);
+ if (!ok || capacity < 0)
+ return std::make_tuple(0, 0, false);
+
+ return std::make_tuple(level, capacity, true);
+}
+
MmrEventMediaPlayerControl::MmrEventMediaPlayerControl(QObject *parent)
: MmRendererMediaPlayerControl(parent)
, m_eventThread(nullptr)
+ , m_bufferStatus("")
+ , m_bufferLevel(0)
+ , m_bufferCapacity(0)
+ , m_position(0)
+ , m_suspended(false)
+ , m_suspendedReason("unknown")
, m_state(MMR_STATE_IDLE)
+ , m_speed(0)
{
openConnection();
}
@@ -75,6 +101,18 @@ void MmrEventMediaPlayerControl::stopMonitoring()
m_eventThread = nullptr;
}
+void MmrEventMediaPlayerControl::resetMonitoring()
+{
+ m_bufferStatus = "";
+ m_bufferLevel = 0;
+ m_bufferCapacity = 0;
+ m_position = 0;
+ m_suspended = false;
+ m_suspendedReason = "unknown";
+ m_state = MMR_STATE_IDLE;
+ m_speed = 0;
+}
+
bool MmrEventMediaPlayerControl::nativeEventFilter(const QByteArray &eventType,
void *message,
long *result)
@@ -102,32 +140,68 @@ void MmrEventMediaPlayerControl::readEvents()
if (event->data) {
const strm_string_t *value;
value = strm_dict_find_rstr(event->data, "bufferstatus");
- if (value)
- setMmBufferStatus(QString::fromLatin1(strm_string_get(value)));
+ if (value) {
+ m_bufferStatus = QByteArray(strm_string_get(value));
+ if (!m_suspended)
+ setMmBufferStatus(m_bufferStatus);
+ }
value = strm_dict_find_rstr(event->data, "bufferlevel");
- if (value)
- setMmBufferLevel(QString::fromLatin1(strm_string_get(value)));
+ if (value) {
+ const char *cstrValue = strm_string_get(value);
+ int level;
+ int capacity;
+ bool ok;
+ std::tie(level, capacity, ok) = parseBufferLevel(QByteArray(cstrValue));
+ if (!ok) {
+ qCritical("Could not parse buffer capacity from '%s'", cstrValue);
+ } else {
+ m_bufferLevel = level;
+ m_bufferCapacity = capacity;
+ setMmBufferLevel(level, capacity);
+ }
+ }
+
+ value = strm_dict_find_rstr(event->data, "suspended");
+ if (value) {
+ if (!m_suspended) {
+ m_suspended = true;
+ m_suspendedReason = strm_string_get(value);
+ handleMmSuspend(m_suspendedReason);
+ }
+ } else if (m_suspended) {
+ m_suspended = false;
+ handleMmSuspendRemoval(m_bufferStatus);
+ }
}
if (event->pos_str) {
const QByteArray valueBa = QByteArray(event->pos_str);
bool ok;
- const qint64 position = valueBa.toLongLong(&ok);
+ m_position = valueBa.toLongLong(&ok);
if (!ok) {
qCritical("Could not parse position from '%s'", valueBa.constData());
} else {
- setMmPosition(position);
+ setMmPosition(m_position);
}
}
break;
}
+ case MMR_EVENT_STATE: {
+ if (event->state == MMR_STATE_PLAYING && m_speed != event->speed) {
+ m_speed = event->speed;
+ if (m_speed == 0)
+ handleMmPause();
+ else
+ handleMmPlay();
+ }
+ break;
+ }
case MMR_EVENT_METADATA: {
updateMetaData(event->data);
break;
}
case MMR_EVENT_ERROR:
- case MMR_EVENT_STATE:
case MMR_EVENT_NONE:
case MMR_EVENT_OVERFLOW:
case MMR_EVENT_WARNING:
diff --git a/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.h b/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.h
index cc1ded3b1..0e4defc5c 100644
--- a/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.h
+++ b/src/plugins/qnx/mediaplayer/mmreventmediaplayercontrol.h
@@ -56,6 +56,7 @@ public:
void startMonitoring() override;
void stopMonitoring() override;
+ void resetMonitoring() override;
bool nativeEventFilter(const QByteArray &eventType,
void *message,
@@ -66,7 +67,18 @@ private Q_SLOTS:
private:
MmrEventThread *m_eventThread;
+
+ // status properties.
+ QByteArray m_bufferStatus;
+ int m_bufferLevel;
+ int m_bufferCapacity;
+ qint64 m_position;
+ bool m_suspended;
+ QByteArray m_suspendedReason;
+
+ // state properties.
mmr_state_t m_state;
+ int m_speed;
};
QT_END_NAMESPACE