diff options
10 files changed, 346 insertions, 17 deletions
diff --git a/src/plugins/blackberry/mediaplayer/bbmediaplayercontrol.cpp b/src/plugins/blackberry/mediaplayer/bbmediaplayercontrol.cpp index d664336d3..1ef68cb12 100644 --- a/src/plugins/blackberry/mediaplayer/bbmediaplayercontrol.cpp +++ b/src/plugins/blackberry/mediaplayer/bbmediaplayercontrol.cpp @@ -40,8 +40,9 @@ ****************************************************************************/ #include "bbmediaplayercontrol.h" #include "bbmetadatareadercontrol.h" -#include "bbvideowindowcontrol.h" +#include "bbplayervideorenderercontrol.h" #include "bbutil.h" +#include "bbvideowindowcontrol.h" #include <QtCore/qabstracteventdispatcher.h> #include <QtCore/qcoreapplication.h> #include <QtCore/qdir.h> @@ -182,8 +183,11 @@ void BbMediaPlayerControl::attach() return; } - if (m_videoControl) - m_videoControl->attachDisplay(m_context); + 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) { @@ -222,8 +226,10 @@ void BbMediaPlayerControl::detach() mmr_input_detach(m_context); m_inputAttached = false; } - if (m_videoControl) - m_videoControl->detachDisplay(); + 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; @@ -322,6 +328,15 @@ void BbMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status) void BbMediaPlayerControl::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); } @@ -511,9 +526,14 @@ void BbMediaPlayerControl::stop() stopInternal(StopMmRenderer); } -void BbMediaPlayerControl::setVideoControl(BbVideoWindowControl *videoControl) +void BbMediaPlayerControl::setVideoRendererControl(BbPlayerVideoRendererControl *videoControl) +{ + m_videoRendererControl = videoControl; +} + +void BbMediaPlayerControl::setVideoWindowControl(BbVideoWindowControl *videoControl) { - m_videoControl = videoControl; + m_videoWindowControl = videoControl; } void BbMediaPlayerControl::setMetaDataReaderControl(BbMetaDataReaderControl *metaDataReaderControl) @@ -532,8 +552,8 @@ bool BbMediaPlayerControl::nativeEventFilter(const QByteArray &eventType, void * bps_event_get_domain(event) != screen_get_domain())) return false; - if (m_videoControl) - m_videoControl->bpsEventHandler(event); + if (m_videoWindowControl) + m_videoWindowControl->bpsEventHandler(event); if (bps_event_get_domain(event) == mmrenderer_get_domain()) { if (bps_event_get_code(event) == MMRENDERER_STATE_CHANGE) { @@ -595,8 +615,8 @@ void BbMediaPlayerControl::updateMetaData() else m_metaData.clear(); - if (m_videoControl) - m_videoControl->setMetaData(m_metaData); + if (m_videoWindowControl) + m_videoWindowControl->setMetaData(m_metaData); if (m_metaDataReaderControl) m_metaDataReaderControl->setMetaData(m_metaData); diff --git a/src/plugins/blackberry/mediaplayer/bbmediaplayercontrol.h b/src/plugins/blackberry/mediaplayer/bbmediaplayercontrol.h index d825a21c0..a8a4a929c 100644 --- a/src/plugins/blackberry/mediaplayer/bbmediaplayercontrol.h +++ b/src/plugins/blackberry/mediaplayer/bbmediaplayercontrol.h @@ -55,6 +55,7 @@ typedef struct mmrenderer_monitor mmrenderer_monitor_t; QT_BEGIN_NAMESPACE class BbMetaDataReaderControl; +class BbPlayerVideoRendererControl; class BbVideoWindowControl; class BbMediaPlayerControl : public QMediaPlayerControl, public QAbstractNativeEventFilter @@ -99,7 +100,8 @@ public: void pause() Q_DECL_OVERRIDE; void stop() Q_DECL_OVERRIDE; - void setVideoControl(BbVideoWindowControl *videoControl); + void setVideoRendererControl(BbPlayerVideoRendererControl *videoControl); + void setVideoWindowControl(BbVideoWindowControl *videoControl); void setMetaDataReaderControl(BbMetaDataReaderControl *metaDataReaderControl); bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE; @@ -138,7 +140,8 @@ private: int m_volume; bool m_muted; qreal m_rate; - QPointer<BbVideoWindowControl> m_videoControl; + QPointer<BbPlayerVideoRendererControl> m_videoRendererControl; + QPointer<BbVideoWindowControl> m_videoWindowControl; QPointer<BbMetaDataReaderControl> m_metaDataReaderControl; BbMetaData m_metaData; int m_id; diff --git a/src/plugins/blackberry/mediaplayer/bbmediaplayerservice.cpp b/src/plugins/blackberry/mediaplayer/bbmediaplayerservice.cpp index 8c3e93445..5846cc020 100644 --- a/src/plugins/blackberry/mediaplayer/bbmediaplayerservice.cpp +++ b/src/plugins/blackberry/mediaplayer/bbmediaplayerservice.cpp @@ -42,23 +42,30 @@ #include "bbmediaplayercontrol.h" #include "bbmetadatareadercontrol.h" +#include "bbplayervideorenderercontrol.h" +#include "bbutil.h" #include "bbvideowindowcontrol.h" QT_BEGIN_NAMESPACE BbMediaPlayerService::BbMediaPlayerService(QObject *parent) : QMediaService(parent), + m_videoRendererControl(0), m_videoWindowControl(0), m_mediaPlayerControl(0), - m_metaDataReaderControl(0) + m_metaDataReaderControl(0), + m_appHasDrmPermission(false), + m_appHasDrmPermissionChecked(false) { } BbMediaPlayerService::~BbMediaPlayerService() { // Someone should have called releaseControl(), but better be safe + delete m_videoRendererControl; delete m_videoWindowControl; delete m_mediaPlayerControl; + delete m_metaDataReaderControl; } QMediaControl *BbMediaPlayerService::requestControl(const char *name) @@ -77,6 +84,25 @@ QMediaControl *BbMediaPlayerService::requestControl(const char *name) } 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 BbPlayerVideoRendererControl(); + updateControls(); + } + return m_videoRendererControl; + } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { if (!m_videoWindowControl) { m_videoWindowControl = new BbVideoWindowControl(); @@ -89,6 +115,8 @@ QMediaControl *BbMediaPlayerService::requestControl(const char *name) void BbMediaPlayerService::releaseControl(QMediaControl *control) { + if (control == m_videoRendererControl) + m_videoRendererControl = 0; if (control == m_videoWindowControl) m_videoWindowControl = 0; if (control == m_mediaPlayerControl) @@ -100,8 +128,11 @@ void BbMediaPlayerService::releaseControl(QMediaControl *control) void BbMediaPlayerService::updateControls() { + if (m_videoRendererControl && m_mediaPlayerControl) + m_mediaPlayerControl->setVideoRendererControl(m_videoRendererControl); + if (m_videoWindowControl && m_mediaPlayerControl) - m_mediaPlayerControl->setVideoControl(m_videoWindowControl); + m_mediaPlayerControl->setVideoWindowControl(m_videoWindowControl); if (m_metaDataReaderControl && m_mediaPlayerControl) m_mediaPlayerControl->setMetaDataReaderControl(m_metaDataReaderControl); diff --git a/src/plugins/blackberry/mediaplayer/bbmediaplayerservice.h b/src/plugins/blackberry/mediaplayer/bbmediaplayerservice.h index 7ace8830b..03aa7818f 100644 --- a/src/plugins/blackberry/mediaplayer/bbmediaplayerservice.h +++ b/src/plugins/blackberry/mediaplayer/bbmediaplayerservice.h @@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE class BbMediaPlayerControl; class BbMetaDataReaderControl; +class BbPlayerVideoRendererControl; class BbVideoWindowControl; class BbMediaPlayerService : public QMediaService @@ -63,9 +64,13 @@ public: private: void updateControls(); + QPointer<BbPlayerVideoRendererControl> m_videoRendererControl; QPointer<BbVideoWindowControl> m_videoWindowControl; QPointer<BbMediaPlayerControl> m_mediaPlayerControl; QPointer<BbMetaDataReaderControl> m_metaDataReaderControl; + + bool m_appHasDrmPermission : 1; + bool m_appHasDrmPermissionChecked : 1; }; QT_END_NAMESPACE diff --git a/src/plugins/blackberry/mediaplayer/bbplayervideorenderercontrol.cpp b/src/plugins/blackberry/mediaplayer/bbplayervideorenderercontrol.cpp new file mode 100644 index 000000000..096ae55ec --- /dev/null +++ b/src/plugins/blackberry/mediaplayer/bbplayervideorenderercontrol.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** 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 "bbplayervideorenderercontrol.h" + +#include "windowgrabber.h" + +#include <QCoreApplication> +#include <QDebug> +#include <QVideoSurfaceFormat> + +#include <mm/renderer.h> + +QT_BEGIN_NAMESPACE + +static int winIdCounter = 0; + +BbPlayerVideoRendererControl::BbPlayerVideoRendererControl(QObject *parent) + : QVideoRendererControl(parent) + , m_windowGrabber(new WindowGrabber(this)) + , m_context(0) + , m_videoId(-1) +{ + connect(m_windowGrabber, SIGNAL(frameGrabbed(QImage)), SLOT(frameGrabbed(QImage))); +} + +BbPlayerVideoRendererControl::~BbPlayerVideoRendererControl() +{ + detachDisplay(); +} + +QAbstractVideoSurface *BbPlayerVideoRendererControl::surface() const +{ + return m_surface; +} + +void BbPlayerVideoRendererControl::setSurface(QAbstractVideoSurface *surface) +{ + m_surface = QPointer<QAbstractVideoSurface>(surface); +} + +void BbPlayerVideoRendererControl::attachDisplay(mmr_context_t *context) +{ + if (m_videoId != -1) { + qWarning() << "BbPlayerVideoRendererControl: Video output already attached!"; + return; + } + + if (!context) { + qWarning() << "BbPlayerVideoRendererControl: No media player context!"; + return; + } + + const QByteArray windowGroupId = m_windowGrabber->windowGroupId(); + if (windowGroupId.isEmpty()) { + qWarning() << "BbPlayerVideoRendererControl: Unable to find window group"; + return; + } + + const QString windowName = QStringLiteral("BbPlayerVideoRendererControl_%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 BbPlayerVideoRendererControl::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 BbPlayerVideoRendererControl::pause() +{ + m_windowGrabber->pause(); +} + +void BbPlayerVideoRendererControl::resume() +{ + m_windowGrabber->resume(); +} + +void BbPlayerVideoRendererControl::frameGrabbed(const QImage &frame) +{ + if (m_surface) { + if (!m_surface->isActive()) + m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_ARGB32)); + + m_surface->present(frame.copy()); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/blackberry/mediaplayer/bbplayervideorenderercontrol.h b/src/plugins/blackberry/mediaplayer/bbplayervideorenderercontrol.h new file mode 100644 index 000000000..fff80dfe8 --- /dev/null +++ b/src/plugins/blackberry/mediaplayer/bbplayervideorenderercontrol.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** 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 BBPLAYERVIDEORENDERERCONTROL_H +#define BBPLAYERVIDEORENDERERCONTROL_H + +#include <QPointer> +#include <qabstractvideosurface.h> +#include <qvideorenderercontrol.h> + +typedef struct mmr_context mmr_context_t; +struct bps_event_t; + +QT_BEGIN_NAMESPACE + +class WindowGrabber; + +class BbPlayerVideoRendererControl : public QVideoRendererControl +{ + Q_OBJECT +public: + explicit BbPlayerVideoRendererControl(QObject *parent = 0); + ~BbPlayerVideoRendererControl(); + + 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 diff --git a/src/plugins/blackberry/mediaplayer/bbutil.cpp b/src/plugins/blackberry/mediaplayer/bbutil.cpp index 9fef98a3a..2e95c3571 100644 --- a/src/plugins/blackberry/mediaplayer/bbutil.cpp +++ b/src/plugins/blackberry/mediaplayer/bbutil.cpp @@ -40,7 +40,12 @@ ****************************************************************************/ #include "bbutil.h" -#include <QtCore/qstring.h> +#include <QDebug> +#include <QDir> +#include <QFile> +#include <QString> +#include <QXmlStreamReader> + #include <mm/renderer.h> QT_BEGIN_NAMESPACE @@ -97,4 +102,28 @@ QString mmErrorMessage(const QString &msg, mmr_context_t *context, int *errorCod } } +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 diff --git a/src/plugins/blackberry/mediaplayer/bbutil.h b/src/plugins/blackberry/mediaplayer/bbutil.h index 44fde4ed4..35d59fe48 100644 --- a/src/plugins/blackberry/mediaplayer/bbutil.h +++ b/src/plugins/blackberry/mediaplayer/bbutil.h @@ -51,6 +51,8 @@ class QString; QString mmErrorMessage(const QString &msg, mmr_context_t *context, int * errorCode = 0); +bool checkForDrmPermission(); + QT_END_NAMESPACE #endif diff --git a/src/plugins/blackberry/mediaplayer/bbvideowindowcontrol.cpp b/src/plugins/blackberry/mediaplayer/bbvideowindowcontrol.cpp index 5668332d1..d29f36f0a 100644 --- a/src/plugins/blackberry/mediaplayer/bbvideowindowcontrol.cpp +++ b/src/plugins/blackberry/mediaplayer/bbvideowindowcontrol.cpp @@ -204,7 +204,7 @@ void BbVideoWindowControl::attachDisplay(mmr_context_t *context) QPlatformNativeInterface * const nativeInterface = QGuiApplication::platformNativeInterface(); if (!nativeInterface) { - qDebug() << "BbVideoWindowControl: Unable to get platform native interface. Qt too old?"; + qDebug() << "BbVideoWindowControl: Unable to get platform native interface"; return; } diff --git a/src/plugins/blackberry/mediaplayer/mediaplayer.pri b/src/plugins/blackberry/mediaplayer/mediaplayer.pri index f8db519f5..065c799a6 100644 --- a/src/plugins/blackberry/mediaplayer/mediaplayer.pri +++ b/src/plugins/blackberry/mediaplayer/mediaplayer.pri @@ -5,6 +5,7 @@ HEADERS += \ $$PWD/bbmediaplayerservice.h \ $$PWD/bbmetadata.h \ $$PWD/bbmetadatareadercontrol.h \ + $$PWD/bbplayervideorenderercontrol.h \ $$PWD/bbutil.h \ $$PWD/bbvideowindowcontrol.h @@ -13,6 +14,7 @@ SOURCES += \ $$PWD/bbmediaplayerservice.cpp \ $$PWD/bbmetadata.cpp \ $$PWD/bbmetadatareadercontrol.cpp \ + $$PWD/bbplayervideorenderercontrol.cpp \ $$PWD/bbutil.cpp \ $$PWD/bbvideowindowcontrol.cpp |