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
HEADERS += bbserviceplugin.h
SOURCES += bbserviceplugin.cpp
include(common/common.pri)
include(camera/camera.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 <qpa/qplatformnativeinterface.h>
#ifdef Q_OS_BLACKBERRY
#include <bps/event.h>
#include <bps/screen.h>
#endif
#include <errno.h>
QT_BEGIN_NAMESPACE
@@ -232,12 +235,8 @@ void WindowGrabber::resume()
m_timer.start();
}
bool WindowGrabber::nativeEventFilter(const QByteArray&, void *message, long*)
bool WindowGrabber::handleScreenEvent(screen_event_t screen_event)
{
bps_event_t * const event = static_cast<bps_event_t *>(message);
if (event && bps_event_get_domain(event) == screen_get_domain()) {
const screen_event_t screen_event = screen_event_get_event(event);
int eventType;
if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
@@ -265,7 +264,26 @@ bool WindowGrabber::nativeEventFilter(const QByteArray&, void *message, long*)
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);
if (event && bps_event_get_domain(event) == screen_get_domain()) {
const screen_event_t screen_event = screen_event_get_event(event);
return handleScreenEvent(screen_event);
}
#else
if (eventType == "screen_event_t") {
const screen_event_t event = static_cast<screen_event_t>(message);
return handleScreenEvent(event);
}
#endif
return false;
}

View File

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

View File

