Support plain QNX in mm-renderer mediaplayer impl

On plain QNX, the native events are plain screen_event_t's,
instead of being wrapped in bps_event_t.

The bps/mm-renderer interface isn't available on QNX, thus
those parts are replaced by reading directly from mm-renderer's
PPS objects.

Change-Id: I38772ddad04432ff099455a730ce0034f07db70d
Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
This commit is contained in:
Frank Osterfeld
2013-11-04 15:52:43 +01:00
committed by The Qt Project
parent 3571a891d5
commit 66219c9a28
18 changed files with 785 additions and 159 deletions

View File

@@ -7,13 +7,16 @@ load(qt_plugin)
LIBS += -lscreen LIBS += -lscreen
HEADERS += bbserviceplugin.h
SOURCES += bbserviceplugin.cpp
include(common/common.pri) include(common/common.pri)
include(camera/camera.pri)
include(mediaplayer/mediaplayer.pri) include(mediaplayer/mediaplayer.pri)
OTHER_FILES += blackberry_mediaservice.json blackberry {
include(camera/camera.pri)
HEADERS += bbserviceplugin.h
SOURCES += bbserviceplugin.cpp
OTHER_FILES += blackberry_mediaservice.json
} else {
HEADERS += neutrinoserviceplugin.h
SOURCES += neutrinoserviceplugin.cpp
OTHER_FILES += neutrino_mediaservice.json
}

View File

@@ -47,7 +47,10 @@
#include <QImage> #include <QImage>
#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformnativeinterface.h>
#ifdef Q_OS_BLACKBERRY
#include <bps/event.h>
#include <bps/screen.h> #include <bps/screen.h>
#endif
#include <errno.h> #include <errno.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -232,40 +235,55 @@ void WindowGrabber::resume()
m_timer.start(); m_timer.start();
} }
bool WindowGrabber::nativeEventFilter(const QByteArray&, void *message, long*) bool WindowGrabber::handleScreenEvent(screen_event_t screen_event)
{ {
int eventType;
if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
qWarning() << "WindowGrabber: Failed to query screen event type";
return false;
}
if (eventType != SCREEN_EVENT_CREATE)
return false;
screen_window_t window = 0;
if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) {
qWarning() << "WindowGrabber: Failed to query window property";
return false;
}
const int maxIdStrLength = 128;
char idString[maxIdStrLength];
if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) {
qWarning() << "WindowGrabber: Failed to query window ID string";
return false;
}
if (m_windowId == idString) {
m_window = window;
start();
}
return false;
}
bool WindowGrabber::nativeEventFilter(const QByteArray &eventType, void *message, long*)
{
#ifdef Q_OS_BLACKBERRY
Q_UNUSED(eventType)
bps_event_t * const event = static_cast<bps_event_t *>(message); bps_event_t * const event = static_cast<bps_event_t *>(message);
if (event && bps_event_get_domain(event) == screen_get_domain()) { if (event && bps_event_get_domain(event) == screen_get_domain()) {
const screen_event_t screen_event = screen_event_get_event(event); const screen_event_t screen_event = screen_event_get_event(event);
return handleScreenEvent(screen_event);
int eventType;
if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
qWarning() << "WindowGrabber: Failed to query screen event type";
return false;
}
if (eventType != SCREEN_EVENT_CREATE)
return false;
screen_window_t window = 0;
if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) {
qWarning() << "WindowGrabber: Failed to query window property";
return false;
}
const int maxIdStrLength = 128;
char idString[maxIdStrLength];
if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) {
qWarning() << "WindowGrabber: Failed to query window ID string";
return false;
}
if (m_windowId == idString) {
m_window = window;
start();
}
} }
#else
if (eventType == "screen_event_t") {
const screen_event_t event = static_cast<screen_event_t>(message);
return handleScreenEvent(event);
}
#endif
return false; return false;
} }

View File

@@ -69,6 +69,8 @@ public:
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
bool handleScreenEvent(screen_event_t event);
QByteArray windowGroupId() const; QByteArray windowGroupId() const;
signals: signals:

View File

