QNX: Restructure plugins
Now that the MmRenderer implementation is ported to plain QNX, rename the directories and files accordingly: "blackberry" becomes "qnx", replace the Bb prefix with MmRenderer for classes concerned with mm-renderer. The legacy alsa support for plain qnx is now "qnx-audio". Change-Id: I6abd98ecdd713b2d5e554d42224dc30f13772f43 Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
This commit is contained in:
committed by
The Qt Project
parent
66219c9a28
commit
99667804e1
117
src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.cpp
Normal file
117
src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.cpp
Normal 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 "mmrenderervideowindowcontrol.h"
|
||||
|
||||
#include <bps/mmrenderer.h>
|
||||
#include <bps/screen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
BpsMediaPlayerControl::BpsMediaPlayerControl(QObject *parent)
|
||||
: MmRendererMediaPlayerControl(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 (MmRendererVideoWindowControl *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
|
||||
66
src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.h
Normal file
66
src/plugins/qnx/mediaplayer/bpsmediaplayercontrol.h
Normal 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 "mmrenderermediaplayercontrol.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class BpsMediaPlayerControl Q_DECL_FINAL : public MmRendererMediaPlayerControl
|
||||
{
|
||||
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
|
||||
31
src/plugins/qnx/mediaplayer/mediaplayer.pri
Normal file
31
src/plugins/qnx/mediaplayer/mediaplayer.pri
Normal file
@@ -0,0 +1,31 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/mmrenderermediaplayercontrol.h \
|
||||
$$PWD/mmrenderermediaplayerservice.h \
|
||||
$$PWD/mmrenderermetadata.h \
|
||||
$$PWD/mmrenderermetadatareadercontrol.h \
|
||||
$$PWD/mmrendererplayervideorenderercontrol.h \
|
||||
$$PWD/mmrendererutil.h \
|
||||
$$PWD/mmrenderervideowindowcontrol.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/mmrenderermediaplayercontrol.cpp \
|
||||
$$PWD/mmrenderermediaplayerservice.cpp \
|
||||
$$PWD/mmrenderermetadata.cpp \
|
||||
$$PWD/mmrenderermetadatareadercontrol.cpp \
|
||||
$$PWD/mmrendererplayervideorenderercontrol.cpp \
|
||||
$$PWD/mmrendererutil.cpp \
|
||||
$$PWD/mmrenderervideowindowcontrol.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
|
||||
}
|
||||
634
src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
Normal file
634
src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp
Normal file
@@ -0,0 +1,634 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "mmrenderermediaplayercontrol.h"
|
||||
#include "mmrenderermetadatareadercontrol.h"
|
||||
#include "mmrendererplayervideorenderercontrol.h"
|
||||
#include "mmrendererutil.h"
|
||||
#include "mmrenderervideowindowcontrol.h"
|
||||
#include <QtCore/qabstracteventdispatcher.h>
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qdir.h>
|
||||
#include <QtCore/qfileinfo.h>
|
||||
#include <QtCore/quuid.h>
|
||||
#include <mm/renderer.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/strm.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static int idCounter = 0;
|
||||
|
||||
MmRendererMediaPlayerControl::MmRendererMediaPlayerControl(QObject *parent)
|
||||
: QMediaPlayerControl(parent),
|
||||
m_connection(0),
|
||||
m_context(0),
|
||||
m_audioId(-1),
|
||||
m_state(QMediaPlayer::StoppedState),
|
||||
m_volume(100),
|
||||
m_muted(false),
|
||||
m_rate(1),
|
||||
m_id(-1),
|
||||
m_position(0),
|
||||
m_mediaStatus(QMediaPlayer::NoMedia),
|
||||
m_playAfterMediaLoaded(false),
|
||||
m_inputAttached(false),
|
||||
m_stopEventsToIgnore(0),
|
||||
m_bufferStatus(0)
|
||||
{
|
||||
m_loadingTimer.setSingleShot(true);
|
||||
m_loadingTimer.setInterval(0);
|
||||
connect(&m_loadingTimer, SIGNAL(timeout()), this, SLOT(continueLoadMedia()));
|
||||
QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::destroy()
|
||||
{
|
||||
stop();
|
||||
detach();
|
||||
closeConnection();
|
||||
QCoreApplication::eventDispatcher()->removeNativeEventFilter(this);
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::openConnection()
|
||||
{
|
||||
m_connection = mmr_connect(NULL);
|
||||
if (!m_connection) {
|
||||
emitPError("Unable to connect to the multimedia renderer");
|
||||
return;
|
||||
}
|
||||
|
||||
m_id = idCounter++;
|
||||
m_contextName = QString("MmRendererMediaPlayerControl_%1_%2").arg(m_id)
|
||||
.arg(QCoreApplication::applicationPid());
|
||||
m_context = mmr_context_create(m_connection, m_contextName.toLatin1(),
|
||||
0, S_IRWXU|S_IRWXG|S_IRWXO);
|
||||
if (!m_context) {
|
||||
emitPError("Unable to create context");
|
||||
closeConnection();
|
||||
return;
|
||||
}
|
||||
|
||||
startMonitoring(m_id, m_contextName);
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::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 MmRendererMediaPlayerControl::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 MmRendererMediaPlayerControl::closeConnection()
|
||||
{
|
||||
stopMonitoring();
|
||||
|
||||
if (m_context) {
|
||||
mmr_context_destroy(m_context);
|
||||
m_context = 0;
|
||||
m_contextName.clear();
|
||||
}
|
||||
|
||||
if (m_connection) {
|
||||
mmr_disconnect(m_connection);
|
||||
m_connection = 0;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray MmRendererMediaPlayerControl::resourcePathForUrl(const QUrl &url)
|
||||
{
|
||||
// If this is a local file, mmrenderer expects the file:// prefix and an absolute path.
|
||||
// We treat URLs without scheme as local files, most likely someone just forgot to set the
|
||||
// file:// prefix when constructing the URL.
|
||||
if (url.isLocalFile() || url.scheme().isEmpty()) {
|
||||
QString relativeFilePath;
|
||||
if (!url.scheme().isEmpty())
|
||||
relativeFilePath = url.toLocalFile();
|
||||
else
|
||||
relativeFilePath = url.path();
|
||||
const QFileInfo fileInfo(relativeFilePath);
|
||||
return QFile::encodeName(QStringLiteral("file://") + fileInfo.absoluteFilePath());
|
||||
|
||||
// QRC, copy to temporary file, as mmrenderer does not support resource files
|
||||
} else if (url.scheme() == QStringLiteral("qrc")) {
|
||||
const QString qrcPath = ':' + url.path();
|
||||
const QFileInfo resourceFileInfo(qrcPath);
|
||||
m_tempMediaFileName = QDir::tempPath() + QStringLiteral("/qtmedia_") +
|
||||
QUuid::createUuid().toString() + QStringLiteral(".") +
|
||||
resourceFileInfo.suffix();
|
||||
if (!QFile::copy(qrcPath, m_tempMediaFileName)) {
|
||||
const QString errorMsg = QString("Failed to copy resource file to temporary file "
|
||||
"%1 for playback").arg(m_tempMediaFileName);
|
||||
qDebug() << errorMsg;
|
||||
emit error(0, errorMsg);
|
||||
return QByteArray();
|
||||
}
|
||||
return QFile::encodeName(m_tempMediaFileName);
|
||||
|
||||
// HTTP or similar URL
|
||||
} else {
|
||||
return url.toEncoded();
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::attach()
|
||||
{
|
||||
// Should only be called in detached state
|
||||
Q_ASSERT(m_audioId == -1 && !m_inputAttached && m_tempMediaFileName.isEmpty());
|
||||
|
||||
if (m_media.isNull() || !m_context) {
|
||||
setMediaStatus(QMediaPlayer::NoMedia);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_videoRendererControl)
|
||||
m_videoRendererControl->attachDisplay(m_context);
|
||||
|
||||
if (m_videoWindowControl)
|
||||
m_videoWindowControl->attachDisplay(m_context);
|
||||
|
||||
m_audioId = mmr_output_attach(m_context, "audio:default", "audio");
|
||||
if (m_audioId == -1) {
|
||||
emitMmError("mmr_output_attach() for audio failed");
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArray resourcePath = resourcePathForUrl(m_media.canonicalUrl());
|
||||
if (resourcePath.isEmpty()) {
|
||||
detach();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mmr_input_attach(m_context, resourcePath.constData(), "track") != 0) {
|
||||
emitMmError(QStringLiteral("mmr_input_attach() failed for ") + QString(resourcePath));
|
||||
setMediaStatus(QMediaPlayer::InvalidMedia);
|
||||
detach();
|
||||
return;
|
||||
}
|
||||
|
||||
// For whatever reason, the mmrenderer sends out a MMR_STOPPED event when calling
|
||||
// mmr_input_attach() above. Ignore it, as otherwise we'll trigger stopping right after we
|
||||
// started.
|
||||
m_stopEventsToIgnore++;
|
||||
|
||||
m_inputAttached = true;
|
||||
setMediaStatus(QMediaPlayer::LoadedMedia);
|
||||
m_bufferStatus = 0;
|
||||
emit bufferStatusChanged(m_bufferStatus);
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::detach()
|
||||
{
|
||||
if (m_context) {
|
||||
if (m_inputAttached) {
|
||||
mmr_input_detach(m_context);
|
||||
m_inputAttached = false;
|
||||
}
|
||||
if (m_videoRendererControl)
|
||||
m_videoRendererControl->detachDisplay();
|
||||
if (m_videoWindowControl)
|
||||
m_videoWindowControl->detachDisplay();
|
||||
if (m_audioId != -1 && m_context) {
|
||||
mmr_output_detach(m_context, m_audioId);
|
||||
m_audioId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_tempMediaFileName.isEmpty()) {
|
||||
QFile::remove(m_tempMediaFileName);
|
||||
m_tempMediaFileName.clear();
|
||||
}
|
||||
m_loadingTimer.stop();
|
||||
}
|
||||
|
||||
QMediaPlayer::State MmRendererMediaPlayerControl::state() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
QMediaPlayer::MediaStatus MmRendererMediaPlayerControl::mediaStatus() const
|
||||
{
|
||||
return m_mediaStatus;
|
||||
}
|
||||
|
||||
qint64 MmRendererMediaPlayerControl::duration() const
|
||||
{
|
||||
return m_metaData.duration();
|
||||
}
|
||||
|
||||
qint64 MmRendererMediaPlayerControl::position() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setPosition(qint64 position)
|
||||
{
|
||||
if (m_position != position) {
|
||||
m_position = position;
|
||||
|
||||
// Don't update in stopped state, it would not have any effect. Instead, the position is
|
||||
// updated in play().
|
||||
if (m_state != QMediaPlayer::StoppedState)
|
||||
setPositionInternal(m_position);
|
||||
|
||||
emit positionChanged(m_position);
|
||||
}
|
||||
}
|
||||
|
||||
int MmRendererMediaPlayerControl::volume() const
|
||||
{
|
||||
return m_volume;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setVolumeInternal(int newVolume)
|
||||
{
|
||||
if (!m_context)
|
||||
return;
|
||||
|
||||
newVolume = qBound(0, newVolume, 100);
|
||||
if (m_audioId != -1) {
|
||||
strm_dict_t * dict = strm_dict_new();
|
||||
dict = strm_dict_set(dict, "volume", QString::number(newVolume).toLatin1());
|
||||
if (mmr_output_parameters(m_context, m_audioId, dict) != 0)
|
||||
emitMmError("mmr_output_parameters: Setting volume failed");
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setPlaybackRateInternal(qreal rate)
|
||||
{
|
||||
if (!m_context)
|
||||
return;
|
||||
|
||||
const int mmRate = rate * 1000;
|
||||
if (mmr_speed_set(m_context, mmRate) != 0)
|
||||
emitMmError("mmr_speed_set failed");
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setPositionInternal(qint64 position)
|
||||
{
|
||||
if (!m_context)
|
||||
return;
|
||||
|
||||
if (m_metaData.isSeekable()) {
|
||||
if (mmr_seek(m_context, QString::number(position).toLatin1()) != 0)
|
||||
emitMmError("Seeking failed");
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status)
|
||||
{
|
||||
if (m_mediaStatus != status) {
|
||||
m_mediaStatus = status;
|
||||
emit mediaStatusChanged(m_mediaStatus);
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setState(QMediaPlayer::State state)
|
||||
{
|
||||
if (m_state != state) {
|
||||
if (m_videoRendererControl) {
|
||||
if (state == QMediaPlayer::PausedState)
|
||||
m_videoRendererControl->pause();
|
||||
else if ((state == QMediaPlayer::PlayingState)
|
||||
&& (m_state == QMediaPlayer::PausedState)) {
|
||||
m_videoRendererControl->resume();
|
||||
}
|
||||
}
|
||||
|
||||
m_state = state;
|
||||
emit stateChanged(m_state);
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::stopInternal(StopCommand stopCommand)
|
||||
{
|
||||
if (m_state != QMediaPlayer::StoppedState) {
|
||||
|
||||
if (stopCommand == StopMmRenderer) {
|
||||
++m_stopEventsToIgnore;
|
||||
mmr_stop(m_context);
|
||||
}
|
||||
|
||||
setState(QMediaPlayer::StoppedState);
|
||||
}
|
||||
|
||||
if (m_position != 0) {
|
||||
m_position = 0;
|
||||
emit positionChanged(0);
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setVolume(int volume)
|
||||
{
|
||||
const int newVolume = qBound(0, volume, 100);
|
||||
if (m_volume != newVolume) {
|
||||
m_volume = newVolume;
|
||||
if (!m_muted)
|
||||
setVolumeInternal(m_volume);
|
||||
emit volumeChanged(m_volume);
|
||||
}
|
||||
}
|
||||
|
||||
bool MmRendererMediaPlayerControl::isMuted() const
|
||||
{
|
||||
return m_muted;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setMuted(bool muted)
|
||||
{
|
||||
if (m_muted != muted) {
|
||||
m_muted = muted;
|
||||
setVolumeInternal(muted ? 0 : m_volume);
|
||||
emit mutedChanged(muted);
|
||||
}
|
||||
}
|
||||
|
||||
int MmRendererMediaPlayerControl::bufferStatus() const
|
||||
{
|
||||
return m_bufferStatus;
|
||||
}
|
||||
|
||||
bool MmRendererMediaPlayerControl::isAudioAvailable() const
|
||||
{
|
||||
return m_metaData.hasAudio();
|
||||
}
|
||||
|
||||
bool MmRendererMediaPlayerControl::isVideoAvailable() const
|
||||
{
|
||||
return m_metaData.hasVideo();
|
||||
}
|
||||
|
||||
bool MmRendererMediaPlayerControl::isSeekable() const
|
||||
{
|
||||
return m_metaData.isSeekable();
|
||||
}
|
||||
|
||||
QMediaTimeRange MmRendererMediaPlayerControl::availablePlaybackRanges() const
|
||||
{
|
||||
// We can't get this information from the mmrenderer API yet, so pretend we can seek everywhere
|
||||
return QMediaTimeRange(0, m_metaData.duration());
|
||||
}
|
||||
|
||||
qreal MmRendererMediaPlayerControl::playbackRate() const
|
||||
{
|
||||
return m_rate;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setPlaybackRate(qreal rate)
|
||||
{
|
||||
if (m_rate != rate) {
|
||||
m_rate = rate;
|
||||
setPlaybackRateInternal(m_rate);
|
||||
emit playbackRateChanged(m_rate);
|
||||
}
|
||||
}
|
||||
|
||||
QMediaContent MmRendererMediaPlayerControl::media() const
|
||||
{
|
||||
return m_media;
|
||||
}
|
||||
|
||||
const QIODevice *MmRendererMediaPlayerControl::mediaStream() const
|
||||
{
|
||||
// Always 0, we don't support QIODevice streams
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream)
|
||||
{
|
||||
Q_UNUSED(stream); // not supported
|
||||
|
||||
stop();
|
||||
detach();
|
||||
|
||||
m_media = media;
|
||||
emit mediaChanged(m_media);
|
||||
|
||||
// Slight hack: With MediaPlayer QtQuick elements that have autoPlay set to true, playback
|
||||
// would start before the QtQuick canvas is propagated to all elements, and therefore our
|
||||
// video output would not work. Therefore, delay actually playing the media a bit so that the
|
||||
// canvas is ready.
|
||||
// The mmrenderer doesn't allow to attach video outputs after playing has started, otherwise
|
||||
// this would be unnecessary.
|
||||
if (!m_media.isNull()) {
|
||||
setMediaStatus(QMediaPlayer::LoadingMedia);
|
||||
m_loadingTimer.start(); // singleshot timer to continueLoadMedia()
|
||||
} else {
|
||||
continueLoadMedia(); // still needed, as it will update the media status and clear metadata
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::continueLoadMedia()
|
||||
{
|
||||
attach();
|
||||
updateMetaData();
|
||||
if (m_playAfterMediaLoaded)
|
||||
play();
|
||||
}
|
||||
|
||||
QString MmRendererMediaPlayerControl::contextName() const
|
||||
{
|
||||
return m_contextName;
|
||||
}
|
||||
|
||||
MmRendererVideoWindowControl *MmRendererMediaPlayerControl::videoWindowControl() const
|
||||
{
|
||||
return m_videoWindowControl;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::play()
|
||||
{
|
||||
if (m_playAfterMediaLoaded)
|
||||
m_playAfterMediaLoaded = false;
|
||||
|
||||
// No-op if we are already playing, except if we were called from continueLoadMedia(), in which
|
||||
// case m_playAfterMediaLoaded is true (hence the 'else').
|
||||
else if (m_state == QMediaPlayer::PlayingState)
|
||||
return;
|
||||
|
||||
if (m_mediaStatus == QMediaPlayer::LoadingMedia) {
|
||||
|
||||
// State changes are supposed to be synchronous
|
||||
setState(QMediaPlayer::PlayingState);
|
||||
|
||||
// Defer playing to later, when the timer triggers continueLoadMedia()
|
||||
m_playAfterMediaLoaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Un-pause the state when it is paused
|
||||
if (m_state == QMediaPlayer::PausedState) {
|
||||
setPlaybackRateInternal(m_rate);
|
||||
setState(QMediaPlayer::PlayingState);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_media.isNull() || !m_connection || !m_context || m_audioId == -1) {
|
||||
setState(QMediaPlayer::StoppedState);
|
||||
return;
|
||||
}
|
||||
|
||||
setPositionInternal(m_position);
|
||||
setVolumeInternal(m_volume);
|
||||
setPlaybackRateInternal(m_rate);
|
||||
|
||||
if (mmr_play(m_context) != 0) {
|
||||
setState(QMediaPlayer::StoppedState);
|
||||
emitMmError("mmr_play() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
setState( QMediaPlayer::PlayingState);
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::pause()
|
||||
{
|
||||
if (m_state == QMediaPlayer::PlayingState) {
|
||||
setPlaybackRateInternal(0);
|
||||
setState(QMediaPlayer::PausedState);
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::stop()
|
||||
{
|
||||
stopInternal(StopMmRenderer);
|
||||
}
|
||||
|
||||
MmRendererPlayerVideoRendererControl *MmRendererMediaPlayerControl::videoRendererControl() const
|
||||
{
|
||||
return m_videoRendererControl;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setVideoRendererControl(MmRendererPlayerVideoRendererControl *videoControl)
|
||||
{
|
||||
m_videoRendererControl = videoControl;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setVideoWindowControl(MmRendererVideoWindowControl *videoControl)
|
||||
{
|
||||
m_videoWindowControl = videoControl;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setMetaDataReaderControl(MmRendererMetaDataReaderControl *metaDataReaderControl)
|
||||
{
|
||||
m_metaDataReaderControl = metaDataReaderControl;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setMmPosition(qint64 newPosition)
|
||||
{
|
||||
if (newPosition != 0 && newPosition != m_position) {
|
||||
m_position = newPosition;
|
||||
emit positionChanged(m_position);
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::setMmBufferStatus(const QString &bufferStatus)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::updateMetaData()
|
||||
{
|
||||
if (m_mediaStatus == QMediaPlayer::LoadedMedia)
|
||||
m_metaData.parse(m_contextName);
|
||||
else
|
||||
m_metaData.clear();
|
||||
|
||||
if (m_videoWindowControl)
|
||||
m_videoWindowControl->setMetaData(m_metaData);
|
||||
|
||||
if (m_metaDataReaderControl)
|
||||
m_metaDataReaderControl->setMetaData(m_metaData);
|
||||
|
||||
emit durationChanged(m_metaData.duration());
|
||||
emit audioAvailableChanged(m_metaData.hasAudio());
|
||||
emit videoAvailableChanged(m_metaData.hasVideo());
|
||||
emit availablePlaybackRangesChanged(availablePlaybackRanges());
|
||||
emit seekableChanged(m_metaData.isSeekable());
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::emitMmError(const QString &msg)
|
||||
{
|
||||
int errorCode = MMR_ERROR_NONE;
|
||||
const QString errorMessage = mmErrorMessage(msg, m_context, &errorCode);
|
||||
qDebug() << errorMessage;
|
||||
emit error(errorCode, errorMessage);
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerControl::emitPError(const QString &msg)
|
||||
{
|
||||
const QString errorMessage = QString("%1: %2").arg(msg).arg(strerror(errno));
|
||||
qDebug() << errorMessage;
|
||||
emit error(errno, errorMessage);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
172
src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h
Normal file
172
src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.h
Normal file
@@ -0,0 +1,172 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 MMRENDERERMEDIAPLAYERCONTROL_H
|
||||
#define MMRENDERERMEDIAPLAYERCONTROL_H
|
||||
|
||||
#include "mmrenderermetadata.h"
|
||||
#include <qmediaplayercontrol.h>
|
||||
#include <QtCore/qabstractnativeeventfilter.h>
|
||||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/qtimer.h>
|
||||
|
||||
typedef struct mmr_connection mmr_connection_t;
|
||||
typedef struct mmr_context mmr_context_t;
|
||||
typedef struct mmrenderer_monitor mmrenderer_monitor_t;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class MmRendererMetaDataReaderControl;
|
||||
class MmRendererPlayerVideoRendererControl;
|
||||
class MmRendererVideoWindowControl;
|
||||
|
||||
class MmRendererMediaPlayerControl : public QMediaPlayerControl, public QAbstractNativeEventFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MmRendererMediaPlayerControl(QObject *parent = 0);
|
||||
|
||||
QMediaPlayer::State state() const Q_DECL_OVERRIDE;
|
||||
|
||||
QMediaPlayer::MediaStatus mediaStatus() const Q_DECL_OVERRIDE;
|
||||
|
||||
qint64 duration() const Q_DECL_OVERRIDE;
|
||||
|
||||
qint64 position() const Q_DECL_OVERRIDE;
|
||||
void setPosition(qint64 position) Q_DECL_OVERRIDE;
|
||||
|
||||
int volume() const Q_DECL_OVERRIDE;
|
||||
void setVolume(int volume) Q_DECL_OVERRIDE;
|
||||
|
||||
bool isMuted() const Q_DECL_OVERRIDE;
|
||||
void setMuted(bool muted) Q_DECL_OVERRIDE;
|
||||
|
||||
int bufferStatus() const Q_DECL_OVERRIDE;
|
||||
|
||||
bool isAudioAvailable() const Q_DECL_OVERRIDE;
|
||||
bool isVideoAvailable() const Q_DECL_OVERRIDE;
|
||||
|
||||
bool isSeekable() const Q_DECL_OVERRIDE;
|
||||
|
||||
QMediaTimeRange availablePlaybackRanges() const Q_DECL_OVERRIDE;
|
||||
|
||||
qreal playbackRate() const Q_DECL_OVERRIDE;
|
||||
void setPlaybackRate(qreal rate) Q_DECL_OVERRIDE;
|
||||
|
||||
QMediaContent media() const Q_DECL_OVERRIDE;
|
||||
const QIODevice *mediaStream() const Q_DECL_OVERRIDE;
|
||||
void setMedia(const QMediaContent &media, QIODevice *stream) Q_DECL_OVERRIDE;
|
||||
|
||||
void play() Q_DECL_OVERRIDE;
|
||||
void pause() Q_DECL_OVERRIDE;
|
||||
void stop() Q_DECL_OVERRIDE;
|
||||
|
||||
MmRendererPlayerVideoRendererControl *videoRendererControl() const;
|
||||
void setVideoRendererControl(MmRendererPlayerVideoRendererControl *videoControl);
|
||||
|
||||
MmRendererVideoWindowControl *videoWindowControl() const;
|
||||
void setVideoWindowControl(MmRendererVideoWindowControl *videoControl);
|
||||
void setMetaDataReaderControl(MmRendererMetaDataReaderControl *metaDataReaderControl);
|
||||
|
||||
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 closeConnection();
|
||||
void attach();
|
||||
void detach();
|
||||
void updateMetaData();
|
||||
|
||||
// All these set the specified value to the backend, but neither emit changed signals
|
||||
// nor change the member value.
|
||||
void setVolumeInternal(int newVolume);
|
||||
void setPlaybackRateInternal(qreal rate);
|
||||
void setPositionInternal(qint64 position);
|
||||
|
||||
void setMediaStatus(QMediaPlayer::MediaStatus status);
|
||||
void setState(QMediaPlayer::State state);
|
||||
|
||||
enum StopCommand { StopMmRenderer, IgnoreMmRenderer };
|
||||
void stopInternal(StopCommand stopCommand);
|
||||
|
||||
QMediaContent m_media;
|
||||
mmr_connection_t *m_connection;
|
||||
mmr_context_t *m_context;
|
||||
QString m_contextName;
|
||||
int m_audioId;
|
||||
QMediaPlayer::State m_state;
|
||||
int m_volume;
|
||||
bool m_muted;
|
||||
qreal m_rate;
|
||||
QPointer<MmRendererPlayerVideoRendererControl> m_videoRendererControl;
|
||||
QPointer<MmRendererVideoWindowControl> m_videoWindowControl;
|
||||
QPointer<MmRendererMetaDataReaderControl> m_metaDataReaderControl;
|
||||
MmRendererMetaData m_metaData;
|
||||
int m_id;
|
||||
qint64 m_position;
|
||||
QMediaPlayer::MediaStatus m_mediaStatus;
|
||||
bool m_playAfterMediaLoaded;
|
||||
bool m_inputAttached;
|
||||
int m_stopEventsToIgnore;
|
||||
int m_bufferStatus;
|
||||
QString m_tempMediaFileName;
|
||||
QTimer m_loadingTimer;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
149
src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.cpp
Normal file
149
src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "mmrenderermediaplayerservice.h"
|
||||
|
||||
#include "mmrenderermediaplayercontrol.h"
|
||||
#include "mmrenderermetadatareadercontrol.h"
|
||||
#include "mmrendererplayervideorenderercontrol.h"
|
||||
#include "mmrendererutil.h"
|
||||
#include "mmrenderervideowindowcontrol.h"
|
||||
|
||||
#ifdef Q_OS_BLACKBERRY
|
||||
#include "bpsmediaplayercontrol.h"
|
||||
typedef BpsMediaPlayerControl PlatformSpecificMediaPlayerControl;
|
||||
#else
|
||||
#include "ppsmediaplayercontrol.h"
|
||||
typedef PpsMediaPlayerControl PlatformSpecificMediaPlayerControl;
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
MmRendererMediaPlayerService::MmRendererMediaPlayerService(QObject *parent)
|
||||
: QMediaService(parent),
|
||||
m_videoRendererControl(0),
|
||||
m_videoWindowControl(0),
|
||||
m_mediaPlayerControl(0),
|
||||
m_metaDataReaderControl(0),
|
||||
m_appHasDrmPermission(false),
|
||||
m_appHasDrmPermissionChecked(false)
|
||||
{
|
||||
}
|
||||
|
||||
MmRendererMediaPlayerService::~MmRendererMediaPlayerService()
|
||||
{
|
||||
// Someone should have called releaseControl(), but better be safe
|
||||
delete m_videoRendererControl;
|
||||
delete m_videoWindowControl;
|
||||
delete m_mediaPlayerControl;
|
||||
delete m_metaDataReaderControl;
|
||||
}
|
||||
|
||||
QMediaControl *MmRendererMediaPlayerService::requestControl(const char *name)
|
||||
{
|
||||
if (qstrcmp(name, QMediaPlayerControl_iid) == 0) {
|
||||
if (!m_mediaPlayerControl) {
|
||||
m_mediaPlayerControl = new PlatformSpecificMediaPlayerControl;
|
||||
updateControls();
|
||||
}
|
||||
return m_mediaPlayerControl;
|
||||
}
|
||||
else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) {
|
||||
if (!m_metaDataReaderControl) {
|
||||
m_metaDataReaderControl = new MmRendererMetaDataReaderControl();
|
||||
updateControls();
|
||||
}
|
||||
return m_metaDataReaderControl;
|
||||
}
|
||||
else if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
|
||||
if (!m_appHasDrmPermissionChecked) {
|
||||
m_appHasDrmPermission = checkForDrmPermission();
|
||||
m_appHasDrmPermissionChecked = true;
|
||||
}
|
||||
|
||||
if (m_appHasDrmPermission) {
|
||||
// When the application wants to play back DRM secured media, we can't use
|
||||
// the QVideoRendererControl, because we won't have access to the pixel data
|
||||
// in this case.
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_videoRendererControl) {
|
||||
m_videoRendererControl = new MmRendererPlayerVideoRendererControl();
|
||||
updateControls();
|
||||
}
|
||||
return m_videoRendererControl;
|
||||
}
|
||||
else if (qstrcmp(name, QVideoWindowControl_iid) == 0) {
|
||||
if (!m_videoWindowControl) {
|
||||
m_videoWindowControl = new MmRendererVideoWindowControl();
|
||||
updateControls();
|
||||
}
|
||||
return m_videoWindowControl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerService::releaseControl(QMediaControl *control)
|
||||
{
|
||||
if (control == m_videoRendererControl)
|
||||
m_videoRendererControl = 0;
|
||||
if (control == m_videoWindowControl)
|
||||
m_videoWindowControl = 0;
|
||||
if (control == m_mediaPlayerControl)
|
||||
m_mediaPlayerControl = 0;
|
||||
if (control == m_metaDataReaderControl)
|
||||
m_metaDataReaderControl = 0;
|
||||
delete control;
|
||||
}
|
||||
|
||||
void MmRendererMediaPlayerService::updateControls()
|
||||
{
|
||||
if (m_videoRendererControl && m_mediaPlayerControl)
|
||||
m_mediaPlayerControl->setVideoRendererControl(m_videoRendererControl);
|
||||
|
||||
if (m_videoWindowControl && m_mediaPlayerControl)
|
||||
m_mediaPlayerControl->setVideoWindowControl(m_videoWindowControl);
|
||||
|
||||
if (m_metaDataReaderControl && m_mediaPlayerControl)
|
||||
m_mediaPlayerControl->setMetaDataReaderControl(m_metaDataReaderControl);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
78
src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.h
Normal file
78
src/plugins/qnx/mediaplayer/mmrenderermediaplayerservice.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 MMRENDERERMEDIAPLAYERSERVICE_H
|
||||
#define MMRENDERERMEDIAPLAYERSERVICE_H
|
||||
|
||||
#include <qmediaservice.h>
|
||||
#include <QtCore/qpointer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class MmRendererMediaPlayerControl;
|
||||
class MmRendererMetaDataReaderControl;
|
||||
class MmRendererPlayerVideoRendererControl;
|
||||
class MmRendererVideoWindowControl;
|
||||
|
||||
class MmRendererMediaPlayerService : public QMediaService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MmRendererMediaPlayerService(QObject *parent = 0);
|
||||
~MmRendererMediaPlayerService();
|
||||
|
||||
QMediaControl *requestControl(const char *name) Q_DECL_OVERRIDE;
|
||||
void releaseControl(QMediaControl *control) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
void updateControls();
|
||||
|
||||
QPointer<MmRendererPlayerVideoRendererControl> m_videoRendererControl;
|
||||
QPointer<MmRendererVideoWindowControl> m_videoWindowControl;
|
||||
QPointer<MmRendererMediaPlayerControl> m_mediaPlayerControl;
|
||||
QPointer<MmRendererMetaDataReaderControl> m_metaDataReaderControl;
|
||||
|
||||
bool m_appHasDrmPermission : 1;
|
||||
bool m_appHasDrmPermissionChecked : 1;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
269
src/plugins/qnx/mediaplayer/mmrenderermetadata.cpp
Normal file
269
src/plugins/qnx/mediaplayer/mmrenderermetadata.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "mmrenderermetadata.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qfile.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
MmRendererMetaData::MmRendererMetaData()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
static const char * titleKey = "md_title_name";
|
||||
static const char * artistKey = "md_title_artist";
|
||||
static const char * commentKey = "md_title_comment";
|
||||
static const char * genreKey = "md_title_genre";
|
||||
static const char * yearKey = "md_title_year";
|
||||
static const char * durationKey = "md_title_duration";
|
||||
static const char * bitRateKey = "md_title_bitrate";
|
||||
static const char * sampleKey = "md_title_samplerate";
|
||||
static const char * albumKey = "md_title_album";
|
||||
static const char * trackKey = "md_title_track";
|
||||
static const char * widthKey = "md_video_width";
|
||||
static const char * heightKey = "md_video_height";
|
||||
static const char * mediaTypeKey = "md_title_mediatype";
|
||||
static const char * pixelWidthKey = "md_video_pixel_width";
|
||||
static const char * pixelHeightKey = "md_video_pixel_height";
|
||||
static const char * seekableKey = "md_title_seekable";
|
||||
|
||||
static const int mediaTypeAudioFlag = 4;
|
||||
static const int mediaTypeVideoFlag = 2;
|
||||
|
||||
bool MmRendererMetaData::parse(const QString &contextName)
|
||||
{
|
||||
clear();
|
||||
QString fileName =
|
||||
QString("/pps/services/multimedia/renderer/context/%1/metadata").arg(contextName);
|
||||
|
||||
// In newer OS versions, the filename is "metadata0", not metadata, so try both.
|
||||
if (!QFile::exists(fileName))
|
||||
fileName += '0';
|
||||
|
||||
QFile metaDataFile(fileName);
|
||||
if (!metaDataFile.open(QFile::ReadOnly)) {
|
||||
qWarning() << "Unable to open media metadata file" << fileName << ":"
|
||||
<< metaDataFile.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString separator("::");
|
||||
QTextStream stream(&metaDataFile);
|
||||
Q_FOREVER {
|
||||
const QString line = stream.readLine();
|
||||
if (line.isNull())
|
||||
break;
|
||||
|
||||
const int separatorPos = line.indexOf(separator);
|
||||
if (separatorPos != -1) {
|
||||
const QString key = line.left(separatorPos);
|
||||
const QString value = line.mid(separatorPos + separator.length());
|
||||
|
||||
if (key == durationKey)
|
||||
m_duration = value.toLongLong();
|
||||
else if (key == widthKey)
|
||||
m_width = value.toInt();
|
||||
else if (key == heightKey)
|
||||
m_height = value.toInt();
|
||||
else if (key == mediaTypeKey)
|
||||
m_mediaType = value.toInt();
|
||||
else if (key == pixelWidthKey)
|
||||
m_pixelWidth = value.toFloat();
|
||||
else if (key == pixelHeightKey)
|
||||
m_pixelHeight = value.toFloat();
|
||||
else if (key == titleKey)
|
||||
m_title = value;
|
||||
else if (key == seekableKey)
|
||||
m_seekable = !(value == QLatin1String("0"));
|
||||
else if (key == artistKey)
|
||||
m_artist = value;
|
||||
else if (key == commentKey)
|
||||
m_comment = value;
|
||||
else if (key == genreKey)
|
||||
m_genre = value;
|
||||
else if (key == yearKey)
|
||||
m_year = value.toInt();
|
||||
else if (key == bitRateKey)
|
||||
m_audioBitRate = value.toInt();
|
||||
else if (key == sampleKey)
|
||||
m_sampleRate = value.toInt();
|
||||
else if (key == albumKey)
|
||||
m_album = value;
|
||||
else if (key == trackKey)
|
||||
m_track = value.toInt();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MmRendererMetaData::clear()
|
||||
{
|
||||
m_duration = 0;
|
||||
m_height = 0;
|
||||
m_width = 0;
|
||||
m_mediaType = -1;
|
||||
m_pixelWidth = 1;
|
||||
m_pixelHeight = 1;
|
||||
m_seekable = true;
|
||||
m_title.clear();
|
||||
m_artist.clear();
|
||||
m_comment.clear();
|
||||
m_genre.clear();
|
||||
m_year = 0;
|
||||
m_audioBitRate = 0;
|
||||
m_sampleRate = 0;
|
||||
m_album.clear();
|
||||
m_track = 0;
|
||||
}
|
||||
|
||||
qlonglong MmRendererMetaData::duration() const
|
||||
{
|
||||
return m_duration;
|
||||
}
|
||||
|
||||
// Handling of pixel aspect ratio
|
||||
//
|
||||
// If the pixel aspect ratio is different from 1:1, it means the video needs to be stretched in
|
||||
// order to look natural.
|
||||
// For example, if the pixel width is 2, and the pixel height is 1, it means a video of 300x200
|
||||
// pixels needs to be displayed as 600x200 to look correct.
|
||||
// In order to support this the easiest way, we simply pretend that the actual size of the video
|
||||
// is 600x200, which will cause the video to be displayed in an aspect ratio of 3:1 instead of 3:2,
|
||||
// and therefore look correct.
|
||||
|
||||
int MmRendererMetaData::height() const
|
||||
{
|
||||
return m_height * m_pixelHeight;
|
||||
}
|
||||
|
||||
int MmRendererMetaData::width() const
|
||||
{
|
||||
return m_width * m_pixelWidth;
|
||||
}
|
||||
|
||||
bool MmRendererMetaData::hasVideo() const
|
||||
{
|
||||
// By default, assume no video if we can't extract the information
|
||||
if (m_mediaType == -1)
|
||||
return false;
|
||||
|
||||
return (m_mediaType & mediaTypeVideoFlag);
|
||||
}
|
||||
|
||||
bool MmRendererMetaData::hasAudio() const
|
||||
{
|
||||
// By default, assume audio only if we can't extract the information
|
||||
if (m_mediaType == -1)
|
||||
return true;
|
||||
|
||||
return (m_mediaType & mediaTypeAudioFlag);
|
||||
}
|
||||
|
||||
QString MmRendererMetaData::title() const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
bool MmRendererMetaData::isSeekable() const
|
||||
{
|
||||
return m_seekable;
|
||||
}
|
||||
|
||||
QString MmRendererMetaData::artist() const
|
||||
{
|
||||
return m_artist;
|
||||
}
|
||||
|
||||
QString MmRendererMetaData::comment() const
|
||||
{
|
||||
return m_comment;
|
||||
}
|
||||
|
||||
QString MmRendererMetaData::genre() const
|
||||
{
|
||||
return m_genre;
|
||||
}
|
||||
|
||||
int MmRendererMetaData::year() const
|
||||
{
|
||||
return m_year;
|
||||
}
|
||||
|
||||
QString MmRendererMetaData::mediaType() const
|
||||
{
|
||||
if (hasVideo())
|
||||
return QLatin1String("video");
|
||||
else if (hasAudio())
|
||||
return QLatin1String("audio");
|
||||
else
|
||||
return QString();
|
||||
}
|
||||
|
||||
int MmRendererMetaData::audioBitRate() const
|
||||
{
|
||||
return m_audioBitRate;
|
||||
}
|
||||
|
||||
int MmRendererMetaData::sampleRate() const
|
||||
{
|
||||
return m_sampleRate;
|
||||
}
|
||||
|
||||
QString MmRendererMetaData::album() const
|
||||
{
|
||||
return m_album;
|
||||
}
|
||||
|
||||
int MmRendererMetaData::track() const
|
||||
{
|
||||
return m_track;
|
||||
}
|
||||
|
||||
QSize MmRendererMetaData::resolution() const
|
||||
{
|
||||
return QSize(width(), height());
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
99
src/plugins/qnx/mediaplayer/mmrenderermetadata.h
Normal file
99
src/plugins/qnx/mediaplayer/mmrenderermetadata.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 MMRENDERERMETADATA_H
|
||||
#define MMRENDERERMETADATA_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/QSize>
|
||||
#include <QtCore/QString>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class MmRendererMetaData
|
||||
{
|
||||
public:
|
||||
MmRendererMetaData();
|
||||
bool parse(const QString &contextName);
|
||||
void clear();
|
||||
|
||||
// Duration in milliseconds
|
||||
qlonglong duration() const;
|
||||
|
||||
int height() const;
|
||||
int width() const;
|
||||
bool hasVideo() const;
|
||||
bool hasAudio() const;
|
||||
bool isSeekable() const;
|
||||
|
||||
QString title() const;
|
||||
QString artist() const;
|
||||
QString comment() const;
|
||||
QString genre() const;
|
||||
int year() const;
|
||||
QString mediaType() const;
|
||||
int audioBitRate() const;
|
||||
int sampleRate() const;
|
||||
QString album() const;
|
||||
int track() const;
|
||||
QSize resolution() const;
|
||||
|
||||
private:
|
||||
qlonglong m_duration;
|
||||
int m_height;
|
||||
int m_width;
|
||||
int m_mediaType;
|
||||
float m_pixelWidth;
|
||||
float m_pixelHeight;
|
||||
bool m_seekable;
|
||||
QString m_title;
|
||||
QString m_artist;
|
||||
QString m_comment;
|
||||
QString m_genre;
|
||||
int m_year;
|
||||
int m_audioBitRate;
|
||||
int m_sampleRate;
|
||||
QString m_album;
|
||||
int m_track;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
170
src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp
Normal file
170
src/plugins/qnx/mediaplayer/mmrenderermetadatareadercontrol.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "mmrenderermetadatareadercontrol.h"
|
||||
#include <QtMultimedia/qmediametadata.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
MmRendererMetaDataReaderControl::MmRendererMetaDataReaderControl(QObject *parent)
|
||||
: QMetaDataReaderControl(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool MmRendererMetaDataReaderControl::isMetaDataAvailable() const
|
||||
{
|
||||
return !availableMetaData().isEmpty();
|
||||
}
|
||||
|
||||
QVariant MmRendererMetaDataReaderControl::metaData(const QString &key) const
|
||||
{
|
||||
if (key == QMediaMetaData::Title)
|
||||
return m_metaData.title();
|
||||
else if (key == QMediaMetaData::Author)
|
||||
return m_metaData.artist();
|
||||
else if (key == QMediaMetaData::Comment)
|
||||
return m_metaData.comment();
|
||||
else if (key == QMediaMetaData::Genre)
|
||||
return m_metaData.genre();
|
||||
else if (key == QMediaMetaData::Year)
|
||||
return m_metaData.year();
|
||||
else if (key == QMediaMetaData::MediaType)
|
||||
return m_metaData.mediaType();
|
||||
else if (key == QMediaMetaData::Duration)
|
||||
return m_metaData.duration();
|
||||
else if (key == QMediaMetaData::AudioBitRate)
|
||||
return m_metaData.audioBitRate();
|
||||
else if (key == QMediaMetaData::SampleRate)
|
||||
return m_metaData.sampleRate();
|
||||
else if (key == QMediaMetaData::AlbumTitle)
|
||||
return m_metaData.album();
|
||||
else if (key == QMediaMetaData::TrackNumber)
|
||||
return m_metaData.track();
|
||||
else if (key == QMediaMetaData::Resolution)
|
||||
return m_metaData.resolution();
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QStringList MmRendererMetaDataReaderControl::availableMetaData() const
|
||||
{
|
||||
QStringList metaData;
|
||||
|
||||
if (!m_metaData.title().isEmpty())
|
||||
metaData << QMediaMetaData::Title;
|
||||
if (!m_metaData.artist().isEmpty())
|
||||
metaData << QMediaMetaData::Author;
|
||||
if (!m_metaData.comment().isEmpty())
|
||||
metaData << QMediaMetaData::Comment;
|
||||
if (!m_metaData.genre().isEmpty())
|
||||
metaData << QMediaMetaData::Genre;
|
||||
if (m_metaData.year() != 0)
|
||||
metaData << QMediaMetaData::Year;
|
||||
if (!m_metaData.mediaType().isEmpty())
|
||||
metaData << QMediaMetaData::MediaType;
|
||||
if (m_metaData.duration() != 0)
|
||||
metaData << QMediaMetaData::Duration;
|
||||
if (m_metaData.audioBitRate() != 0)
|
||||
metaData << QMediaMetaData::AudioBitRate;
|
||||
if (m_metaData.sampleRate() != 0)
|
||||
metaData << QMediaMetaData::SampleRate;
|
||||
if (!m_metaData.album().isEmpty())
|
||||
metaData << QMediaMetaData::AlbumTitle;
|
||||
if (m_metaData.track() != 0)
|
||||
metaData << QMediaMetaData::TrackNumber;
|
||||
if (m_metaData.resolution().isValid())
|
||||
metaData << QMediaMetaData::Resolution;
|
||||
|
||||
return metaData;
|
||||
}
|
||||
|
||||
void MmRendererMetaDataReaderControl::setMetaData(const MmRendererMetaData &data)
|
||||
{
|
||||
const MmRendererMetaData oldMetaData = m_metaData;
|
||||
const bool oldMetaDataAvailable = isMetaDataAvailable();
|
||||
|
||||
m_metaData = data;
|
||||
|
||||
bool changed = false;
|
||||
if (m_metaData.title() != oldMetaData.title()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::Title, m_metaData.title());
|
||||
} else if (m_metaData.artist() != oldMetaData.artist()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::Author, m_metaData.artist());
|
||||
} else if (m_metaData.comment() != oldMetaData.comment()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::Comment, m_metaData.comment());
|
||||
} else if (m_metaData.genre() != oldMetaData.genre()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::Genre, m_metaData.genre());
|
||||
} else if (m_metaData.year() != oldMetaData.year()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::Year, m_metaData.year());
|
||||
} else if (m_metaData.mediaType() != oldMetaData.mediaType()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::MediaType, m_metaData.mediaType());
|
||||
} else if (m_metaData.duration() != oldMetaData.duration()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::Duration, m_metaData.duration());
|
||||
} else if (m_metaData.audioBitRate() != oldMetaData.audioBitRate()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::AudioBitRate, m_metaData.audioBitRate());
|
||||
} else if (m_metaData.sampleRate() != oldMetaData.sampleRate()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::SampleRate, m_metaData.sampleRate());
|
||||
} else if (m_metaData.album() != oldMetaData.album()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::AlbumTitle, m_metaData.album());
|
||||
} else if (m_metaData.track() != oldMetaData.track()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::TrackNumber, m_metaData.track());
|
||||
} else if (m_metaData.resolution() != oldMetaData.resolution()) {
|
||||
changed = true;
|
||||
emit metaDataChanged(QMediaMetaData::Resolution, m_metaData.resolution());
|
||||
}
|
||||
|
||||
if (changed)
|
||||
emit metaDataChanged();
|
||||
|
||||
const bool metaDataAvailable = isMetaDataAvailable();
|
||||
if (metaDataAvailable != oldMetaDataAvailable)
|
||||
emit metaDataAvailableChanged(metaDataAvailable);
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 MMRENDERERMETADATAREADERCONTROL_H
|
||||
#define MMRENDERERMETADATAREADERCONTROL_H
|
||||
|
||||
#include "mmrenderermetadata.h"
|
||||
#include <qmetadatareadercontrol.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class MmRendererMetaDataReaderControl : public QMetaDataReaderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MmRendererMetaDataReaderControl(QObject *parent = 0);
|
||||
|
||||
bool isMetaDataAvailable() const Q_DECL_OVERRIDE;
|
||||
|
||||
QVariant metaData(const QString &key) const Q_DECL_OVERRIDE;
|
||||
QStringList availableMetaData() const Q_DECL_OVERRIDE;
|
||||
|
||||
void setMetaData(const MmRendererMetaData &data);
|
||||
|
||||
private:
|
||||
MmRendererMetaData m_metaData;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,158 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "mmrendererplayervideorenderercontrol.h"
|
||||
|
||||
#include "windowgrabber.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QVideoSurfaceFormat>
|
||||
|
||||
#include <mm/renderer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static int winIdCounter = 0;
|
||||
|
||||
MmRendererPlayerVideoRendererControl::MmRendererPlayerVideoRendererControl(QObject *parent)
|
||||
: QVideoRendererControl(parent)
|
||||
, m_windowGrabber(new WindowGrabber(this))
|
||||
, m_context(0)
|
||||
, m_videoId(-1)
|
||||
{
|
||||
connect(m_windowGrabber, SIGNAL(frameGrabbed(QImage)), SLOT(frameGrabbed(QImage)));
|
||||
}
|
||||
|
||||
MmRendererPlayerVideoRendererControl::~MmRendererPlayerVideoRendererControl()
|
||||
{
|
||||
detachDisplay();
|
||||
}
|
||||
|
||||
QAbstractVideoSurface *MmRendererPlayerVideoRendererControl::surface() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
void MmRendererPlayerVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
|
||||
{
|
||||
m_surface = QPointer<QAbstractVideoSurface>(surface);
|
||||
}
|
||||
|
||||
void MmRendererPlayerVideoRendererControl::attachDisplay(mmr_context_t *context)
|
||||
{
|
||||
if (m_videoId != -1) {
|
||||
qWarning() << "MmRendererPlayerVideoRendererControl: Video output already attached!";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!context) {
|
||||
qWarning() << "MmRendererPlayerVideoRendererControl: No media player context!";
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArray windowGroupId = m_windowGrabber->windowGroupId();
|
||||
if (windowGroupId.isEmpty()) {
|
||||
qWarning() << "MmRendererPlayerVideoRendererControl: Unable to find window group";
|
||||
return;
|
||||
}
|
||||
|
||||
const QString windowName = QStringLiteral("MmRendererPlayerVideoRendererControl_%1_%2")
|
||||
.arg(winIdCounter++)
|
||||
.arg(QCoreApplication::applicationPid());
|
||||
|
||||
m_windowGrabber->setWindowId(windowName.toLatin1());
|
||||
|
||||
// Start with an invisible window, because we just want to grab the frames from it.
|
||||
const QString videoDeviceUrl = QStringLiteral("screen:?winid=%1&wingrp=%2&initflags=invisible&nodstviewport=1")
|
||||
.arg(windowName)
|
||||
.arg(QString::fromLatin1(windowGroupId));
|
||||
|
||||
m_videoId = mmr_output_attach(context, videoDeviceUrl.toLatin1(), "video");
|
||||
if (m_videoId == -1) {
|
||||
qWarning() << "mmr_output_attach() for video failed";
|
||||
return;
|
||||
}
|
||||
|
||||
m_context = context;
|
||||
}
|
||||
|
||||
void MmRendererPlayerVideoRendererControl::detachDisplay()
|
||||
{
|
||||
m_windowGrabber->stop();
|
||||
|
||||
if (m_surface)
|
||||
m_surface->stop();
|
||||
|
||||
if (m_context && m_videoId != -1)
|
||||
mmr_output_detach(m_context, m_videoId);
|
||||
|
||||
m_context = 0;
|
||||
m_videoId = -1;
|
||||
}
|
||||
|
||||
void MmRendererPlayerVideoRendererControl::pause()
|
||||
{
|
||||
m_windowGrabber->pause();
|
||||
}
|
||||
|
||||
void MmRendererPlayerVideoRendererControl::resume()
|
||||
{
|
||||
m_windowGrabber->resume();
|
||||
}
|
||||
|
||||
void MmRendererPlayerVideoRendererControl::frameGrabbed(const QImage &frame)
|
||||
{
|
||||
if (m_surface) {
|
||||
if (!m_surface->isActive()) {
|
||||
m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_ARGB32));
|
||||
} else {
|
||||
if (m_surface->surfaceFormat().frameSize() != frame.size()) {
|
||||
m_surface->stop();
|
||||
m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_ARGB32));
|
||||
}
|
||||
}
|
||||
|
||||
m_surface->present(frame.copy());
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 MMRENDERERPLAYERVIDEORENDERERCONTROL_H
|
||||
#define MMRENDERERPLAYERVIDEORENDERERCONTROL_H
|
||||
|
||||
#include <QPointer>
|
||||
#include <qabstractvideosurface.h>
|
||||
#include <qvideorenderercontrol.h>
|
||||
|
||||
typedef struct mmr_context mmr_context_t;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class WindowGrabber;
|
||||
|
||||
class MmRendererPlayerVideoRendererControl : public QVideoRendererControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MmRendererPlayerVideoRendererControl(QObject *parent = 0);
|
||||
~MmRendererPlayerVideoRendererControl();
|
||||
|
||||
QAbstractVideoSurface *surface() const Q_DECL_OVERRIDE;
|
||||
void setSurface(QAbstractVideoSurface *surface) Q_DECL_OVERRIDE;
|
||||
|
||||
// Called by media control
|
||||
void attachDisplay(mmr_context_t *context);
|
||||
void detachDisplay();
|
||||
void pause();
|
||||
void resume();
|
||||
|
||||
private Q_SLOTS:
|
||||
void frameGrabbed(const QImage &frame);
|
||||
|
||||
private:
|
||||
QPointer<QAbstractVideoSurface> m_surface;
|
||||
|
||||
WindowGrabber* m_windowGrabber;
|
||||
mmr_context_t *m_context;
|
||||
|
||||
int m_videoId;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
129
src/plugins/qnx/mediaplayer/mmrendererutil.cpp
Normal file
129
src/plugins/qnx/mediaplayer/mmrendererutil.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "mmrendererutil.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QString>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#include <mm/renderer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
struct MmError {
|
||||
int errorCode;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#define MM_ERROR_ENTRY(error) { error, #error }
|
||||
static const MmError mmErrors[] = {
|
||||
MM_ERROR_ENTRY(MMR_ERROR_NONE),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_UNKNOWN ),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_INVALID_PARAMETER ),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_INVALID_STATE),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_UNSUPPORTED_VALUE),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_UNSUPPORTED_MEDIA_TYPE),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_MEDIA_PROTECTED),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_UNSUPPORTED_OPERATION),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_READ),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_WRITE),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_MEDIA_UNAVAILABLE),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_MEDIA_CORRUPTED),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_OUTPUT_UNAVAILABLE),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_NO_MEMORY),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_RESOURCE_UNAVAILABLE),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_MEDIA_DRM_NO_RIGHTS),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_CORRUPTED_DATA_STORE),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_OUTPUT_PROTECTION),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_HDMI),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_DISPLAYPORT),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_DVI),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_ANALOG_VIDEO),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_ANALOG_AUDIO),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_TOSLINK),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_SPDIF),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_BLUETOOTH),
|
||||
MM_ERROR_ENTRY(MMR_ERROR_DRM_OPL_WIRELESSHD),
|
||||
};
|
||||
static const unsigned int numMmErrors = sizeof(mmErrors) / sizeof(MmError);
|
||||
|
||||
QString mmErrorMessage(const QString &msg, mmr_context_t *context, int *errorCode)
|
||||
{
|
||||
const mmr_error_info_t * const mmError = mmr_error_info(context);
|
||||
|
||||
if (errorCode)
|
||||
*errorCode = mmError->error_code;
|
||||
|
||||
if (mmError->error_code < numMmErrors) {
|
||||
return QString("%1: %2 (code %3)").arg(msg).arg(mmErrors[mmError->error_code].name)
|
||||
.arg(mmError->error_code);
|
||||
} else {
|
||||
return QString("%1: Unknown error code %2").arg(msg).arg(mmError->error_code);
|
||||
}
|
||||
}
|
||||
|
||||
bool checkForDrmPermission()
|
||||
{
|
||||
QDir sandboxDir = QDir::home(); // always returns 'data' directory
|
||||
sandboxDir.cdUp(); // change to app sandbox directory
|
||||
|
||||
QFile file(sandboxDir.filePath("app/native/bar-descriptor.xml"));
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qWarning() << "checkForDrmPermission: Unable to open bar-descriptor.xml";
|
||||
return false;
|
||||
}
|
||||
|
||||
QXmlStreamReader reader(&file);
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNextStartElement();
|
||||
if (reader.name() == QLatin1String("action")
|
||||
|| reader.name() == QLatin1String("permission")) {
|
||||
if (reader.readElementText().trimmed() == QLatin1String("access_protected_media"))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
58
src/plugins/qnx/mediaplayer/mmrendererutil.h
Normal file
58
src/plugins/qnx/mediaplayer/mmrendererutil.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 MMRENDERERUTIL_H
|
||||
#define MMRENDERERUTIL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
typedef struct mmr_context mmr_context_t;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QString;
|
||||
|
||||
QString mmErrorMessage(const QString &msg, mmr_context_t *context, int * errorCode = 0);
|
||||
|
||||
bool checkForDrmPermission();
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
414
src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp
Normal file
414
src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.cpp
Normal file
@@ -0,0 +1,414 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "mmrenderervideowindowcontrol.h"
|
||||
#include "mmrendererutil.h"
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QtGui/qpa/qplatformnativeinterface.h>
|
||||
#include <QtGui/qscreen.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
#include <mm/renderer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static int winIdCounter = 0;
|
||||
|
||||
MmRendererVideoWindowControl::MmRendererVideoWindowControl(QObject *parent)
|
||||
: QVideoWindowControl(parent),
|
||||
m_videoId(-1),
|
||||
m_winId(0),
|
||||
m_context(0),
|
||||
m_fullscreen(false),
|
||||
m_aspectRatioMode(Qt::IgnoreAspectRatio),
|
||||
m_window(0),
|
||||
m_hue(0),
|
||||
m_brightness(0),
|
||||
m_contrast(0),
|
||||
m_saturation(0)
|
||||
{
|
||||
}
|
||||
|
||||
MmRendererVideoWindowControl::~MmRendererVideoWindowControl()
|
||||
{
|
||||
}
|
||||
|
||||
WId MmRendererVideoWindowControl::winId() const
|
||||
{
|
||||
return m_winId;
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::setWinId(WId id)
|
||||
{
|
||||
m_winId = id;
|
||||
}
|
||||
|
||||
QRect MmRendererVideoWindowControl::displayRect() const
|
||||
{
|
||||
return m_displayRect ;
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::setDisplayRect(const QRect &rect)
|
||||
{
|
||||
if (m_displayRect != rect) {
|
||||
m_displayRect = rect;
|
||||
updateVideoPosition();
|
||||
}
|
||||
}
|
||||
|
||||
bool MmRendererVideoWindowControl::isFullScreen() const
|
||||
{
|
||||
return m_fullscreen;
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::setFullScreen(bool fullScreen)
|
||||
{
|
||||
if (m_fullscreen != fullScreen) {
|
||||
m_fullscreen = fullScreen;
|
||||
updateVideoPosition();
|
||||
emit fullScreenChanged(m_fullscreen);
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::repaint()
|
||||
{
|
||||
// Nothing we can or should do here
|
||||
}
|
||||
|
||||
QSize MmRendererVideoWindowControl::nativeSize() const
|
||||
{
|
||||
return QSize(m_metaData.width(), m_metaData.height());
|
||||
}
|
||||
|
||||
Qt::AspectRatioMode MmRendererVideoWindowControl::aspectRatioMode() const
|
||||
{
|
||||
return m_aspectRatioMode;
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode)
|
||||
{
|
||||
m_aspectRatioMode = mode;
|
||||
}
|
||||
|
||||
int MmRendererVideoWindowControl::brightness() const
|
||||
{
|
||||
return m_brightness;
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::setBrightness(int brightness)
|
||||
{
|
||||
if (m_brightness != brightness) {
|
||||
m_brightness = brightness;
|
||||
updateBrightness();
|
||||
emit brightnessChanged(m_brightness);
|
||||
}
|
||||
}
|
||||
|
||||
int MmRendererVideoWindowControl::contrast() const
|
||||
{
|
||||
return m_contrast;
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::setContrast(int contrast)
|
||||
{
|
||||
if (m_contrast != contrast) {
|
||||
m_contrast = contrast;
|
||||
updateContrast();
|
||||
emit contrastChanged(m_contrast);
|
||||
}
|
||||
}
|
||||
|
||||
int MmRendererVideoWindowControl::hue() const
|
||||
{
|
||||
return m_hue;
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::setHue(int hue)
|
||||
{
|
||||
if (m_hue != hue) {
|
||||
m_hue = hue;
|
||||
updateHue();
|
||||
emit hueChanged(m_hue);
|
||||
}
|
||||
}
|
||||
|
||||
int MmRendererVideoWindowControl::saturation() const
|
||||
{
|
||||
return m_saturation;
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::setSaturation(int saturation)
|
||||
{
|
||||
if (m_saturation != saturation) {
|
||||
m_saturation = saturation;
|
||||
updateSaturation();
|
||||
emit saturationChanged(m_saturation);
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::attachDisplay(mmr_context_t *context)
|
||||
{
|
||||
if (m_videoId != -1) {
|
||||
qDebug() << "MmRendererVideoWindowControl: Video output already attached!";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!context) {
|
||||
qDebug() << "MmRendererVideoWindowControl: No media player context!";
|
||||
return;
|
||||
}
|
||||
|
||||
QWindow *window = findWindow(m_winId);
|
||||
if (!window) {
|
||||
qDebug() << "MmRendererVideoWindowControl: No video window!";
|
||||
return;
|
||||
}
|
||||
|
||||
QPlatformNativeInterface * const nativeInterface = QGuiApplication::platformNativeInterface();
|
||||
if (!nativeInterface) {
|
||||
qDebug() << "MmRendererVideoWindowControl: Unable to get platform native interface";
|
||||
return;
|
||||
}
|
||||
|
||||
const char * const groupNameData = static_cast<const char *>(
|
||||
nativeInterface->nativeResourceForWindow("windowGroup", window));
|
||||
if (!groupNameData) {
|
||||
qDebug() << "MmRendererVideoWindowControl: Unable to find window group for window" << window;
|
||||
return;
|
||||
}
|
||||
|
||||
const QString groupName = QString::fromLatin1(groupNameData);
|
||||
m_windowName = QString("MmRendererVideoWindowControl_%1_%2").arg(winIdCounter++)
|
||||
.arg(QCoreApplication::applicationPid());
|
||||
|
||||
nativeInterface->setWindowProperty(window->handle(),
|
||||
QStringLiteral("mmRendererWindowName"), m_windowName);
|
||||
|
||||
// Start with an invisible window. If it would be visible right away, it would be at the wrong
|
||||
// position, and we can only change the position once we get the window handle.
|
||||
const QString videoDeviceUrl =
|
||||
QString("screen:?winid=%1&wingrp=%2&initflags=invisible&nodstviewport=1").arg(m_windowName).arg(groupName);
|
||||
|
||||
m_videoId = mmr_output_attach(context, videoDeviceUrl.toLatin1(), "video");
|
||||
if (m_videoId == -1) {
|
||||
qDebug() << mmErrorMessage("mmr_output_attach() for video failed", context);
|
||||
return;
|
||||
}
|
||||
|
||||
m_context = context;
|
||||
updateVideoPosition();
|
||||
updateHue();
|
||||
updateContrast();
|
||||
updateBrightness();
|
||||
updateSaturation();
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::updateVideoPosition()
|
||||
{
|
||||
QWindow * const window = findWindow(m_winId);
|
||||
if (m_context && m_videoId != -1 && window) {
|
||||
QPoint topLeft = m_fullscreen ?
|
||||
QPoint(0,0) :
|
||||
window->mapToGlobal(m_displayRect.topLeft());
|
||||
|
||||
QScreen * const screen = window->screen();
|
||||
int width = m_fullscreen ?
|
||||
screen->size().width() :
|
||||
m_displayRect.width();
|
||||
int height = m_fullscreen ?
|
||||
screen->size().height() :
|
||||
m_displayRect.height();
|
||||
|
||||
if (m_metaData.hasVideo()) { // We need the source size to do aspect ratio scaling
|
||||
const qreal sourceRatio = m_metaData.width() / static_cast<float>(m_metaData.height());
|
||||
const qreal targetRatio = width / static_cast<float>(height);
|
||||
|
||||
if (m_aspectRatioMode == Qt::KeepAspectRatio) {
|
||||
if (targetRatio < sourceRatio) {
|
||||
// Need to make height smaller
|
||||
const int newHeight = width / sourceRatio;
|
||||
const int heightDiff = height - newHeight;
|
||||
topLeft.ry() += heightDiff / 2;
|
||||
height = newHeight;
|
||||
} else {
|
||||
// Need to make width smaller
|
||||
const int newWidth = sourceRatio * height;
|
||||
const int widthDiff = width - newWidth;
|
||||
topLeft.rx() += widthDiff / 2;
|
||||
width = newWidth;
|
||||
}
|
||||
|
||||
} else if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) {
|
||||
if (targetRatio < sourceRatio) {
|
||||
// Need to make width larger
|
||||
const int newWidth = sourceRatio * height;
|
||||
const int widthDiff = newWidth - width;
|
||||
topLeft.rx() -= widthDiff / 2;
|
||||
width = newWidth;
|
||||
} else {
|
||||
// Need to make height larger
|
||||
const int newHeight = width / sourceRatio;
|
||||
const int heightDiff = newHeight - height;
|
||||
topLeft.ry() -= heightDiff / 2;
|
||||
height = newHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_window != 0) {
|
||||
const int position[2] = { topLeft.x(), topLeft.y() };
|
||||
const int size[2] = { width, height };
|
||||
const int visible = m_displayRect.isValid();
|
||||
if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, position) != 0)
|
||||
perror("Setting video position failed");
|
||||
if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, size) != 0)
|
||||
perror("Setting video size failed");
|
||||
if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &visible) != 0)
|
||||
perror("Setting video visibility failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::updateBrightness()
|
||||
{
|
||||
if (m_window != 0) {
|
||||
const int backendValue = m_brightness * 2.55f;
|
||||
if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BRIGHTNESS, &backendValue) != 0)
|
||||
perror("Setting brightness failed");
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::updateContrast()
|
||||
{
|
||||
if (m_window != 0) {
|
||||
const int backendValue = m_contrast * 1.27f;
|
||||
if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_CONTRAST, &backendValue) != 0)
|
||||
perror("Setting contrast failed");
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::updateHue()
|
||||
{
|
||||
if (m_window != 0) {
|
||||
const int backendValue = m_hue * 1.27f;
|
||||
if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_HUE, &backendValue) != 0)
|
||||
perror("Setting hue failed");
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::updateSaturation()
|
||||
{
|
||||
if (m_window != 0) {
|
||||
const int backendValue = m_saturation * 1.27f;
|
||||
if (screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SATURATION, &backendValue) != 0)
|
||||
perror("Setting saturation failed");
|
||||
}
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::detachDisplay()
|
||||
{
|
||||
if (m_context && m_videoId != -1)
|
||||
mmr_output_detach(m_context, m_videoId);
|
||||
|
||||
m_context = 0;
|
||||
m_videoId = -1;
|
||||
m_metaData.clear();
|
||||
m_windowName.clear();
|
||||
m_window = 0;
|
||||
m_hue = 0;
|
||||
m_brightness = 0;
|
||||
m_contrast = 0;
|
||||
m_saturation = 0;
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::setMetaData(const MmRendererMetaData &metaData)
|
||||
{
|
||||
m_metaData = metaData;
|
||||
emit nativeSizeChanged();
|
||||
|
||||
// To handle the updated source size data
|
||||
updateVideoPosition();
|
||||
}
|
||||
|
||||
void MmRendererVideoWindowControl::screenEventHandler(const screen_event_t &screen_event)
|
||||
{
|
||||
int eventType;
|
||||
if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
|
||||
perror("MmRendererVideoWindowControl: Failed to query screen event type");
|
||||
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("MmRendererVideoWindowControl: 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("MmRendererVideoWindowControl: 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("MmRendererVideoWindowControl: Failed to make window visible");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QWindow *MmRendererVideoWindowControl::findWindow(WId id) const
|
||||
{
|
||||
Q_FOREACH (QWindow *window, QGuiApplication::allWindows())
|
||||
if (window->winId() == id)
|
||||
return window;
|
||||
return 0;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
120
src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.h
Normal file
120
src/plugins/qnx/mediaplayer/mmrenderervideowindowcontrol.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 MMRENDERERVIDEOWINDOWCONTROL_H
|
||||
#define MMRENDERERVIDEOWINDOWCONTROL_H
|
||||
|
||||
#include "mmrenderermetadata.h"
|
||||
#include <qvideowindowcontrol.h>
|
||||
#include <screen/screen.h>
|
||||
|
||||
typedef struct mmr_context mmr_context_t;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class MmRendererVideoWindowControl : public QVideoWindowControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MmRendererVideoWindowControl(QObject *parent = 0);
|
||||
~MmRendererVideoWindowControl();
|
||||
|
||||
WId winId() const Q_DECL_OVERRIDE;
|
||||
void setWinId(WId id) Q_DECL_OVERRIDE;
|
||||
|
||||
QRect displayRect() const Q_DECL_OVERRIDE;
|
||||
void setDisplayRect(const QRect &rect) Q_DECL_OVERRIDE;
|
||||
|
||||
bool isFullScreen() const Q_DECL_OVERRIDE;
|
||||
void setFullScreen(bool fullScreen) Q_DECL_OVERRIDE;
|
||||
|
||||
void repaint() Q_DECL_OVERRIDE;
|
||||
|
||||
QSize nativeSize() const Q_DECL_OVERRIDE;
|
||||
|
||||
Qt::AspectRatioMode aspectRatioMode() const Q_DECL_OVERRIDE;
|
||||
void setAspectRatioMode(Qt::AspectRatioMode mode) Q_DECL_OVERRIDE;
|
||||
|
||||
int brightness() const Q_DECL_OVERRIDE;
|
||||
void setBrightness(int brightness) Q_DECL_OVERRIDE;
|
||||
|
||||
int contrast() const Q_DECL_OVERRIDE;
|
||||
void setContrast(int contrast) Q_DECL_OVERRIDE;
|
||||
|
||||
int hue() const Q_DECL_OVERRIDE;
|
||||
void setHue(int hue) Q_DECL_OVERRIDE;
|
||||
|
||||
int saturation() const Q_DECL_OVERRIDE;
|
||||
void setSaturation(int saturation) Q_DECL_OVERRIDE;
|
||||
|
||||
//
|
||||
// Called by media control
|
||||
//
|
||||
void detachDisplay();
|
||||
void attachDisplay(mmr_context_t *context);
|
||||
void setMetaData(const MmRendererMetaData &metaData);
|
||||
void screenEventHandler(const screen_event_t &event);
|
||||
|
||||
private:
|
||||
QWindow *findWindow(WId id) const;
|
||||
void updateVideoPosition();
|
||||
void updateBrightness();
|
||||
void updateContrast();
|
||||
void updateHue();
|
||||
void updateSaturation();
|
||||
|
||||
int m_videoId;
|
||||
WId m_winId;
|
||||
QRect m_displayRect;
|
||||
mmr_context_t *m_context;
|
||||
bool m_fullscreen;
|
||||
MmRendererMetaData m_metaData;
|
||||
Qt::AspectRatioMode m_aspectRatioMode;
|
||||
QString m_windowName;
|
||||
screen_window_t m_window;
|
||||
int m_hue;
|
||||
int m_brightness;
|
||||
int m_contrast;
|
||||
int m_saturation;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
199
src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.cpp
Normal file
199
src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.cpp
Normal 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 "mmrenderervideowindowcontrol.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)
|
||||
: MmRendererMediaPlayerControl(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 (MmRendererVideoWindowControl *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
|
||||
75
src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.h
Normal file
75
src/plugins/qnx/mediaplayer/ppsmediaplayercontrol.h
Normal 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 "mmrenderermediaplayercontrol.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSocketNotifier;
|
||||
|
||||
class PpsMediaPlayerControl Q_DECL_FINAL : public MmRendererMediaPlayerControl
|
||||
{
|
||||
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
|
||||
Reference in New Issue
Block a user