@@ -49,8 +49,7 @@
#include <QtCore/qfileinfo.h>
#include <QtCore/quuid.h>
#include <mm/renderer.h>
#include <bps/mmrenderer.h>
#include <bps/screen.h>
#include <errno.h>
#include <sys/strm.h>
#include <sys/stat.h>
@@ -69,7 +68,6 @@ BbMediaPlayerControl::BbMediaPlayerControl(QObject *parent)
m_muted(false),
m_rate(1),
m_id(-1),
m_eventMonitor(0),
m_position(0),
m_mediaStatus(QMediaPlayer::NoMedia),
m_playAfterMediaLoaded(false),
@@ -81,10 +79,9 @@ BbMediaPlayerControl::BbMediaPlayerControl(QObject *parent)
m_loadingTimer.setInterval(0);
connect(&m_loadingTimer, SIGNAL(timeout()), this, SLOT(continueLoadMedia()));
QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
openConnection();
}
BbMediaPlayerControl::~BbMediaPlayerControl()
void BbMediaPlayerControl::destroy()
{
stop();
detach();
@@ -111,19 +108,41 @@ void BbMediaPlayerControl::openConnection()
return;
}
m_eventMonitor = mmrenderer_request_events(m_contextName.toLatin1(), 0, m_id);
if (!m_eventMonitor) {
qDebug() << "Unable to request multimedia events";
emit error(0, "Unable to request multimedia events");
startMonitoring(m_id, m_contextName);
}
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()
{
if (m_eventMonitor) {
mmrenderer_stop_events(m_eventMonitor);
m_eventMonitor = 0;
}
stopMonitoring();
if (m_context) {
mmr_context_destroy(m_context);
@@ -468,6 +487,16 @@ void BbMediaPlayerControl::continueLoadMedia()
play();
}
QString BbMediaPlayerControl::contextName() const
{
return m_contextName;
}
BbVideoWindowControl *BbMediaPlayerControl::videoWindowControl() const
{
return m_videoWindowControl;
}
void BbMediaPlayerControl::play()
{
if (m_playAfterMediaLoaded)
@@ -526,6 +555,11 @@ void BbMediaPlayerControl::stop()
stopInternal(StopMmRenderer);
}
BbPlayerVideoRendererControl *BbMediaPlayerControl::videoRendererControl() const
{
return m_videoRendererControl;
}
void BbMediaPlayerControl::setVideoRendererControl(BbPlayerVideoRendererControl *videoControl)
{
m_videoRendererControl = videoControl;
@@ -541,58 +575,16 @@ void BbMediaPlayerControl::setMetaDataReaderControl(BbMetaDataReaderControl *met
m_metaDataReaderControl = metaDataReaderControl;
}
bool BbMediaPlayerControl::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
void BbMediaPlayerControl::setMmPosition(qint64 newPosition)
{
Q_UNUSED(eventType);
Q_UNUSED(result);
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 (m_videoWindowControl)
m_videoWindowControl->bpsEventHandler(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) {
// 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));
void BbMediaPlayerControl::setMmBufferStatus(const QString &bufferStatus)
{
const int slashPos = bufferStatus.indexOf('/');
if (slashPos != -1) {
const int fill = bufferStatus.left(slashPos).toInt();
@@ -602,10 +594,6 @@ bool BbMediaPlayerControl::nativeEventFilter(const QByteArray &eventType, void *
emit bufferStatusChanged(m_bufferStatus);
}
}
}
}
return false;
}
void BbMediaPlayerControl::updateMetaData()

View File

@@ -47,7 +47,6 @@
#include <QtCore/qpointer.h>
#include <QtCore/qtimer.h>
struct bps_event_t;
typedef struct mmr_connection mmr_connection_t;
typedef struct mmr_context mmr_context_t;
typedef struct mmrenderer_monitor mmrenderer_monitor_t;
@@ -63,7 +62,6 @@ class BbMediaPlayerControl : public QMediaPlayerControl, public QAbstractNativeE
Q_OBJECT
public:
explicit BbMediaPlayerControl(QObject *parent = 0);
~BbMediaPlayerControl();
QMediaPlayer::State state() const Q_DECL_OVERRIDE;
@@ -100,25 +98,39 @@ public:
void pause() Q_DECL_OVERRIDE;
void stop() Q_DECL_OVERRIDE;
BbPlayerVideoRendererControl *videoRendererControl() const;
void setVideoRendererControl(BbPlayerVideoRendererControl *videoControl);
BbVideoWindowControl *videoWindowControl() const;
void setVideoWindowControl(BbVideoWindowControl *videoControl);
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:
void continueLoadMedia();
private:
QByteArray resourcePathForUrl(const QUrl &url);
void openConnection();
void closeConnection();
void attach();
void detach();
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
// nor change the member value.
void setVolumeInternal(int newVolume);
@@ -145,7 +157,6 @@ private:
QPointer<BbMetaDataReaderControl> m_metaDataReaderControl;
BbMetaData m_metaData;
int m_id;
mmrenderer_monitor_t *m_eventMonitor;
qint64 m_position;
QMediaPlayer::MediaStatus m_mediaStatus;
bool m_playAfterMediaLoaded;

View File

@@ -46,6 +46,14 @@
#include "bbutil.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
BbMediaPlayerService::BbMediaPlayerService(QObject *parent)
@@ -72,7 +80,7 @@ QMediaControl *BbMediaPlayerService::requestControl(const char *name)
{
if (qstrcmp(name, QMediaPlayerControl_iid) == 0) {
if (!m_mediaPlayerControl) {
m_mediaPlayerControl = new BbMediaPlayerControl();
m_mediaPlayerControl = new PlatformSpecificMediaPlayerControl;
updateControls();
}
return m_mediaPlayerControl;

View File

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

View File

@@ -46,7 +46,6 @@
#include <QtGui/qscreen.h>
#include <QtGui/qwindow.h>
#include <mm/renderer.h>
#include <bps/screen.h>
QT_BEGIN_NAMESPACE
@@ -368,11 +367,8 @@ void BbVideoWindowControl::setMetaData(const BbMetaData &metaData)
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()) {
const screen_event_t screen_event = screen_event_get_event(event);
int eventType;
if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
perror("BbVideoWindowControl: Failed to query screen event type");
@@ -405,7 +401,6 @@ void BbVideoWindowControl::bpsEventHandler(bps_event_t *event)
return;
}
}
}
}
QWindow *BbVideoWindowControl::findWindow(WId id) const

View File

@@ -46,7 +46,6 @@
#include <screen/screen.h>
typedef struct mmr_context mmr_context_t;
struct bps_event_t;
QT_BEGIN_NAMESPACE
@@ -91,7 +90,7 @@ public:
void detachDisplay();
void attachDisplay(mmr_context_t *context);
void setMetaData(const BbMetaData &metaData);
void bpsEventHandler(bps_event_t *event);
void screenEventHandler(const screen_event_t &event);
private:
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
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
}
blackberry {
SUBDIRS += blackberry
}
qnx {
SUBDIRS += blackberry
SUBDIRS += audiocapture qnx
}