@@ -49,8 +49,7 @@
#include <QtCore/qfileinfo.h> #include <QtCore/qfileinfo.h>
#include <QtCore/quuid.h> #include <QtCore/quuid.h>
#include <mm/renderer.h> #include <mm/renderer.h>
#include <bps/mmrenderer.h>
#include <bps/screen.h>
#include <errno.h> #include <errno.h>
#include <sys/strm.h> #include <sys/strm.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -69,7 +68,6 @@ BbMediaPlayerControl::BbMediaPlayerControl(QObject *parent)
m_muted(false), m_muted(false),
m_rate(1), m_rate(1),
m_id(-1), m_id(-1),
m_eventMonitor(0),
m_position(0), m_position(0),
m_mediaStatus(QMediaPlayer::NoMedia), m_mediaStatus(QMediaPlayer::NoMedia),
m_playAfterMediaLoaded(false), m_playAfterMediaLoaded(false),
@@ -81,10 +79,9 @@ BbMediaPlayerControl::BbMediaPlayerControl(QObject *parent)
m_loadingTimer.setInterval(0); m_loadingTimer.setInterval(0);
connect(&m_loadingTimer, SIGNAL(timeout()), this, SLOT(continueLoadMedia())); connect(&m_loadingTimer, SIGNAL(timeout()), this, SLOT(continueLoadMedia()));
QCoreApplication::eventDispatcher()->installNativeEventFilter(this); QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
openConnection();
} }
BbMediaPlayerControl::~BbMediaPlayerControl() void BbMediaPlayerControl::destroy()
{ {
stop(); stop();
detach(); detach();
@@ -111,19 +108,41 @@ void BbMediaPlayerControl::openConnection()
return; return;
} }
m_eventMonitor = mmrenderer_request_events(m_contextName.toLatin1(), 0, m_id); startMonitoring(m_id, m_contextName);
if (!m_eventMonitor) { }
qDebug() << "Unable to request multimedia events";
emit error(0, "Unable to request multimedia events"); void BbMediaPlayerControl::handleMmStatusUpdate(qint64 newPosition)
{
// Prevent spurious position change events from overriding our own position, for example
// when setting the position to 0 in stop().
// Also, don't change the position while we're loading the media, as then play() would
// set a wrong initial position.
if (m_state != QMediaPlayer::PlayingState ||
m_mediaStatus == QMediaPlayer::LoadingMedia ||
m_mediaStatus == QMediaPlayer::NoMedia ||
m_mediaStatus == QMediaPlayer::InvalidMedia)
return;
setMmPosition(newPosition);
}
void BbMediaPlayerControl::handleMmStopped()
{
// Only react to stop events that happen when the end of the stream is reached and
// playback is stopped because of this.
// Ignore other stop event sources, souch as calling mmr_stop() ourselves and
// mmr_input_attach().
if (m_stopEventsToIgnore > 0) {
--m_stopEventsToIgnore;
} else {
setMediaStatus(QMediaPlayer::EndOfMedia);
stopInternal(IgnoreMmRenderer);
} }
} }
void BbMediaPlayerControl::closeConnection() void BbMediaPlayerControl::closeConnection()
{ {
if (m_eventMonitor) { stopMonitoring();
mmrenderer_stop_events(m_eventMonitor);
m_eventMonitor = 0;
}
if (m_context) { if (m_context) {
mmr_context_destroy(m_context); mmr_context_destroy(m_context);
@@ -468,6 +487,16 @@ void BbMediaPlayerControl::continueLoadMedia()
play(); play();
} }
QString BbMediaPlayerControl::contextName() const
{
return m_contextName;
}
BbVideoWindowControl *BbMediaPlayerControl::videoWindowControl() const
{
return m_videoWindowControl;
}
void BbMediaPlayerControl::play() void BbMediaPlayerControl::play()
{ {
if (m_playAfterMediaLoaded) if (m_playAfterMediaLoaded)
@@ -526,6 +555,11 @@ void BbMediaPlayerControl::stop()
stopInternal(StopMmRenderer); stopInternal(StopMmRenderer);
} }
BbPlayerVideoRendererControl *BbMediaPlayerControl::videoRendererControl() const
{
return m_videoRendererControl;
}
void BbMediaPlayerControl::setVideoRendererControl(BbPlayerVideoRendererControl *videoControl) void BbMediaPlayerControl::setVideoRendererControl(BbPlayerVideoRendererControl *videoControl)
{ {
m_videoRendererControl = videoControl; m_videoRendererControl = videoControl;
@@ -541,71 +575,25 @@ void BbMediaPlayerControl::setMetaDataReaderControl(BbMetaDataReaderControl *met
m_metaDataReaderControl = metaDataReaderControl; m_metaDataReaderControl = metaDataReaderControl;
} }
bool BbMediaPlayerControl::nativeEventFilter(const QByteArray &eventType, void *message, long *result) void BbMediaPlayerControl::setMmPosition(qint64 newPosition)
{ {
Q_UNUSED(eventType); if (newPosition != 0 && newPosition != m_position) {
Q_UNUSED(result); m_position = newPosition;
emit positionChanged(m_position);
}
}
bps_event_t * const event = static_cast<bps_event_t *>(message); void BbMediaPlayerControl::setMmBufferStatus(const QString &bufferStatus)
if (!event || {
(bps_event_get_domain(event) != mmrenderer_get_domain() && const int slashPos = bufferStatus.indexOf('/');
bps_event_get_domain(event) != screen_get_domain())) if (slashPos != -1) {
return false; const int fill = bufferStatus.left(slashPos).toInt();
const int capacity = bufferStatus.mid(slashPos + 1).toInt();
if (m_videoWindowControl) if (capacity != 0) {
m_videoWindowControl->bpsEventHandler(event); m_bufferStatus = fill / static_cast<float>(capacity) * 100.0f;
emit bufferStatusChanged(m_bufferStatus);
if (bps_event_get_domain(event) == mmrenderer_get_domain()) {
if (bps_event_get_code(event) == MMRENDERER_STATE_CHANGE) {
const mmrenderer_state_t newState = mmrenderer_event_get_state(event);
if (newState == MMR_STOPPED) {
// Only react to stop events that happen when the end of the stream is reached and
// playback is stopped because of this.
// Ignore other stop event sources, souch as calling mmr_stop() ourselves and
// mmr_input_attach().
if (m_stopEventsToIgnore > 0) {
--m_stopEventsToIgnore;
} else {
setMediaStatus(QMediaPlayer::EndOfMedia);
stopInternal(IgnoreMmRenderer);
}
return false;
}
}
if (bps_event_get_code(event) == MMRENDERER_STATUS_UPDATE) {
// Prevent spurious position change events from overriding our own position, for example
// when setting the position to 0 in stop().
// Also, don't change the position while we're loading the media, as then play() would
// set a wrong initial position.
if (m_state != QMediaPlayer::PlayingState ||
m_mediaStatus == QMediaPlayer::LoadingMedia ||
m_mediaStatus == QMediaPlayer::NoMedia ||
m_mediaStatus == QMediaPlayer::InvalidMedia)
return false;
const qint64 newPosition = QString::fromLatin1(mmrenderer_event_get_position(event)).toLongLong();
if (newPosition != 0 && newPosition != m_position) {
m_position = newPosition;
emit positionChanged(m_position);
}
const QString bufferStatus = QString::fromLatin1(mmrenderer_event_get_bufferlevel(event));
const int slashPos = bufferStatus.indexOf('/');
if (slashPos != -1) {
const int fill = bufferStatus.left(slashPos).toInt();
const int capacity = bufferStatus.mid(slashPos + 1).toInt();
if (capacity != 0) {
m_bufferStatus = fill / static_cast<float>(capacity) * 100.0f;
emit bufferStatusChanged(m_bufferStatus);
}
}
} }
} }
return false;
} }
void BbMediaPlayerControl::updateMetaData() void BbMediaPlayerControl::updateMetaData()

View File

@@ -47,7 +47,6 @@
#include <QtCore/qpointer.h> #include <QtCore/qpointer.h>
#include <QtCore/qtimer.h> #include <QtCore/qtimer.h>
struct bps_event_t;
typedef struct mmr_connection mmr_connection_t; typedef struct mmr_connection mmr_connection_t;
typedef struct mmr_context mmr_context_t; typedef struct mmr_context mmr_context_t;
typedef struct mmrenderer_monitor mmrenderer_monitor_t; typedef struct mmrenderer_monitor mmrenderer_monitor_t;
@@ -63,7 +62,6 @@ class BbMediaPlayerControl : public QMediaPlayerControl, public QAbstractNativeE
Q_OBJECT Q_OBJECT
public: public:
explicit BbMediaPlayerControl(QObject *parent = 0); explicit BbMediaPlayerControl(QObject *parent = 0);
~BbMediaPlayerControl();
QMediaPlayer::State state() const Q_DECL_OVERRIDE; QMediaPlayer::State state() const Q_DECL_OVERRIDE;
@@ -100,25 +98,39 @@ public:
void pause() Q_DECL_OVERRIDE; void pause() Q_DECL_OVERRIDE;
void stop() Q_DECL_OVERRIDE; void stop() Q_DECL_OVERRIDE;
BbPlayerVideoRendererControl *videoRendererControl() const;
void setVideoRendererControl(BbPlayerVideoRendererControl *videoControl); void setVideoRendererControl(BbPlayerVideoRendererControl *videoControl);
BbVideoWindowControl *videoWindowControl() const;
void setVideoWindowControl(BbVideoWindowControl *videoControl); void setVideoWindowControl(BbVideoWindowControl *videoControl);
void setMetaDataReaderControl(BbMetaDataReaderControl *metaDataReaderControl); void setMetaDataReaderControl(BbMetaDataReaderControl *metaDataReaderControl);
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
protected:
virtual void startMonitoring(int contextId, const QString &contextName) = 0;
virtual void stopMonitoring() = 0;
QString contextName() const;
void openConnection();
void emitMmError(const QString &msg);
void emitPError(const QString &msg);
void setMmPosition(qint64 newPosition);
void setMmBufferStatus(const QString &bufferStatus);
void handleMmStopped();
void handleMmStatusUpdate(qint64 position);
// must be called from subclass dtors (calls virtual function stopMonitoring())
void destroy();
private Q_SLOTS: private Q_SLOTS:
void continueLoadMedia(); void continueLoadMedia();
private: private:
QByteArray resourcePathForUrl(const QUrl &url); QByteArray resourcePathForUrl(const QUrl &url);
void openConnection();
void closeConnection(); void closeConnection();
void attach(); void attach();
void detach(); void detach();
void updateMetaData(); void updateMetaData();
void emitMmError(const QString &msg);
void emitPError(const QString &msg);
// All these set the specified value to the backend, but neither emit changed signals // All these set the specified value to the backend, but neither emit changed signals
// nor change the member value. // nor change the member value.
void setVolumeInternal(int newVolume); void setVolumeInternal(int newVolume);
@@ -145,7 +157,6 @@ private:
QPointer<BbMetaDataReaderControl> m_metaDataReaderControl; QPointer<BbMetaDataReaderControl> m_metaDataReaderControl;
BbMetaData m_metaData; BbMetaData m_metaData;
int m_id; int m_id;
mmrenderer_monitor_t *m_eventMonitor;
qint64 m_position; qint64 m_position;
QMediaPlayer::MediaStatus m_mediaStatus; QMediaPlayer::MediaStatus m_mediaStatus;
bool m_playAfterMediaLoaded; bool m_playAfterMediaLoaded;

View File

@@ -46,6 +46,14 @@
#include "bbutil.h" #include "bbutil.h"
#include "bbvideowindowcontrol.h" #include "bbvideowindowcontrol.h"
#ifdef Q_OS_BLACKBERRY
#include "bpsmediaplayercontrol.h"
typedef BpsMediaPlayerControl PlatformSpecificMediaPlayerControl;
#else
#include "ppsmediaplayercontrol.h"
typedef PpsMediaPlayerControl PlatformSpecificMediaPlayerControl;
#endif
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
BbMediaPlayerService::BbMediaPlayerService(QObject *parent) BbMediaPlayerService::BbMediaPlayerService(QObject *parent)
@@ -72,7 +80,7 @@ QMediaControl *BbMediaPlayerService::requestControl(const char *name)
{ {
if (qstrcmp(name, QMediaPlayerControl_iid) == 0) { if (qstrcmp(name, QMediaPlayerControl_iid) == 0) {
if (!m_mediaPlayerControl) { if (!m_mediaPlayerControl) {
m_mediaPlayerControl = new BbMediaPlayerControl(); m_mediaPlayerControl = new PlatformSpecificMediaPlayerControl;
updateControls(); updateControls();
} }
return m_mediaPlayerControl; return m_mediaPlayerControl;

View File

@@ -46,7 +46,6 @@
#include <qvideorenderercontrol.h> #include <qvideorenderercontrol.h>
typedef struct mmr_context mmr_context_t; typedef struct mmr_context mmr_context_t;
struct bps_event_t;
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@@ -46,7 +46,6 @@
#include <QtGui/qscreen.h> #include <QtGui/qscreen.h>
#include <QtGui/qwindow.h> #include <QtGui/qwindow.h>
#include <mm/renderer.h> #include <mm/renderer.h>
#include <bps/screen.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -368,43 +367,39 @@ void BbVideoWindowControl::setMetaData(const BbMetaData &metaData)
updateVideoPosition(); updateVideoPosition();
} }
void BbVideoWindowControl::bpsEventHandler(bps_event_t *event) void BbVideoWindowControl::screenEventHandler(const screen_event_t &screen_event)
{ {
if (event && bps_event_get_domain(event) == screen_get_domain()) { int eventType;
const screen_event_t screen_event = screen_event_get_event(event); if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
perror("BbVideoWindowControl: Failed to query screen event type");
return;
}
int eventType; if (eventType != SCREEN_EVENT_CREATE)
if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) { return;
perror("BbVideoWindowControl: Failed to query screen event type");
screen_window_t window = 0;
if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) {
perror("BbVideoWindowControl: Failed to query window property");
return;
}
const int maxIdStrLength = 128;
char idString[maxIdStrLength];
if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) {
perror("BbVideoWindowControl: Failed to query window ID string");
return;
}
if (m_windowName == idString) {
m_window = window;
updateVideoPosition();
const int visibleFlag = 1;
if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &visibleFlag) != 0) {
perror("BbVideoWindowControl: Failed to make window visible");
return; return;
} }
if (eventType != SCREEN_EVENT_CREATE)
return;
screen_window_t window = 0;
if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) {
perror("BbVideoWindowControl: Failed to query window property");
return;
}
const int maxIdStrLength = 128;
char idString[maxIdStrLength];
if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) {
perror("BbVideoWindowControl: Failed to query window ID string");
return;
}
if (m_windowName == idString) {
m_window = window;
updateVideoPosition();
const int visibleFlag = 1;
if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &visibleFlag) != 0) {
perror("BbVideoWindowControl: Failed to make window visible");
return;
}
}
} }
} }

