qtubuntu-media-0.7.1+14.04.20140304/0000755000015201777760000000000012305354221017052 5ustar pbusernogroup00000000000000qtubuntu-media-0.7.1+14.04.20140304/unittests/0000755000015201777760000000000012305354221021114 5ustar pbusernogroup00000000000000qtubuntu-media-0.7.1+14.04.20140304/unittests/unittests.pro0000644000015201777760000000123712305353776023721 0ustar pbusernogroup00000000000000include(../coverage.pri) CONFIG += testcase TARGET = tst_mediaplayerplugin QT += testlib QT += multimedia opengl INCLUDEPATH += ../src \ /usr/include/qt5/QtMultimedia \ /usr/include/hybris \ /usr/include/libqtubuntu-media-signals LIBS += -lqtubuntu-media-signals HEADERS += \ ../src/aalmediaplayercontrol.h \ ../src/aalmediaplayerservice.h \ ../src/aalmediaplayerserviceplugin.h \ ../src/aalvideorenderercontrol.h SOURCES += \ tst_mediaplayerplugin.cpp \ player.cpp \ ../src/aalmediaplayercontrol.cpp \ ../src/aalmediaplayerservice.cpp \ ../src/aalmediaplayerserviceplugin.cpp \ ../src/aalvideorenderercontrol.cpp qtubuntu-media-0.7.1+14.04.20140304/unittests/media_compatibility_layer.h0000644000015201777760000000546412305353776026520 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * */ #ifndef MEDIA_COMPATIBILITY_LAYER_H_ #define MEDIA_COMPATIBILITY_LAYER_H_ #include #include #include #ifdef __cplusplus extern "C" { #endif // Callback types typedef void (*on_msg_set_video_size)(int height, int width, void *context); typedef void (*on_video_texture_needs_update)(void *context); typedef void (*on_msg_error)(void *context); typedef void (*on_playback_complete)(void *context); typedef void (*on_media_prepared)(void *context); struct MediaPlayerWrapper; // ----- Start of C API ----- // // Callback setters void android_media_set_video_size_cb(MediaPlayerWrapper *mp, on_msg_set_video_size cb, void *context); void android_media_set_video_texture_needs_update_cb(MediaPlayerWrapper *mp, on_video_texture_needs_update cb, void *context); void android_media_set_error_cb(MediaPlayerWrapper *mp, on_msg_error cb, void *context); void android_media_set_playback_complete_cb(MediaPlayerWrapper *mp, on_playback_complete cb, void *context); void android_media_set_media_prepared_cb(MediaPlayerWrapper *mp, on_media_prepared cb, void *context); // Main player control API MediaPlayerWrapper *android_media_new_player(); int android_media_set_data_source(MediaPlayerWrapper *mp, const char* url); int android_media_set_preview_texture(MediaPlayerWrapper *mp, int texture_id); void android_media_update_surface_texture(MediaPlayerWrapper *mp); void android_media_surface_texture_get_transformation_matrix(MediaPlayerWrapper *mp, GLfloat*matrix); int android_media_play(MediaPlayerWrapper *mp); int android_media_pause(MediaPlayerWrapper *mp); int android_media_stop(MediaPlayerWrapper *mp); bool android_media_is_playing(MediaPlayerWrapper *mp); int android_media_seek_to(MediaPlayerWrapper *mp, int msec); int android_media_get_current_position(MediaPlayerWrapper *mp, int *msec); int android_media_get_duration(MediaPlayerWrapper *mp, int *msec); int android_media_get_volume(MediaPlayerWrapper *mp, int *volume); int android_media_set_volume(MediaPlayerWrapper *mp, int volume); #ifdef __cplusplus } #endif #endif // CAMERA_COMPATIBILITY_LAYER_H_ qtubuntu-media-0.7.1+14.04.20140304/unittests/tst_mediaplayerplugin.cpp0000644000015201777760000000530512305353776026246 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalmediaplayerservice.h" #include "media_compatibility_layer.h" #include #include #include #define private public struct MediaPlayerWrapper; class tst_MediaPlayerPlugin : public QObject { Q_OBJECT AalMediaPlayerService m_service; QMediaControl *m_playerControl; QMediaControl *m_rendererControl; private slots: void initTestCase(); void cleanupTestCase(); void tst_requestRelease(); void tst_newMediaPlayer(); void tst_androidControl(); }; void tst_MediaPlayerPlugin::initTestCase() { m_playerControl = m_service.requestControl(QMediaPlayerControl_iid); QVERIFY(m_playerControl != NULL); m_rendererControl = m_service.requestControl(QVideoRendererControl_iid); QVERIFY(m_rendererControl != NULL); } void tst_MediaPlayerPlugin::cleanupTestCase() { m_service.releaseControl(m_playerControl); m_service.releaseControl(m_rendererControl); } void tst_MediaPlayerPlugin::tst_requestRelease() { QMediaControl *mpControl = NULL; QMediaControl *rendererControl = NULL; // Request a new reference to the media player control and verify that // it's the same pointer as the original reference. mpControl = m_service.requestControl(QMediaPlayerControl_iid); QVERIFY(mpControl == m_playerControl); rendererControl = m_service.requestControl(QVideoRendererControl_iid); QVERIFY(rendererControl == m_rendererControl); // Now release the reference and make sure that the original media player // control reference still exists. m_service.releaseControl(mpControl); QVERIFY(mpControl == m_playerControl); m_service.releaseControl(rendererControl); QVERIFY(rendererControl == m_rendererControl); } void tst_MediaPlayerPlugin::tst_newMediaPlayer() { bool ret = m_service.newMediaPlayer(); QVERIFY(ret == true); } void tst_MediaPlayerPlugin::tst_androidControl() { MediaPlayerWrapper *mp = m_service.androidControl(); QVERIFY(mp != NULL); } QTEST_MAIN(tst_MediaPlayerPlugin) #include "tst_mediaplayerplugin.moc" qtubuntu-media-0.7.1+14.04.20140304/unittests/player.cpp0000644000015201777760000000625612305353776023143 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "media_compatibility_layer.h" #include // Mock object so that we don't get an incomplete type compiler error struct MediaPlayerWrapper { MediaPlayerWrapper() { } }; void android_media_set_video_size_cb(MediaPlayerWrapper *mp, on_msg_set_video_size cb, void *context) { Q_UNUSED(mp); Q_UNUSED(cb); Q_UNUSED(context); } void android_media_set_video_texture_needs_update_cb(MediaPlayerWrapper *mp, on_video_texture_needs_update cb, void *context) { Q_UNUSED(mp); Q_UNUSED(cb); Q_UNUSED(context); } void android_media_set_error_cb(MediaPlayerWrapper *mp, on_msg_error cb, void *context) { Q_UNUSED(mp); Q_UNUSED(cb); Q_UNUSED(context); } void android_media_set_playback_complete_cb(MediaPlayerWrapper *mp, on_playback_complete cb, void *context) { Q_UNUSED(mp); Q_UNUSED(cb); Q_UNUSED(context); } void android_media_set_media_prepared_cb(MediaPlayerWrapper *mp, on_media_prepared cb, void *context) { Q_UNUSED(mp); Q_UNUSED(cb); Q_UNUSED(context); } MediaPlayerWrapper *android_media_new_player() { return new MediaPlayerWrapper(); } int android_media_set_data_source(MediaPlayerWrapper *mp, const char* url) { Q_UNUSED(mp); Q_UNUSED(url); return 0; } int android_media_set_preview_texture(MediaPlayerWrapper *mp, int texture_id) { Q_UNUSED(mp); Q_UNUSED(texture_id); return 0; } void android_media_update_surface_texture(MediaPlayerWrapper *mp) { Q_UNUSED(mp); } void android_media_surface_texture_get_transformation_matrix(MediaPlayerWrapper *mp, GLfloat* matrix) { Q_UNUSED(mp); Q_UNUSED(matrix); } int android_media_play(MediaPlayerWrapper *mp) { Q_UNUSED(mp); return 0; } int android_media_pause(MediaPlayerWrapper *mp) { Q_UNUSED(mp); return 0; } int android_media_stop(MediaPlayerWrapper *mp) { Q_UNUSED(mp); return 0; } bool android_media_is_playing(MediaPlayerWrapper *mp) { Q_UNUSED(mp); return true; } int android_media_seek_to(MediaPlayerWrapper *mp, int msec) { Q_UNUSED(mp); Q_UNUSED(msec); return 0; } int android_media_get_current_position(MediaPlayerWrapper *mp, int *msec) { Q_UNUSED(mp); Q_UNUSED(msec); return 0; } int android_media_get_duration(MediaPlayerWrapper *mp, int *msec) { Q_UNUSED(mp); Q_UNUSED(msec); return 0; } int android_media_get_volume(MediaPlayerWrapper *mp, int *volume) { Q_UNUSED(mp); Q_UNUSED(volume); return 0; } int android_media_set_volume(MediaPlayerWrapper *mp, int volume) { Q_UNUSED(mp); Q_UNUSED(volume); return 0; } qtubuntu-media-0.7.1+14.04.20140304/aalMediaPlayer.pro0000644000015201777760000000012012305353776022455 0ustar pbusernogroup00000000000000include(coverage.pri) TEMPLATE = subdirs SUBDIRS += \ src \ unittests qtubuntu-media-0.7.1+14.04.20140304/coverage.pri0000644000015201777760000000356112305353776021404 0ustar pbusernogroup00000000000000# Coverage CONFIG(coverage) { OBJECTS_DIR = MOC_DIR = TOP_SRC_DIR = $$PWD LIBS += -lgcov QMAKE_CXXFLAGS += --coverage QMAKE_LDFLAGS += --coverage QMAKE_EXTRA_TARGETS += coverage cov QMAKE_EXTRA_TARGETS += clean-gcno clean-gcda coverage-html \ generate-coverage-html clean-coverage-html coverage-gcovr \ generate-gcovr generate-coverage-gcovr clean-coverage-gcovr clean-gcno.commands = \ "@echo Removing old coverage instrumentation"; \ "find -name '*.gcno' -print | xargs -r rm" clean-gcda.commands = \ "@echo Removing old coverage results"; \ "find -name '*.gcda' -print | xargs -r rm" coverage-html.depends = clean-gcda check generate-coverage-html generate-coverage-html.commands = \ "@echo Collecting coverage data"; \ "lcov --directory $${TOP_SRC_DIR} --capture --output-file coverage.info --no-checksum --compat-libtool"; \ "lcov --extract coverage.info \"*/src/*.cpp\" -o coverage.info"; \ "lcov --remove coverage.info \"moc_*.cpp\" -o coverage.info"; \ "LANG=C genhtml --prefix $${TOP_SRC_DIR} --output-directory coverage-html --title \"Code Coverage\" --legend --show-details coverage.info" clean-coverage-html.depends = clean-gcda clean-coverage-html.commands = \ "lcov --directory $${TOP_SRC_DIR} -z"; \ "rm -rf coverage.info coverage-html" coverage-gcovr.depends = clean-gcda check generate-coverage-gcovr generate-coverage-gcovr.commands = \ "@echo Generating coverage GCOVR report"; \ "gcovr -x -r $${TOP_SRC_DIR} -o $${TOP_SRC_DIR}/coverage.xml -e \".*/moc_.*\" -e \"unittests/.*\" -e \".*\\.h\"" clean-coverage-gcovr.depends = clean-gcda clean-coverage-gcovr.commands = \ "rm -rf $${TOP_SRC_DIR}/coverage.xml" QMAKE_CLEAN += *.gcda *.gcno coverage.info coverage.xml } qtubuntu-media-0.7.1+14.04.20140304/src/0000755000015201777760000000000012305354221017641 5ustar pbusernogroup00000000000000qtubuntu-media-0.7.1+14.04.20140304/src/aalmediaplayer.json0000644000015201777760000000006212305353776023522 0ustar pbusernogroup00000000000000{ "Keys": ["org.qt-project.qt.mediaplayer"] } qtubuntu-media-0.7.1+14.04.20140304/src/aalmediaplayercontrol.h0000644000015201777760000000434612305353776024412 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALMEDIAPLAYER_H #define AALMEDIAPLAYER_H #include class AalMediaPlayerService; class AalMediaPlayerControl : public QMediaPlayerControl { Q_OBJECT public: AalMediaPlayerControl(AalMediaPlayerService *service, QObject *parent = 0); ~AalMediaPlayerControl(); virtual QMediaPlayer::State state() const; virtual QMediaPlayer::MediaStatus mediaStatus() const; virtual qint64 duration() const; virtual qint64 position() const; virtual void setPosition(qint64); virtual int volume() const; virtual void setVolume(int); virtual bool isMuted() const; virtual void setMuted(bool); virtual int bufferStatus() const; virtual bool isAudioAvailable() const; virtual bool isVideoAvailable() const; virtual bool isSeekable() const; virtual QMediaTimeRange availablePlaybackRanges() const; virtual qreal playbackRate() const; virtual void setPlaybackRate(qreal); virtual QMediaContent media() const; virtual const QIODevice* mediaStream() const; virtual void setMedia(const QMediaContent&, QIODevice*); virtual void play(); virtual void pause(); virtual void stop(); static void playbackCompleteCb(void *context); static void mediaPreparedCb(void *context); private: AalMediaPlayerService *m_service; QMediaPlayer::State m_state; QMediaPlayer::MediaStatus m_status; QMediaContent m_mediaContent; int m_cachedVolume; void playbackComplete(); void mediaPrepared(); void setMediaStatus(QMediaPlayer::MediaStatus status); void setState(QMediaPlayer::State state); }; #endif qtubuntu-media-0.7.1+14.04.20140304/src/aalmediaplayerservice.h0000644000015201777760000000453612305353776024373 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALMEDIAPLAYERSERVICE_H #define AALMEDIAPLAYERSERVICE_H #include #include class AalMediaPlayerControl; class QMediaPlayerControl; class AalVideoRendererControl; struct MediaPlayerWrapper; class AalMediaPlayerService : public QMediaService { Q_OBJECT public: AalMediaPlayerService(QObject *parent = 0); ~AalMediaPlayerService(); QMediaControl* requestControl(const char *name); void releaseControl(QMediaControl *control); AalMediaPlayerControl *mediaPlayerControl() const { return m_mediaPlayerControl; } AalVideoRendererControl *videoOutputControl() const { return m_videoOutput; } MediaPlayerWrapper *androidControl(); bool newMediaPlayer(); void setupMediaPlayer(); void setMedia(const QUrl &url); void play(); void pause(); void stop(); int position() const; void setPosition(int msec); int duration() const; int getVolume() const; void setVolume(int volume); void setVideoTextureNeedsUpdateCb(on_video_texture_needs_update cb, void *context); void setVideoSizeCb(on_msg_set_video_size cb, void *context); void setPlaybackCompleteCb(on_playback_complete cb, void *context); void setMediaPreparedCb(on_media_prepared cb, void *context); static AalMediaPlayerService *instance() { return m_service; } Q_SIGNALS: void serviceReady(); private: static AalMediaPlayerService *m_service; AalMediaPlayerControl *m_mediaPlayerControl; AalVideoRendererControl *m_videoOutput; MediaPlayerWrapper *m_androidMediaPlayer; int m_mediaPlayerControlRef; int m_videoOutputRef; on_msg_set_video_size m_setVideoSizeCb; void *m_setVideoSizeContext; }; #endif qtubuntu-media-0.7.1+14.04.20140304/src/aalvideorenderercontrol.cpp0000644000015201777760000001330212305353776025276 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalvideorenderercontrol.h" #include "aalmediaplayercontrol.h" #include "aalmediaplayerservice.h" #include #include #include #include #include #include #include #include class AalGLTextureBuffer : public QAbstractVideoBuffer { public: AalGLTextureBuffer(GLuint textureId) : QAbstractVideoBuffer(QAbstractVideoBuffer::GLTextureHandle), m_textureId(textureId) { } MapMode mapMode() const { return NotMapped; } uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) { qDebug() << Q_FUNC_INFO; Q_UNUSED(mode); Q_UNUSED(numBytes); Q_UNUSED(bytesPerLine); return NULL; } void unmap() { qDebug() << Q_FUNC_INFO; } QVariant handle() const { return QVariant::fromValue(m_textureId); } GLuint textureId() { return m_textureId; } private: GLuint m_textureId; }; AalVideoRendererControl::AalVideoRendererControl(AalMediaPlayerService *service, QObject *parent) : QVideoRendererControl(parent), m_surface(0), m_service(service), m_textureBuffer(0), m_textureId(0), m_height(720), m_width(1280), m_firstFrame(true) { m_service->setVideoSizeCb(AalVideoRendererControl::setVideoSizeCb, static_cast(this)); // Get notified when qtvideo-node creates a GL texture connect(SharedSignal::instance(), SIGNAL(textureCreated(unsigned int)), this, SLOT(onTextureCreated(unsigned int))); // Get notified when the AalMediaPlayerService is ready to play video connect(m_service, SIGNAL(serviceReady()), this, SLOT(onServiceReady())); } AalVideoRendererControl::~AalVideoRendererControl() { if (m_textureBuffer) { GLuint textureId = m_textureBuffer->handle().toUInt(); glDeleteTextures(1, &textureId); delete m_textureBuffer; } } QAbstractVideoSurface *AalVideoRendererControl::surface() const { return m_surface; } void AalVideoRendererControl::setSurface(QAbstractVideoSurface *surface) { if (m_surface != surface) { m_surface = surface; Q_EMIT surfaceChanged(surface); } } void AalVideoRendererControl::updateVideoTextureCb(void *context) { Q_ASSERT(context != NULL); QMetaObject::invokeMethod(static_cast(context), "updateVideoTexture", Qt::QueuedConnection); } void AalVideoRendererControl::setVideoSizeCb(int height, int width, void *data) { if (data != NULL) static_cast(data)->setVideoSize(height, width); else qWarning() << "Failed to call setVideoSize() since data is NULL." << endl; } void AalVideoRendererControl::setupSurface() { if (!m_textureBuffer) return; MediaPlayerWrapper *mp = m_service->androidControl(); m_service->setVideoTextureNeedsUpdateCb(AalVideoRendererControl::updateVideoTextureCb, static_cast(this)); android_media_set_preview_texture(mp, m_textureBuffer->handle().toUInt()); } void AalVideoRendererControl::setVideoSize(int height, int width) { m_height = height; m_width = width; } void AalVideoRendererControl::updateVideoTexture() { if (!m_surface) { qWarning() << "m_surface is NULL, can't update video texture" << endl; return; } if (!m_textureBuffer) { qWarning() << "m_textureBuffer is NULL, can't update video texture" << endl; return; } // If this is the first video frame being rendered, it's ok that m_textureId == 0. // This is necessary so that a ShaderVideoNode instance from qtvideo-node gets created, // as it is responsible for creating and returning a new texture and ID respectively. if (m_textureId == 0 && !m_firstFrame) { qWarning() << "m_textureId == 0, can't update video texture" << endl; return; } QVideoFrame frame(new AalGLTextureBuffer(m_textureId), QSize(m_width, m_height), QVideoFrame::Format_RGB32); if (!frame.isValid()) { qWarning() << "Frame is invalid, not presenting." << endl; return; } MediaPlayerWrapper *mp = m_service->androidControl(); frame.setMetaData("MediaPlayerControl", QVariant::fromValue((void*)mp)); presentVideoFrame(frame); if (m_firstFrame) m_firstFrame = false; } void AalVideoRendererControl::onTextureCreated(unsigned int textureID) { m_textureId = static_cast(textureID); } void AalVideoRendererControl::onServiceReady() { m_textureBuffer = new AalGLTextureBuffer(m_textureId); setupSurface(); } void AalVideoRendererControl::presentVideoFrame(const QVideoFrame &frame, bool empty) { Q_ASSERT(m_surface != NULL); if (!m_surface->isActive()) { QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), frame.handleType()); if (!m_surface->start(format)) { qWarning() << "Failed to start video surface with format:" << format; } } if (m_surface->isActive()) { m_surface->present(frame); } } qtubuntu-media-0.7.1+14.04.20140304/src/aalmediaplayerserviceplugin.h0000644000015201777760000000251312305353776025603 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALMEDIAPLAYERSERVICEPLUGIN_H #define AALMEDIAPLAYERSERVICEPLUGIN_H #include class AalServicePlugin : public QMediaServiceProviderPlugin, public QMediaServiceSupportedDevicesInterface { Q_OBJECT Q_INTERFACES(QMediaServiceSupportedDevicesInterface) Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "aalmediaplayer.json") public: AalServicePlugin(); QMediaService* create(QString const& key); void release(QMediaService *service); QList devices(const QByteArray &service) const; QString deviceDescription(const QByteArray &service, const QByteArray &device); }; #endif qtubuntu-media-0.7.1+14.04.20140304/src/aalvideorenderercontrol.h0000644000015201777760000000356212305353776024752 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALVIDEORENDERERCONTROL_H #define AALVIDEORENDERERCONTROL_H #include #include #include #include class AalMediaPlayerService; class AalGLTextureBuffer; class AalVideoRendererControl : public QVideoRendererControl { Q_OBJECT public: AalVideoRendererControl(AalMediaPlayerService *service, QObject *parent = 0); ~AalVideoRendererControl(); QAbstractVideoSurface *surface() const; void setSurface(QAbstractVideoSurface *surface); // Callbacks static void updateVideoTextureCb(void *context); static void setVideoSizeCb(int height, int width, void *data); public Q_SLOTS: void setupSurface(); Q_SIGNALS: void surfaceChanged(QAbstractVideoSurface *surface); private Q_SLOTS: void setVideoSize(int height, int width); void updateVideoTexture(); void onTextureCreated(unsigned int textureID); void onServiceReady(); private: void presentVideoFrame(const QVideoFrame &frame, bool empty = false); QAbstractVideoSurface *m_surface; AalMediaPlayerService *m_service; AalGLTextureBuffer *m_textureBuffer; GLuint m_textureId; int m_height; int m_width; bool m_firstFrame; }; #endif qtubuntu-media-0.7.1+14.04.20140304/src/aalmediaplayerserviceplugin.cpp0000644000015201777760000000262712305353776026144 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalmediaplayerserviceplugin.h" #include "aalmediaplayerservice.h" #include AalServicePlugin::AalServicePlugin() { } QMediaService* AalServicePlugin::create(QString const& key) { if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) return new AalMediaPlayerService; else qWarning() << "Key not supported:" << key; return 0; } void AalServicePlugin::release(QMediaService *service) { Q_UNUSED(service); delete service; } QList AalServicePlugin::devices(const QByteArray &service) const { Q_UNUSED(service); return QList(); } QString AalServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) { Q_UNUSED(service); Q_UNUSED(device); return QString(); } qtubuntu-media-0.7.1+14.04.20140304/src/src.pro0000644000015201777760000000125612305353776021174 0ustar pbusernogroup00000000000000include(../coverage.pri) TARGET = aalmediaplayer QT += multimedia opengl TEMPLATE = lib CONFIG += plugin PLUGIN_TYPE = mediaservice target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE} INSTALLS = target INCLUDEPATH += /usr/include/hybris /usr/include/libqtubuntu-media-signals LIBS += -lhybris-common -lubuntu_application_api -lmedia -lqtubuntu-media-signals OTHER_FILES += aalmediaplayer.json HEADERS += \ aalmediaplayercontrol.h \ aalmediaplayerservice.h \ aalmediaplayerserviceplugin.h \ aalvideorenderercontrol.h SOURCES += \ aalmediaplayercontrol.cpp \ aalmediaplayerservice.cpp \ aalmediaplayerserviceplugin.cpp \ aalvideorenderercontrol.cpp qtubuntu-media-0.7.1+14.04.20140304/src/aalmediaplayerservice.cpp0000644000015201777760000001664412305353776024731 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalmediaplayercontrol.h" #include "aalmediaplayerservice.h" #include "aalvideorenderercontrol.h" #include #include #include enum { OK = 0, NO_ERROR = 0, BAD_VALUE = -EINVAL, }; static void error_msg_cb(void *context) { Q_UNUSED(context); qDebug() << __PRETTY_FUNCTION__ << endl; } AalMediaPlayerService *AalMediaPlayerService::m_service = 0; AalMediaPlayerService::AalMediaPlayerService(QObject *parent): QMediaService(parent), m_androidMediaPlayer(NULL), m_mediaPlayerControlRef(0), m_videoOutputRef(0), m_setVideoSizeCb(0), m_setVideoSizeContext(0) { m_service = this; if (!newMediaPlayer()) qWarning() << "Failed to create a new media player backend. Video playback will not function." << endl; m_videoOutput = new AalVideoRendererControl(this); m_mediaPlayerControl = new AalMediaPlayerControl(this); } AalMediaPlayerService::~AalMediaPlayerService() { if (m_mediaPlayerControl != NULL) delete m_mediaPlayerControl; if (m_videoOutput != NULL) delete m_videoOutput; if (m_androidMediaPlayer != NULL) delete m_androidMediaPlayer; } QMediaControl *AalMediaPlayerService::requestControl(const char *name) { if (qstrcmp(name, QMediaPlayerControl_iid) == 0) { if (m_mediaPlayerControlRef == 0 && m_mediaPlayerControl == NULL) m_mediaPlayerControl = new AalMediaPlayerControl(this); ++m_mediaPlayerControlRef; return m_mediaPlayerControl; } if (qstrcmp(name, QVideoRendererControl_iid) == 0) { if (m_videoOutputRef == 0 && m_videoOutput == NULL) m_videoOutput = new AalVideoRendererControl(this); ++m_videoOutputRef; return m_videoOutput; } return NULL; } void AalMediaPlayerService::releaseControl(QMediaControl *control) { if (control == m_mediaPlayerControl) { if (m_mediaPlayerControlRef > 0) --m_mediaPlayerControlRef; if (m_mediaPlayerControlRef == 0) { if (m_mediaPlayerControl != NULL) { delete m_mediaPlayerControl; m_mediaPlayerControl = NULL; control = NULL; } } } else if (control == m_videoOutput) { if (m_videoOutputRef > 0) --m_videoOutputRef; if (m_videoOutputRef == 0) { if (m_videoOutput != NULL) { delete m_videoOutput; m_videoOutput = NULL; control = NULL; } } } } MediaPlayerWrapper *AalMediaPlayerService::androidControl() { return m_androidMediaPlayer; } bool AalMediaPlayerService::newMediaPlayer() { if (m_androidMediaPlayer) return true; m_androidMediaPlayer = android_media_new_player(); if (!m_androidMediaPlayer) { qWarning() << "Unable to create a new media player instance."; return false; } return true; } void AalMediaPlayerService::setupMediaPlayer() { assert(m_androidMediaPlayer != NULL); assert(m_setVideoSizeCb != NULL); android_media_set_video_size_cb(m_androidMediaPlayer, m_setVideoSizeCb, m_setVideoSizeContext); m_videoOutput->setupSurface(); // Gets called when there is any type of media playback issue android_media_set_error_cb(m_androidMediaPlayer, error_msg_cb, static_cast(this)); } void AalMediaPlayerService::setMedia(const QUrl &url) { if (url.isEmpty()) { qWarning() << "Failed to set media source, url must be set." << endl; return; } int ret = android_media_set_data_source(m_androidMediaPlayer, url.path().toStdString().c_str()); if (ret != OK) { qWarning() << "Failed to set media source." << endl; return; } } void AalMediaPlayerService::play() { assert(m_androidMediaPlayer != NULL); int ret = android_media_play(m_androidMediaPlayer); if (ret != OK) { qWarning() << "Failed to play media." << endl; return; } Q_EMIT serviceReady(); } void AalMediaPlayerService::pause() { assert(m_androidMediaPlayer != NULL); int ret = android_media_pause(m_androidMediaPlayer); if (ret != OK) { qWarning() << "Failed to pause media playback." << endl; return; } } void AalMediaPlayerService::stop() { assert(m_androidMediaPlayer != NULL); int ret = android_media_stop(m_androidMediaPlayer); if (ret != OK) { qWarning() << "Failed to stop media playback." << endl; return; } } int AalMediaPlayerService::position() const { assert(m_androidMediaPlayer != NULL); int pos_msec = 0; int ret = android_media_get_current_position(m_androidMediaPlayer, &pos_msec); if (ret != OK) { qWarning() << "Failed to get the current playback position." << endl; } return pos_msec; } void AalMediaPlayerService::setPosition(int msec) { assert(m_androidMediaPlayer != NULL); int ret = android_media_seek_to(m_androidMediaPlayer, msec); if (ret != OK) { qWarning() << "Failed to set the current playback position." << endl; return; } } int AalMediaPlayerService::duration() const { assert(m_androidMediaPlayer != NULL); int duration_msec = 0; int ret = android_media_get_duration(m_androidMediaPlayer, &duration_msec); if (ret != OK) { qWarning() << "Failed to get the media duration." << endl; } return duration_msec; } int AalMediaPlayerService::getVolume() const { assert(m_androidMediaPlayer != NULL); int vol = 0; int ret = android_media_get_volume(m_androidMediaPlayer, &vol); if (ret != OK) { qWarning() << "Failed to get the volume." << endl; } return vol; } void AalMediaPlayerService::setVolume(int volume) { assert(m_androidMediaPlayer != NULL); int ret = android_media_set_volume(m_androidMediaPlayer, volume); if (ret != OK) { qWarning() << "Failed to set the volume." << endl; } } void AalMediaPlayerService::setVideoTextureNeedsUpdateCb(on_video_texture_needs_update cb, void *context) { assert(m_androidMediaPlayer != NULL); android_media_set_video_texture_needs_update_cb(m_androidMediaPlayer, cb, context); } void AalMediaPlayerService::setVideoSizeCb(on_msg_set_video_size cb, void *context) { m_setVideoSizeCb = cb; m_setVideoSizeContext = context; } void AalMediaPlayerService::setPlaybackCompleteCb(on_playback_complete cb, void *context) { assert(m_androidMediaPlayer != NULL); android_media_set_playback_complete_cb(m_androidMediaPlayer, cb, context); } void AalMediaPlayerService::setMediaPreparedCb(on_media_prepared cb, void *context) { assert(m_androidMediaPlayer != NULL); android_media_set_media_prepared_cb(m_androidMediaPlayer, cb, context); } qtubuntu-media-0.7.1+14.04.20140304/src/aalmediaplayercontrol.cpp0000644000015201777760000001400612305353776024737 0ustar pbusernogroup00000000000000/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalmediaplayercontrol.h" #include "aalmediaplayerservice.h" #include "aalvideorenderercontrol.h" #include #include AalMediaPlayerControl::AalMediaPlayerControl(AalMediaPlayerService *service, QObject *parent) : QMediaPlayerControl(parent), m_service(service), m_state(QMediaPlayer::StoppedState), m_status(QMediaPlayer::NoMedia) { m_service->setupMediaPlayer(); m_service->setPlaybackCompleteCb(AalMediaPlayerControl::playbackCompleteCb, static_cast(this)); m_service->setMediaPreparedCb(AalMediaPlayerControl::mediaPreparedCb, static_cast(this)); m_cachedVolume = volume(); } AalMediaPlayerControl::~AalMediaPlayerControl() { stop(); m_state = QMediaPlayer::StoppedState; m_status = QMediaPlayer::NoMedia; m_cachedVolume = 0; } QMediaPlayer::State AalMediaPlayerControl::state() const { qDebug() << __PRETTY_FUNCTION__ << endl; return m_state; } QMediaPlayer::MediaStatus AalMediaPlayerControl::mediaStatus() const { qDebug() << __PRETTY_FUNCTION__ << endl; return m_status; } qint64 AalMediaPlayerControl::duration() const { return static_cast(m_service->duration()); } qint64 AalMediaPlayerControl::position() const { return static_cast(m_service->position()); } void AalMediaPlayerControl::setPosition(qint64 msec) { m_service->setPosition(static_cast(msec)); Q_EMIT positionChanged(msec); } int AalMediaPlayerControl::volume() const { qDebug() << __PRETTY_FUNCTION__ << endl; return m_service->getVolume(); } void AalMediaPlayerControl::setVolume(int volume) { qDebug() << __PRETTY_FUNCTION__ << endl; m_cachedVolume = volume; m_service->setVolume(volume); Q_EMIT volumeChanged(m_cachedVolume); } bool AalMediaPlayerControl::isMuted() const { qDebug() << __PRETTY_FUNCTION__ << endl; return (volume() == 0); } void AalMediaPlayerControl::setMuted(bool muted) { qDebug() << __PRETTY_FUNCTION__ << endl; if (muted) { m_cachedVolume = volume(); setVolume(0); } else { setVolume(m_cachedVolume); } Q_EMIT mutedChanged(muted); } int AalMediaPlayerControl::bufferStatus() const { qDebug() << __PRETTY_FUNCTION__ << endl; // Until we are playing network streams, there is no buffering necessary return 100; } bool AalMediaPlayerControl::isAudioAvailable() const { qDebug() << __PRETTY_FUNCTION__ << endl; return true; } bool AalMediaPlayerControl::isVideoAvailable() const { qDebug() << __PRETTY_FUNCTION__ << endl; return true; } bool AalMediaPlayerControl::isSeekable() const { qDebug() << __PRETTY_FUNCTION__ << endl; return true; } QMediaTimeRange AalMediaPlayerControl::availablePlaybackRanges() const { qDebug() << __PRETTY_FUNCTION__ << endl; // TODO: this will need to change once we can play networked sources return QMediaTimeRange(0, duration()); } qreal AalMediaPlayerControl::playbackRate() const { qDebug() << __PRETTY_FUNCTION__ << endl; return 1.0; } void AalMediaPlayerControl::setPlaybackRate(qreal rate) { qDebug() << __PRETTY_FUNCTION__ << endl; Q_UNUSED(rate); } QMediaContent AalMediaPlayerControl::media() const { qDebug() << __PRETTY_FUNCTION__ << endl; return m_mediaContent; } const QIODevice* AalMediaPlayerControl::mediaStream() const { qDebug() << __PRETTY_FUNCTION__ << endl; // This is only valid if a stream was passed into setMedia() return NULL; } void AalMediaPlayerControl::setMedia(const QMediaContent& media, QIODevice* stream) { Q_UNUSED(stream); qDebug() << __PRETTY_FUNCTION__ << endl; stop(); m_mediaContent = media; Q_EMIT mediaChanged(m_mediaContent); // Make sure we can actually load something valid if (!media.isNull()) { setMediaStatus(QMediaPlayer::LoadingMedia); m_service->setMedia(media.canonicalUrl()); } } void AalMediaPlayerControl::play() { m_service->play(); setState(QMediaPlayer::PlayingState); } void AalMediaPlayerControl::pause() { m_service->pause(); setState(QMediaPlayer::PausedState); } void AalMediaPlayerControl::stop() { m_service->stop(); setState(QMediaPlayer::StoppedState); } void AalMediaPlayerControl::playbackCompleteCb(void *context) { if (context != NULL) static_cast(context)->playbackComplete(); else qWarning() << "Failed to call playbackComplete() since context is NULL." << endl; } void AalMediaPlayerControl::playbackComplete() { setMediaStatus(QMediaPlayer::EndOfMedia); setState(QMediaPlayer::StoppedState); } void AalMediaPlayerControl::mediaPreparedCb(void *context) { if (context != NULL) static_cast(context)->mediaPrepared(); else qWarning() << "Failed to call mediaPrepared() since context is NULL." << endl; } void AalMediaPlayerControl::mediaPrepared() { setMediaStatus(QMediaPlayer::LoadedMedia); Q_EMIT durationChanged(duration()); Q_EMIT positionChanged(position()); } void AalMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status) { if (status != m_status) { m_status = status; Q_EMIT mediaStatusChanged(m_status); } } void AalMediaPlayerControl::setState(QMediaPlayer::State state) { if (state != m_state) { m_state = state; Q_EMIT stateChanged(m_state); } } qtubuntu-media-0.7.1+14.04.20140304/COPYING0000644000015201777760000001674312305353776020136 0ustar pbusernogroup00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.