View File

@@ -46,7 +46,6 @@
#include <screen/screen.h> #include <screen/screen.h>
typedef struct mmr_context mmr_context_t; typedef struct mmr_context mmr_context_t;
struct bps_event_t;
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -91,7 +90,7 @@ public:
void detachDisplay(); void detachDisplay();
void attachDisplay(mmr_context_t *context); void attachDisplay(mmr_context_t *context);
void setMetaData(const BbMetaData &metaData); void setMetaData(const BbMetaData &metaData);
void bpsEventHandler(bps_event_t *event); void screenEventHandler(const screen_event_t &event);
private: private:
QWindow *findWindow(WId id) const; QWindow *findWindow(WId id) const;

View File

@@ -0,0 +1,117 @@
/****************************************************************************
**
** Copyright (C) 2013 Research In Motion
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia 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.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "bpsmediaplayercontrol.h"
#include "bbvideowindowcontrol.h"
#include <bps/mmrenderer.h>
#include <bps/screen.h>
QT_BEGIN_NAMESPACE
BpsMediaPlayerControl::BpsMediaPlayerControl(QObject *parent)
: BbMediaPlayerControl(parent),
m_eventMonitor(0)
{
openConnection();
}
BpsMediaPlayerControl::~BpsMediaPlayerControl()
{
destroy();
}
void BpsMediaPlayerControl::startMonitoring(int contextId, const QString &contextName)
{
m_eventMonitor = mmrenderer_request_events(contextName.toLatin1().constData(), 0, contextId);
if (!m_eventMonitor) {
qDebug() << "Unable to request multimedia events";
emit error(0, "Unable to request multimedia events");
}
}
void BpsMediaPlayerControl::stopMonitoring()
{
if (m_eventMonitor) {
mmrenderer_stop_events(m_eventMonitor);
m_eventMonitor = 0;
}
}
bool BpsMediaPlayerControl::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
Q_UNUSED(result)
Q_UNUSED(eventType)
bps_event_t * const event = static_cast<bps_event_t *>(message);
if (!event ||
(bps_event_get_domain(event) != mmrenderer_get_domain() &&
bps_event_get_domain(event) != screen_get_domain()))
return false;
if (event && bps_event_get_domain(event) == screen_get_domain()) {
const screen_event_t screen_event = screen_event_get_event(event);
if (BbVideoWindowControl *control = videoWindowControl())
control->screenEventHandler(screen_event);
}
if (bps_event_get_domain(event) == mmrenderer_get_domain()) {
if (bps_event_get_code(event) == MMRENDERER_STATE_CHANGE) {
const mmrenderer_state_t newState = mmrenderer_event_get_state(event);
if (newState == MMR_STOPPED) {
handleMmStopped();
return false;
}
}
if (bps_event_get_code(event) == MMRENDERER_STATUS_UPDATE) {
const qint64 newPosition = QString::fromLatin1(mmrenderer_event_get_position(event)).toLongLong();
handleMmStatusUpdate(newPosition);
const QString bufferStatus = QString::fromLatin1(mmrenderer_event_get_bufferlevel(event));
setMmBufferStatus(bufferStatus);
}
}
return false;
}
QT_END_NAMESPACE

View File

@@ -0,0 +1,66 @@
/****************************************************************************
**
** Copyright (C) 2013 Research In Motion
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia 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.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef BPSMEDIAPLAYERCONTROL_H
#define BPSMEDIAPLAYERCONTROL_H
#include "bbmediaplayercontrol.h"
QT_BEGIN_NAMESPACE
class BpsMediaPlayerControl Q_DECL_FINAL : public BbMediaPlayerControl
{
Q_OBJECT
public:
explicit BpsMediaPlayerControl(QObject *parent = 0);
~BpsMediaPlayerControl();
void startMonitoring(int contextId, const QString &contextName) Q_DECL_OVERRIDE;
void stopMonitoring() Q_DECL_OVERRIDE;
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
private:
mmrenderer_monitor_t *m_eventMonitor;
};
QT_END_NAMESPACE
#endif

View File

@@ -19,3 +19,13 @@ SOURCES += \
$$PWD/bbvideowindowcontrol.cpp $$PWD/bbvideowindowcontrol.cpp
LIBS += -lmmrndclient -lstrm LIBS += -lmmrndclient -lstrm
blackberry {
HEADERS += $$PWD/bpsmediaplayercontrol.h
SOURCES += $$PWD/bpsmediaplayercontrol.cpp
} else {
HEADERS += $$PWD/ppsmediaplayercontrol.h
SOURCES += $$PWD/ppsmediaplayercontrol.cpp
QT += core-private
LIBS += -lpps
}

View File

@@ -0,0 +1,199 @@
/****************************************************************************
**
** Copyright (C) 2013 Research In Motion
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia 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.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "ppsmediaplayercontrol.h"
#include "bbvideowindowcontrol.h"
#include <QtCore/qfile.h>
#include <QtCore/qsocketnotifier.h>
#include <QtCore/private/qcore_unix_p.h>
#include <screen/screen.h>
#include <sys/pps.h>
QT_BEGIN_NAMESPACE
PpsMediaPlayerControl::PpsMediaPlayerControl(QObject *parent)
: BbMediaPlayerControl(parent),
m_ppsStatusNotifier(0),
m_ppsStatusFd(-1),
m_ppsStateNotifier(0),
m_ppsStateFd(-1)
, m_previouslySeenState("STOPPED")
{
openConnection();
}
PpsMediaPlayerControl::~PpsMediaPlayerControl()
{
destroy();
}
void PpsMediaPlayerControl::startMonitoring(int, const QString &contextName)
{
const QString ppsContextPath = QStringLiteral("/pps/services/multimedia/renderer/context/%1/").arg(contextName);
const QString ppsStatusPath = ppsContextPath + QStringLiteral("/status");
Q_ASSERT(m_ppsStatusFd == -1);
errno = 0;
m_ppsStatusFd = qt_safe_open(QFile::encodeName(ppsStatusPath).constData(), O_RDONLY);
if (m_ppsStatusFd == -1) {
emitPError(QStringLiteral("Unable to open %1: %2").arg(ppsStatusPath, qt_error_string(errno)));
return;
}
Q_ASSERT(!m_ppsStatusNotifier);
m_ppsStatusNotifier = new QSocketNotifier(m_ppsStatusFd, QSocketNotifier::Read);
connect(m_ppsStatusNotifier, SIGNAL(activated(int)), this, SLOT(ppsReadyRead(int)));
const QString ppsStatePath = ppsContextPath + QStringLiteral("/state");
Q_ASSERT(m_ppsStateFd == -1);
errno = 0;
m_ppsStateFd = qt_safe_open(QFile::encodeName(ppsStatePath).constData(), O_RDONLY);
if (m_ppsStateFd == -1) {
emitPError(QStringLiteral("Unable to open %1: %2").arg(ppsStatePath, qt_error_string(errno)));
return;
}
Q_ASSERT(!m_ppsStateNotifier);
m_ppsStateNotifier = new QSocketNotifier(m_ppsStateFd, QSocketNotifier::Read);
connect(m_ppsStateNotifier, SIGNAL(activated(int)), this, SLOT(ppsReadyRead(int)));
//ensure we receive any initial state
ppsReadyRead(m_ppsStatusFd);
ppsReadyRead(m_ppsStateFd);
}
void PpsMediaPlayerControl::stopMonitoring()
{
if (m_ppsStatusFd != -1) {
::close(m_ppsStatusFd);
m_ppsStatusFd = -1;
}
delete m_ppsStatusNotifier;
m_ppsStatusNotifier = 0;
if (m_ppsStateFd != -1) {
::close(m_ppsStateFd);
m_ppsStateFd = -1;
}
delete m_ppsStateNotifier;
m_ppsStateNotifier = 0;
}
bool PpsMediaPlayerControl::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
Q_UNUSED(result)
if (eventType == "screen_event_t") {
screen_event_t event = static_cast<screen_event_t>(message);
if (BbVideoWindowControl *control = videoWindowControl())
control->screenEventHandler(event);
}
return false;
}
void PpsMediaPlayerControl::ppsReadyRead(int fd)
{
Q_ASSERT(fd == m_ppsStateFd || fd == m_ppsStatusFd);
const int bufferSize = 2048;
char buffer[bufferSize];
const ssize_t nread = qt_safe_read(fd, buffer, bufferSize - 1);
if (nread < 0) {
//TODO emit error?
}
if (nread == 0) {
return;
}
// nread is the real space necessary, not the amount read.
if (static_cast<size_t>(nread) > bufferSize - 1) {
//TODO emit error?
qCritical("BBMediaPlayerControl: PPS buffer size too short; need %u.", nread + 1);
return;
}
buffer[nread] = 0;
pps_decoder_t decoder;
if (pps_decoder_initialize(&decoder, buffer) != PPS_DECODER_OK) {
//TODO emit error?
qCritical("Could not initialize pps_decoder");
pps_decoder_cleanup(&decoder);
return;
}
pps_decoder_push(&decoder, 0);
const char *value = 0;
if (pps_decoder_get_string(&decoder, "bufferlevel", &value) == PPS_DECODER_OK) {
setMmBufferStatus(QString::fromLatin1(value));
}
if (pps_decoder_get_string(&decoder, "state", &value) == PPS_DECODER_OK) {
const QByteArray state = value;
if (state != m_previouslySeenState && state == "STOPPED")
handleMmStopped();
m_previouslySeenState = state;
}
if (pps_decoder_get_string(&decoder, "position", &value) == PPS_DECODER_OK) {
const QByteArray valueBa = QByteArray(value);
bool ok;
const qint64 position = valueBa.toLongLong(&ok);
if (!ok) {
qCritical("Could not parse position from '%s'", valueBa.constData());
} else {
setMmPosition(position);
}
}
pps_decoder_cleanup(&decoder);
}
QT_END_NAMESPACE

View File

@@ -0,0 +1,75 @@
/****************************************************************************
**
** Copyright (C) 2013 Research In Motion
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia 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.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef PPSMEDIAPLAYERCONTROL_H
#define PPSMEDIAPLAYERCONTROL_H
#include "bbmediaplayercontrol.h"
QT_BEGIN_NAMESPACE
class QSocketNotifier;
class PpsMediaPlayerControl Q_DECL_FINAL : public BbMediaPlayerControl
{
Q_OBJECT
public:
explicit PpsMediaPlayerControl(QObject *parent = 0);
~PpsMediaPlayerControl();
void startMonitoring(int contextId, const QString &contextName) Q_DECL_OVERRIDE;
void stopMonitoring() Q_DECL_OVERRIDE;
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE;
private Q_SLOTS:
void ppsReadyRead(int fd);
private:
QSocketNotifier *m_ppsStatusNotifier;
int m_ppsStatusFd;
QSocketNotifier *m_ppsStateNotifier;
int m_ppsStateFd;
QByteArray m_previouslySeenState;
};
QT_END_NAMESPACE
#endif

View File

@@ -0,0 +1,4 @@
{
"Keys": ["neutrinomultimedia"],
"Services": ["org.qt-project.qt.mediaplayer"]
}

View File

@@ -0,0 +1,70 @@
/****************************************************************************
**
** Copyright (C) 2012 Research In Motion
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia 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.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "neutrinoserviceplugin.h"
#include "bbmediaplayerservice.h"
QT_BEGIN_NAMESPACE
NeutrinoServicePlugin::NeutrinoServicePlugin()
{
}
QMediaService *NeutrinoServicePlugin::create(const QString &key)
{
if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
return new BbMediaPlayerService();
return 0;
}
void NeutrinoServicePlugin::release(QMediaService *service)
{
delete service;
}
QMediaServiceProviderHint::Features NeutrinoServicePlugin::supportedFeatures(const QByteArray &service) const
{
Q_UNUSED(service)
return QMediaServiceProviderHint::Features();
}
QT_END_NAMESPACE

View File

@@ -0,0 +1,65 @@
/****************************************************************************
**
** Copyright (C) 2012 Research In Motion
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, 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, Digia gives you certain additional
** rights. These rights are described in the Digia 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.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef NEUTRINOSERVICEPLUGIN_H
#define NEUTRINOSERVICEPLUGIN_H
#include <qmediaserviceproviderplugin.h>
QT_BEGIN_NAMESPACE
class NeutrinoServicePlugin
: public QMediaServiceProviderPlugin,
public QMediaServiceFeaturesInterface
{
Q_OBJECT
Q_INTERFACES(QMediaServiceFeaturesInterface)
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "neutrino_mediaservice.json")
public:
NeutrinoServicePlugin();
QMediaService *create(const QString &key) Q_DECL_OVERRIDE;
void release(QMediaService *service) Q_DECL_OVERRIDE;
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
#endif

View File

@@ -12,11 +12,8 @@ android {
SUBDIRS += android opensles SUBDIRS += android opensles
} }
blackberry {
SUBDIRS += blackberry
}
qnx { qnx {
SUBDIRS += blackberry
SUBDIRS += audiocapture qnx SUBDIRS += audiocapture qnx
} }