Android multimedia plug-in.
Adds MediaPlayer support for Android. Change-Id: I4c7b1e19927b2e50b227f3a3b3f7ca2e99397618 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
This commit is contained in:
committed by
The Qt Project
parent
68a38b151e
commit
909a09069f
@@ -51,6 +51,11 @@ include(radio/radio.pri)
|
||||
include(recording/recording.pri)
|
||||
include(video/video.pri)
|
||||
|
||||
ANDROID_JAR_DEPENDENCIES = \
|
||||
jar/QtMultimedia.jar:org.qtproject.qt5.android.multimedia.QtAndroidMediaPlayer
|
||||
ANDROID_LIB_DEPENDENCIES = \
|
||||
plugins/mediaservice/libandroidmediaplayer.so
|
||||
|
||||
mac {
|
||||
LIBS += -framework AppKit -framework QuartzCore -framework QTKit
|
||||
}
|
||||
|
||||
5
src/plugins/android/android.pro
Normal file
5
src/plugins/android/android.pro
Normal file
@@ -0,0 +1,5 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += mediaplayer \
|
||||
jar
|
||||
|
||||
6
src/plugins/android/jar/AndroidManifest.xml
Normal file
6
src/plugins/android/jar/AndroidManifest.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.qtproject.qt5.android.multimedia"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
|
||||
</manifest>
|
||||
11
src/plugins/android/jar/jar.pro
Normal file
11
src/plugins/android/jar/jar.pro
Normal file
@@ -0,0 +1,11 @@
|
||||
load(qt_build_paths)
|
||||
CONFIG += java
|
||||
TARGET = QtMultimedia
|
||||
DESTDIR = $$MODULE_BASE_OUTDIR/jar
|
||||
API_VERSION = android-11
|
||||
|
||||
JAVACLASSPATH += $$PWD/src
|
||||
|
||||
JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java \
|
||||
$$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java \
|
||||
$$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java
|
||||
@@ -0,0 +1,445 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtMultimedia module 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
package org.qtproject.qt5.android.multimedia;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.String;
|
||||
|
||||
// API is level is < 9 unless marked otherwise.
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
public class QtAndroidMediaPlayer extends MediaPlayer
|
||||
{
|
||||
// Native callback functions for MediaPlayer
|
||||
native public void onErrorNative(int what, int extra, long id);
|
||||
native public void onBufferingUpdateNative(int percent, long id);
|
||||
native public void onInfoNative(int what, int extra, long id);
|
||||
native public void onMediaPlayerInfoNative(int what, int extra, long id);
|
||||
native public void onVideoSizeChangedNative(int width, int height, long id);
|
||||
|
||||
private Uri mUri = null;
|
||||
private final long mID;
|
||||
private boolean mMuted = false;
|
||||
private boolean mPreparing = false;
|
||||
private boolean mInitialized = false;
|
||||
private int mVolume = 100;
|
||||
private static final String TAG = "Qt MediaPlayer";
|
||||
private static Context mApplicationContext = null;
|
||||
|
||||
final int MEDIA_PLAYER_INVALID_STATE = 1;
|
||||
final int MEDIA_PLAYER_PREPARING = 2;
|
||||
final int MEDIA_PLAYER_READY = 3;
|
||||
final int MEDIA_PLAYER_DURATION = 4;
|
||||
final int MEDIA_PLAYER_PROGRESS = 5;
|
||||
final int MEDIA_PLAYER_FINISHED = 6;
|
||||
|
||||
// Activity set by Qt on load.
|
||||
static public void setActivity(final Activity activity)
|
||||
{
|
||||
try {
|
||||
mApplicationContext = activity.getApplicationContext();
|
||||
} catch(final Exception e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private class ProgressWatcher implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
final int duratation = getDuration();
|
||||
int currentPosition = getCurrentPosition();
|
||||
|
||||
try {
|
||||
while (duratation >= currentPosition && isPlaying()) {
|
||||
onMediaPlayerInfoNative(MEDIA_PLAYER_PROGRESS, currentPosition, mID);
|
||||
Thread.sleep(1000);
|
||||
currentPosition = getCurrentPosition();
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MediaPlayer OnErrorListener
|
||||
*/
|
||||
private class MediaPlayerErrorListener
|
||||
implements MediaPlayer.OnErrorListener
|
||||
{
|
||||
@Override
|
||||
public boolean onError(final MediaPlayer mp,
|
||||
final int what,
|
||||
final int extra)
|
||||
{
|
||||
reset();
|
||||
onErrorNative(what, extra, mID);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MediaPlayer OnBufferingListener
|
||||
*/
|
||||
private class MediaPlayerBufferingListener
|
||||
implements MediaPlayer.OnBufferingUpdateListener
|
||||
{
|
||||
private int mBufferPercent = -1;
|
||||
@Override
|
||||
public void onBufferingUpdate(final android.media.MediaPlayer mp,
|
||||
final int percent)
|
||||
{
|
||||
// Avoid updates when percent is unchanged.
|
||||
// E.g., we keep getting updates when percent == 100
|
||||
if (mBufferPercent == percent)
|
||||
return;
|
||||
|
||||
onBufferingUpdateNative((mBufferPercent = percent), mID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MediaPlayer OnCompletionListener
|
||||
*/
|
||||
private class MediaPlayerCompletionListener
|
||||
implements MediaPlayer.OnCompletionListener
|
||||
{
|
||||
@Override
|
||||
public void onCompletion(final MediaPlayer mp)
|
||||
{
|
||||
onMediaPlayerInfoNative(MEDIA_PLAYER_FINISHED, 0, mID);
|
||||
reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MediaPlayer OnInfoListener
|
||||
*/
|
||||
private class MediaPlayerInfoListener
|
||||
implements MediaPlayer.OnInfoListener
|
||||
{
|
||||
@Override
|
||||
public boolean onInfo(final MediaPlayer mp,
|
||||
final int what,
|
||||
final int extra)
|
||||
{
|
||||
onInfoNative(what, extra, mID);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MediaPlayer OnPreparedListener
|
||||
*/
|
||||
private class MediaPlayerPreparedListener
|
||||
implements MediaPlayer.OnPreparedListener
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onPrepared(final MediaPlayer mp)
|
||||
{
|
||||
onMediaPlayerInfoNative(MEDIA_PLAYER_DURATION, getDuration(), mID);
|
||||
onMediaPlayerInfoNative(MEDIA_PLAYER_READY, 0, mID);
|
||||
mPreparing = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MediaPlayer OnSeekCompleteListener
|
||||
*/
|
||||
private class MediaPlayerSeekCompleteListener
|
||||
implements MediaPlayer.OnSeekCompleteListener
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onSeekComplete(final MediaPlayer mp)
|
||||
{
|
||||
onMediaPlayerInfoNative(MEDIA_PLAYER_PROGRESS, getCurrentPosition(), mID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MediaPlayer OnVideoSizeChangedListener
|
||||
*/
|
||||
private class MediaPlayerVideoSizeChangedListener
|
||||
implements MediaPlayer.OnVideoSizeChangedListener
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onVideoSizeChanged(final MediaPlayer mp,
|
||||
final int width,
|
||||
final int height)
|
||||
{
|
||||
onVideoSizeChangedNative(width, height, mID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public QtAndroidMediaPlayer(final long id)
|
||||
{
|
||||
super();
|
||||
mID = id;
|
||||
setOnBufferingUpdateListener(new MediaPlayerBufferingListener());
|
||||
setOnCompletionListener(new MediaPlayerCompletionListener());
|
||||
setOnInfoListener(new MediaPlayerInfoListener());
|
||||
setOnSeekCompleteListener(new MediaPlayerSeekCompleteListener());
|
||||
setOnVideoSizeChangedListener(new MediaPlayerVideoSizeChangedListener());
|
||||
setOnErrorListener(new MediaPlayerErrorListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start()
|
||||
{
|
||||
if (!mInitialized) {
|
||||
onMediaPlayerInfoNative(MEDIA_PLAYER_INVALID_STATE, 0, mID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mApplicationContext == null)
|
||||
return;
|
||||
|
||||
if (mPreparing)
|
||||
return;
|
||||
|
||||
if (isPlaying())
|
||||
return;
|
||||
|
||||
try {
|
||||
super.start();
|
||||
Thread progressThread = new Thread(new ProgressWatcher());
|
||||
progressThread.start();
|
||||
} catch (final IllegalStateException e) {
|
||||
reset();
|
||||
Log.d(TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause()
|
||||
{
|
||||
if (!isPlaying())
|
||||
return;
|
||||
|
||||
try {
|
||||
super.pause();
|
||||
} catch (final IllegalStateException e) {
|
||||
reset();
|
||||
Log.d(TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
if (!mInitialized)
|
||||
return;
|
||||
|
||||
try {
|
||||
super.stop();
|
||||
} catch (final IllegalStateException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
} finally {
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seekTo(final int msec)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return;
|
||||
|
||||
try {
|
||||
super.seekTo(msec);
|
||||
onMediaPlayerInfoNative(MEDIA_PLAYER_PROGRESS, msec, mID);
|
||||
} catch (final IllegalStateException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying()
|
||||
{
|
||||
boolean playing = false;
|
||||
|
||||
if (!mInitialized)
|
||||
return playing;
|
||||
|
||||
try {
|
||||
playing = super.isPlaying();
|
||||
} catch (final IllegalStateException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
}
|
||||
|
||||
return playing;
|
||||
}
|
||||
|
||||
public void setMediaPath(final String path)
|
||||
{
|
||||
if (mInitialized)
|
||||
reset();
|
||||
|
||||
try {
|
||||
mPreparing = true;
|
||||
onMediaPlayerInfoNative(MEDIA_PLAYER_PREPARING, 0, mID);
|
||||
mUri = Uri.parse(path);
|
||||
setDataSource(mApplicationContext, mUri);
|
||||
mInitialized = true;
|
||||
setOnPreparedListener(new MediaPlayerPreparedListener());
|
||||
prepareAsync();
|
||||
} catch (final IOException e) {
|
||||
mPreparing = false;
|
||||
onErrorNative(MEDIA_ERROR_UNKNOWN,
|
||||
/* MEDIA_ERROR_UNSUPPORTED= */ -1010,
|
||||
mID);
|
||||
} catch (final IllegalArgumentException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
} catch (final SecurityException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
} catch (final IllegalStateException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
} catch (final NullPointerException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurrentPosition()
|
||||
{
|
||||
int currentPosition = 0;
|
||||
|
||||
if (!mInitialized)
|
||||
return currentPosition;
|
||||
|
||||
try {
|
||||
currentPosition = super.getCurrentPosition();
|
||||
} catch (final IllegalStateException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
}
|
||||
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDuration()
|
||||
{
|
||||
int duration = 0;
|
||||
|
||||
if (!mInitialized)
|
||||
return duration;
|
||||
|
||||
try {
|
||||
duration = super.getDuration();
|
||||
} catch (final IllegalStateException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
}
|
||||
|
||||
return duration;
|
||||
}
|
||||
|
||||
private float adjustVolume(final int volume)
|
||||
{
|
||||
if (volume < 1)
|
||||
return 0.0f;
|
||||
|
||||
if (volume > 98)
|
||||
return 1.0f;
|
||||
|
||||
return (float) (1-(Math.log(100-volume)/Math.log(100)));
|
||||
}
|
||||
|
||||
public void setVolume(int volume)
|
||||
{
|
||||
if (volume < 0)
|
||||
volume = 0;
|
||||
|
||||
if (volume > 100)
|
||||
volume = 100;
|
||||
|
||||
float newVolume = adjustVolume(volume);
|
||||
|
||||
try {
|
||||
super.setVolume(newVolume, newVolume);
|
||||
if (!mMuted)
|
||||
mVolume = volume;
|
||||
} catch (final IllegalStateException e) {
|
||||
Log.d(TAG, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public int getVolume()
|
||||
{
|
||||
return mVolume;
|
||||
}
|
||||
|
||||
public void mute(final boolean mute)
|
||||
{
|
||||
mMuted = mute;
|
||||
setVolume(mute ? 0 : mVolume);
|
||||
}
|
||||
|
||||
public boolean isMuted()
|
||||
{
|
||||
return mMuted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
mInitialized = false;
|
||||
super.reset();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtMultimedia module 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
package org.qtproject.qt5.android.multimedia;
|
||||
|
||||
import android.graphics.SurfaceTexture;
|
||||
|
||||
public class QtSurfaceTexture implements SurfaceTexture.OnFrameAvailableListener
|
||||
{
|
||||
public SurfaceTexture surfaceTexture;
|
||||
private int texID;
|
||||
|
||||
public QtSurfaceTexture(int texName)
|
||||
{
|
||||
texID = texName;
|
||||
surfaceTexture = new SurfaceTexture(texName);
|
||||
surfaceTexture.setOnFrameAvailableListener(this);
|
||||
}
|
||||
|
||||
public void getTransformMatrix(float[] mtx)
|
||||
{
|
||||
surfaceTexture.getTransformMatrix(mtx);
|
||||
}
|
||||
|
||||
public void updateTexImage()
|
||||
{
|
||||
surfaceTexture.updateTexImage();
|
||||
}
|
||||
|
||||
public void onFrameAvailable(SurfaceTexture surfaceTexture)
|
||||
{
|
||||
notifyFrameAvailable(texID);
|
||||
}
|
||||
|
||||
private static native void notifyFrameAvailable(int id);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the QtMultimedia module 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
package org.qtproject.qt5.android.multimedia;
|
||||
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.Surface;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Canvas;
|
||||
|
||||
public class QtSurfaceTextureHolder implements SurfaceHolder
|
||||
{
|
||||
private Surface surfaceTexture;
|
||||
|
||||
public QtSurfaceTextureHolder(Surface surface)
|
||||
{
|
||||
surfaceTexture = surface;
|
||||
}
|
||||
|
||||
public void addCallback(SurfaceHolder.Callback callback)
|
||||
{
|
||||
}
|
||||
|
||||
public Surface getSurface()
|
||||
{
|
||||
return surfaceTexture;
|
||||
}
|
||||
|
||||
public Rect getSurfaceFrame()
|
||||
{
|
||||
return new Rect();
|
||||
}
|
||||
|
||||
public boolean isCreating()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public Canvas lockCanvas(Rect dirty)
|
||||
{
|
||||
return new Canvas();
|
||||
}
|
||||
|
||||
public Canvas lockCanvas()
|
||||
{
|
||||
return new Canvas();
|
||||
}
|
||||
|
||||
public void removeCallback(SurfaceHolder.Callback callback)
|
||||
{
|
||||
}
|
||||
|
||||
public void setFixedSize(int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
public void setFormat(int format)
|
||||
{
|
||||
}
|
||||
|
||||
public void setKeepScreenOn(boolean screenOn)
|
||||
{
|
||||
}
|
||||
|
||||
public void setSizeFromLayout()
|
||||
{
|
||||
}
|
||||
|
||||
public void setType(int type)
|
||||
{
|
||||
}
|
||||
|
||||
public void unlockCanvasAndPost(Canvas canvas)
|
||||
{
|
||||
}
|
||||
}
|
||||
3
src/plugins/android/mediaplayer/mediaplayer.json
Normal file
3
src/plugins/android/mediaplayer/mediaplayer.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"Keys": ["org.qt-project.qt.mediaplayer"]
|
||||
}
|
||||
24
src/plugins/android/mediaplayer/mediaplayer.pro
Normal file
24
src/plugins/android/mediaplayer/mediaplayer.pro
Normal file
@@ -0,0 +1,24 @@
|
||||
TARGET = androidmediaplayer
|
||||
QT += multimedia-private gui-private platformsupport-private network
|
||||
|
||||
PLUGIN_TYPE = mediaservice
|
||||
PLUGIN_CLASS_NAME = QAndroidMediaPlayerServicePlugin
|
||||
load(qt_plugin)
|
||||
|
||||
HEADERS += \
|
||||
qandroidmediaplayercontrol.h \
|
||||
qandroidmediaservice.h \
|
||||
qandroidmetadatareadercontrol.h \
|
||||
qandroidmediaserviceplugin.h \
|
||||
qandroidvideorendercontrol.h \
|
||||
qandroidvideooutput.h
|
||||
SOURCES += \
|
||||
qandroidmediaplayercontrol.cpp \
|
||||
qandroidmediaservice.cpp \
|
||||
qandroidmetadatareadercontrol.cpp \
|
||||
qandroidmediaserviceplugin.cpp \
|
||||
qandroidvideorendercontrol.cpp
|
||||
|
||||
OTHER_FILES += mediaplayer.json
|
||||
|
||||
include (../wrappers/wrappers.pri)
|
||||
496
src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp
Normal file
496
src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp
Normal file
@@ -0,0 +1,496 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 "qandroidmediaplayercontrol.h"
|
||||
#include "jmediaplayer.h"
|
||||
#include "qandroidvideooutput.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent)
|
||||
: QMediaPlayerControl(parent),
|
||||
mMediaPlayer(new JMediaPlayer),
|
||||
mCurrentState(QMediaPlayer::StoppedState),
|
||||
mCurrentMediaStatus(QMediaPlayer::NoMedia),
|
||||
mMediaStream(0),
|
||||
mVideoOutput(0),
|
||||
mSeekable(true),
|
||||
mBufferPercent(-1),
|
||||
mAudioAvailable(false),
|
||||
mVideoAvailable(false),
|
||||
mBuffering(false),
|
||||
mMediaPlayerReady(false),
|
||||
mPendingPosition(-1)
|
||||
{
|
||||
connect(mMediaPlayer, SIGNAL(bufferingUpdate(qint32)),
|
||||
this, SLOT(onBufferChanged(qint32)));
|
||||
connect(mMediaPlayer, SIGNAL(info(qint32, qint32)),
|
||||
this, SLOT(onInfo(qint32, qint32)));
|
||||
connect(mMediaPlayer, SIGNAL(error(qint32, qint32)),
|
||||
this, SLOT(onError(qint32, qint32)));
|
||||
connect(mMediaPlayer, SIGNAL(mediaPlayerInfo(qint32, qint32)),
|
||||
this, SLOT(onMediaPlayerInfo(qint32, qint32)));
|
||||
connect(mMediaPlayer, SIGNAL(videoSizeChanged(qint32,qint32)),
|
||||
this, SLOT(onVideoSizeChanged(qint32,qint32)));
|
||||
}
|
||||
|
||||
QAndroidMediaPlayerControl::~QAndroidMediaPlayerControl()
|
||||
{
|
||||
delete mMediaPlayer;
|
||||
}
|
||||
|
||||
QMediaPlayer::State QAndroidMediaPlayerControl::state() const
|
||||
{
|
||||
return mCurrentState;
|
||||
}
|
||||
|
||||
QMediaPlayer::MediaStatus QAndroidMediaPlayerControl::mediaStatus() const
|
||||
{
|
||||
return mCurrentMediaStatus;
|
||||
}
|
||||
|
||||
qint64 QAndroidMediaPlayerControl::duration() const
|
||||
{
|
||||
return (mCurrentMediaStatus == QMediaPlayer::InvalidMedia
|
||||
|| mCurrentMediaStatus == QMediaPlayer::NoMedia) ? 0
|
||||
: mMediaPlayer->getDuration();
|
||||
}
|
||||
|
||||
qint64 QAndroidMediaPlayerControl::position() const
|
||||
{
|
||||
if (!mMediaPlayerReady)
|
||||
return mPendingPosition < 0 ? 0 : mPendingPosition;
|
||||
|
||||
return mMediaPlayer->getCurrentPosition();
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setPosition(qint64 position)
|
||||
{
|
||||
if (!mSeekable)
|
||||
return;
|
||||
|
||||
const int seekPosition = (position > INT_MAX) ? INT_MAX : position;
|
||||
|
||||
if (!mMediaPlayerReady) {
|
||||
mPendingPosition = seekPosition;
|
||||
Q_EMIT positionChanged(seekPosition);
|
||||
return;
|
||||
}
|
||||
|
||||
mMediaPlayer->seekTo(seekPosition);
|
||||
mPendingPosition = -1;
|
||||
}
|
||||
|
||||
int QAndroidMediaPlayerControl::volume() const
|
||||
{
|
||||
return mMediaPlayer->volume();
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setVolume(int volume)
|
||||
{
|
||||
mMediaPlayer->setVolume(volume);
|
||||
Q_EMIT volumeChanged(volume);
|
||||
}
|
||||
|
||||
bool QAndroidMediaPlayerControl::isMuted() const
|
||||
{
|
||||
return mMediaPlayer->isMuted();
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setMuted(bool muted)
|
||||
{
|
||||
mMediaPlayer->setMuted(muted);
|
||||
Q_EMIT mutedChanged(muted);
|
||||
}
|
||||
|
||||
int QAndroidMediaPlayerControl::bufferStatus() const
|
||||
{
|
||||
return mBufferPercent;
|
||||
}
|
||||
|
||||
bool QAndroidMediaPlayerControl::isAudioAvailable() const
|
||||
{
|
||||
return mAudioAvailable;
|
||||
}
|
||||
|
||||
bool QAndroidMediaPlayerControl::isVideoAvailable() const
|
||||
{
|
||||
return mVideoAvailable;
|
||||
}
|
||||
|
||||
bool QAndroidMediaPlayerControl::isSeekable() const
|
||||
{
|
||||
return mSeekable;
|
||||
}
|
||||
|
||||
QMediaTimeRange QAndroidMediaPlayerControl::availablePlaybackRanges() const
|
||||
{
|
||||
return mAvailablePlaybackRange;
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::updateAvailablePlaybackRanges()
|
||||
{
|
||||
if (mBuffering) {
|
||||
const qint64 pos = position();
|
||||
const qint64 end = (duration() / 100) * mBufferPercent;
|
||||
mAvailablePlaybackRange.addInterval(pos, end);
|
||||
} else if (mSeekable) {
|
||||
mAvailablePlaybackRange = QMediaTimeRange(0, duration());
|
||||
} else {
|
||||
mAvailablePlaybackRange = QMediaTimeRange();
|
||||
}
|
||||
|
||||
Q_EMIT availablePlaybackRangesChanged(mAvailablePlaybackRange);
|
||||
}
|
||||
|
||||
qreal QAndroidMediaPlayerControl::playbackRate() const
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setPlaybackRate(qreal rate)
|
||||
{
|
||||
Q_UNUSED(rate);
|
||||
}
|
||||
|
||||
QMediaContent QAndroidMediaPlayerControl::media() const
|
||||
{
|
||||
return mMediaContent;
|
||||
}
|
||||
|
||||
const QIODevice *QAndroidMediaPlayerControl::mediaStream() const
|
||||
{
|
||||
return mMediaStream;
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent,
|
||||
QIODevice *stream)
|
||||
{
|
||||
mMediaContent = mediaContent;
|
||||
mMediaStream = stream;
|
||||
|
||||
const QString uri = mediaContent.canonicalUrl().toString();
|
||||
|
||||
if (!uri.isEmpty())
|
||||
mMediaPlayer->setDataSource(uri);
|
||||
else
|
||||
setMediaStatus(QMediaPlayer::NoMedia);
|
||||
|
||||
Q_EMIT mediaChanged(mMediaContent);
|
||||
|
||||
resetBufferingProgress();
|
||||
|
||||
// reset some properties
|
||||
setAudioAvailable(false);
|
||||
setVideoAvailable(false);
|
||||
setSeekable(true);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setVideoOutput(QAndroidVideoOutput *videoOutput)
|
||||
{
|
||||
if (mVideoOutput)
|
||||
mVideoOutput->stop();
|
||||
|
||||
mVideoOutput = videoOutput;
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::play()
|
||||
{
|
||||
if (!mMediaPlayerReady) {
|
||||
mPendingState = QMediaPlayer::PlayingState;
|
||||
if (mCurrentState == QMediaPlayer::StoppedState
|
||||
&& !mMediaContent.isNull()
|
||||
&& mCurrentMediaStatus != QMediaPlayer::LoadingMedia) {
|
||||
setMedia(mMediaContent, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mMediaPlayer->play();
|
||||
setState(QMediaPlayer::PlayingState);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::pause()
|
||||
{
|
||||
if (!mMediaPlayerReady) {
|
||||
mPendingState = QMediaPlayer::PausedState;
|
||||
return;
|
||||
}
|
||||
|
||||
mMediaPlayer->pause();
|
||||
setState(QMediaPlayer::PausedState);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::stop()
|
||||
{
|
||||
mMediaPlayer->stop();
|
||||
setState(QMediaPlayer::StoppedState);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra)
|
||||
{
|
||||
Q_UNUSED(extra);
|
||||
switch (what) {
|
||||
case JMediaPlayer::MEDIA_INFO_UNKNOWN:
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_INFO_VIDEO_TRACK_LAGGING:
|
||||
// IGNORE
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_INFO_VIDEO_RENDERING_START:
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_INFO_BUFFERING_START:
|
||||
mPendingState = mCurrentState;
|
||||
setState(QMediaPlayer::PausedState);
|
||||
setMediaStatus(QMediaPlayer::StalledMedia);
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_INFO_BUFFERING_END:
|
||||
setMediaStatus(mBufferPercent == 100 ? QMediaPlayer::BufferedMedia : QMediaPlayer::BufferingMedia);
|
||||
flushPendingStates();
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_INFO_BAD_INTERLEAVING:
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_INFO_NOT_SEEKABLE:
|
||||
setSeekable(false);
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_INFO_METADATA_UPDATE:
|
||||
Q_EMIT metaDataUpdated();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::onMediaPlayerInfo(qint32 what, qint32 extra)
|
||||
{
|
||||
switch (what) {
|
||||
case JMediaPlayer::MEDIA_PLAYER_INVALID_STATE:
|
||||
setError(what, QStringLiteral("Error: Invalid state"));
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_PLAYER_PREPARING:
|
||||
setMediaStatus(QMediaPlayer::LoadingMedia);
|
||||
setState(QMediaPlayer::StoppedState);
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_PLAYER_READY:
|
||||
if (mBuffering) {
|
||||
setMediaStatus(mBufferPercent == 100 ? QMediaPlayer::BufferedMedia
|
||||
: QMediaPlayer::BufferingMedia);
|
||||
} else {
|
||||
setMediaStatus(QMediaPlayer::LoadedMedia);
|
||||
mBufferPercent = 100;
|
||||
Q_EMIT bufferStatusChanged(mBufferPercent);
|
||||
updateAvailablePlaybackRanges();
|
||||
}
|
||||
setAudioAvailable(true);
|
||||
mMediaPlayerReady = true;
|
||||
flushPendingStates();
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_PLAYER_DURATION:
|
||||
Q_EMIT durationChanged(extra);
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_PLAYER_PROGRESS:
|
||||
Q_EMIT positionChanged(extra);
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_PLAYER_FINISHED:
|
||||
setState(QMediaPlayer::StoppedState);
|
||||
setMediaStatus(QMediaPlayer::EndOfMedia);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra)
|
||||
{
|
||||
QString errorString;
|
||||
QMediaPlayer::Error error = QMediaPlayer::ResourceError;
|
||||
|
||||
switch (what) {
|
||||
case JMediaPlayer::MEDIA_ERROR_UNKNOWN:
|
||||
errorString = QLatin1String("Error:");
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_ERROR_SERVER_DIED:
|
||||
errorString = QLatin1String("Error: Server died");
|
||||
error = QMediaPlayer::ServiceMissingError;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (extra) {
|
||||
case JMediaPlayer::MEDIA_ERROR_IO: // Network OR file error
|
||||
errorString += QLatin1String(" (I/O operation failed)");
|
||||
error = QMediaPlayer::NetworkError;
|
||||
setMediaStatus(QMediaPlayer::InvalidMedia);
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_ERROR_MALFORMED:
|
||||
errorString += QLatin1String(" (Malformed bitstream)");
|
||||
error = QMediaPlayer::FormatError;
|
||||
setMediaStatus(QMediaPlayer::InvalidMedia);
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_ERROR_UNSUPPORTED:
|
||||
errorString += QLatin1String(" (Unsupported media)");
|
||||
error = QMediaPlayer::FormatError;
|
||||
setMediaStatus(QMediaPlayer::InvalidMedia);
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_ERROR_TIMED_OUT:
|
||||
errorString += QLatin1String(" (Timed out)");
|
||||
break;
|
||||
case JMediaPlayer::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
|
||||
errorString += QLatin1String(" (Unable to start progressive playback')");
|
||||
error = QMediaPlayer::FormatError;
|
||||
setMediaStatus(QMediaPlayer::InvalidMedia);
|
||||
break;
|
||||
}
|
||||
|
||||
setError(error, errorString);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::onBufferChanged(qint32 percent)
|
||||
{
|
||||
mBuffering = true;
|
||||
mBufferPercent = percent;
|
||||
Q_EMIT bufferStatusChanged(mBufferPercent);
|
||||
|
||||
updateAvailablePlaybackRanges();
|
||||
|
||||
if (mBufferPercent == 100)
|
||||
setMediaStatus(QMediaPlayer::BufferedMedia);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::onVideoSizeChanged(qint32 width, qint32 height)
|
||||
{
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
setVideoAvailable(true);
|
||||
|
||||
if (mVideoOutput) {
|
||||
if (!mMediaPlayer->display())
|
||||
mMediaPlayer->setDisplay(mVideoOutput->surfaceHolder());
|
||||
if (mMediaPlayer->display())
|
||||
mVideoOutput->setVideoSize(QSize(width, height));
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setState(QMediaPlayer::State state)
|
||||
{
|
||||
if (mCurrentState == state)
|
||||
return;
|
||||
|
||||
if (state == QMediaPlayer::StoppedState) {
|
||||
if (mVideoOutput)
|
||||
mVideoOutput->stop();
|
||||
resetBufferingProgress();
|
||||
mMediaPlayerReady = false;
|
||||
mPendingPosition = -1;
|
||||
Q_EMIT positionChanged(0);
|
||||
}
|
||||
|
||||
mCurrentState = state;
|
||||
Q_EMIT stateChanged(mCurrentState);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status)
|
||||
{
|
||||
if (mCurrentMediaStatus == status)
|
||||
return;
|
||||
|
||||
if (status == QMediaPlayer::NoMedia || status == QMediaPlayer::InvalidMedia)
|
||||
Q_EMIT durationChanged(0);
|
||||
|
||||
mCurrentMediaStatus = status;
|
||||
Q_EMIT mediaStatusChanged(mCurrentMediaStatus);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setError(int error,
|
||||
const QString &errorString)
|
||||
{
|
||||
setState(QMediaPlayer::StoppedState);
|
||||
Q_EMIT QMediaPlayerControl::error(error, errorString);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setSeekable(bool seekable)
|
||||
{
|
||||
if (mSeekable == seekable)
|
||||
return;
|
||||
|
||||
mSeekable = seekable;
|
||||
Q_EMIT seekableChanged(mSeekable);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setAudioAvailable(bool available)
|
||||
{
|
||||
if (mAudioAvailable == available)
|
||||
return;
|
||||
|
||||
mAudioAvailable = available;
|
||||
Q_EMIT audioAvailableChanged(mAudioAvailable);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::setVideoAvailable(bool available)
|
||||
{
|
||||
if (mVideoAvailable == available)
|
||||
return;
|
||||
|
||||
mVideoAvailable = available;
|
||||
Q_EMIT videoAvailableChanged(mVideoAvailable);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::resetBufferingProgress()
|
||||
{
|
||||
mBuffering = false;
|
||||
mBufferPercent = 0;
|
||||
mAvailablePlaybackRange = QMediaTimeRange();
|
||||
Q_EMIT bufferStatusChanged(mBufferPercent);
|
||||
}
|
||||
|
||||
void QAndroidMediaPlayerControl::flushPendingStates()
|
||||
{
|
||||
switch (mPendingState) {
|
||||
case QMediaPlayer::PlayingState:
|
||||
if (mPendingPosition > -1)
|
||||
setPosition(mPendingPosition);
|
||||
play();
|
||||
break;
|
||||
case QMediaPlayer::PausedState:
|
||||
pause();
|
||||
break;
|
||||
case QMediaPlayer::StoppedState:
|
||||
stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
127
src/plugins/android/mediaplayer/qandroidmediaplayercontrol.h
Normal file
127
src/plugins/android/mediaplayer/qandroidmediaplayercontrol.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 QANDROIDMEDIAPLAYERCONTROL_H
|
||||
#define QANDROIDMEDIAPLAYERCONTROL_H
|
||||
|
||||
#include <qglobal.h>
|
||||
#include <QMediaPlayerControl>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class JMediaPlayer;
|
||||
class QAndroidVideoOutput;
|
||||
|
||||
class QAndroidMediaPlayerControl : public QMediaPlayerControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QAndroidMediaPlayerControl(QObject *parent = 0);
|
||||
~QAndroidMediaPlayerControl() Q_DECL_OVERRIDE;
|
||||
|
||||
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;
|
||||
int volume() const Q_DECL_OVERRIDE;
|
||||
bool isMuted() const 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 &mediaContent, QIODevice *stream) Q_DECL_OVERRIDE;
|
||||
|
||||
void setVideoOutput(QAndroidVideoOutput *videoOutput);
|
||||
|
||||
Q_SIGNALS:
|
||||
void metaDataUpdated();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setPosition(qint64 position) Q_DECL_OVERRIDE;
|
||||
void play() Q_DECL_OVERRIDE;
|
||||
void pause() Q_DECL_OVERRIDE;
|
||||
void stop() Q_DECL_OVERRIDE;
|
||||
void setVolume(int volume) Q_DECL_OVERRIDE;
|
||||
void setMuted(bool muted) Q_DECL_OVERRIDE;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onError(qint32 what, qint32 extra);
|
||||
void onInfo(qint32 what, qint32 extra);
|
||||
void onMediaPlayerInfo(qint32 what, qint32 extra);
|
||||
void onBufferChanged(qint32 percent);
|
||||
void onVideoSizeChanged(qint32 width, qint32 height);
|
||||
|
||||
private:
|
||||
JMediaPlayer *mMediaPlayer;
|
||||
QMediaPlayer::State mCurrentState;
|
||||
QMediaPlayer::MediaStatus mCurrentMediaStatus;
|
||||
QMediaContent mMediaContent;
|
||||
QIODevice *mMediaStream;
|
||||
QAndroidVideoOutput *mVideoOutput;
|
||||
bool mSeekable;
|
||||
int mBufferPercent;
|
||||
bool mAudioAvailable;
|
||||
bool mVideoAvailable;
|
||||
bool mBuffering;
|
||||
QMediaTimeRange mAvailablePlaybackRange;
|
||||
bool mMediaPlayerReady;
|
||||
QMediaPlayer::State mPendingState;
|
||||
qint64 mPendingPosition;
|
||||
|
||||
void setState(QMediaPlayer::State state);
|
||||
void setMediaStatus(QMediaPlayer::MediaStatus status);
|
||||
void setError(int error, const QString &errorString);
|
||||
void setSeekable(bool seekable);
|
||||
void setAudioAvailable(bool available);
|
||||
void setVideoAvailable(bool available);
|
||||
void updateAvailablePlaybackRanges();
|
||||
void resetBufferingProgress();
|
||||
void flushPendingStates();
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDMEDIAPLAYERCONTROL_H
|
||||
97
src/plugins/android/mediaplayer/qandroidmediaservice.cpp
Normal file
97
src/plugins/android/mediaplayer/qandroidmediaservice.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 "qandroidmediaservice.h"
|
||||
|
||||
#include "qandroidmediaplayercontrol.h"
|
||||
#include "qandroidmetadatareadercontrol.h"
|
||||
#include "qandroidvideorendercontrol.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QAndroidMediaService::QAndroidMediaService(QObject *parent)
|
||||
: QMediaService(parent)
|
||||
, mVideoRendererControl(0)
|
||||
{
|
||||
mMediaControl = new QAndroidMediaPlayerControl;
|
||||
mMetadataControl = new QAndroidMetaDataReaderControl;
|
||||
connect(mMediaControl, SIGNAL(mediaChanged(QMediaContent)),
|
||||
mMetadataControl, SLOT(onMediaChanged(QMediaContent)));
|
||||
connect(mMediaControl, SIGNAL(metaDataUpdated()),
|
||||
mMetadataControl, SLOT(onUpdateMetaData()));
|
||||
}
|
||||
|
||||
QAndroidMediaService::~QAndroidMediaService()
|
||||
{
|
||||
delete mMediaControl;
|
||||
delete mMetadataControl;
|
||||
delete mVideoRendererControl;
|
||||
}
|
||||
|
||||
QMediaControl *QAndroidMediaService::requestControl(const char *name)
|
||||
{
|
||||
if (qstrcmp(name, QMediaPlayerControl_iid) == 0)
|
||||
return mMediaControl;
|
||||
|
||||
if (qstrcmp(name, QMetaDataReaderControl_iid) == 0)
|
||||
return mMetadataControl;
|
||||
|
||||
if (qstrcmp(name, QVideoRendererControl_iid) == 0) {
|
||||
if (!mVideoRendererControl) {
|
||||
mVideoRendererControl = new QAndroidVideoRendererControl;
|
||||
mMediaControl->setVideoOutput(mVideoRendererControl);
|
||||
return mVideoRendererControl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QAndroidMediaService::releaseControl(QMediaControl *control)
|
||||
{
|
||||
if (control == mVideoRendererControl) {
|
||||
mMediaControl->setVideoOutput(0);
|
||||
delete mVideoRendererControl;
|
||||
mVideoRendererControl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
71
src/plugins/android/mediaplayer/qandroidmediaservice.h
Normal file
71
src/plugins/android/mediaplayer/qandroidmediaservice.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 QANDROIDMEDIASERVICE_H
|
||||
#define QANDROIDMEDIASERVICE_H
|
||||
|
||||
#include <QMediaService>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAndroidMediaPlayerControl;
|
||||
class QAndroidMetaDataReaderControl;
|
||||
class QAndroidVideoRendererControl;
|
||||
|
||||
class QAndroidMediaService : public QMediaService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QAndroidMediaService(QObject *parent = 0);
|
||||
~QAndroidMediaService() Q_DECL_OVERRIDE;
|
||||
|
||||
QMediaControl* requestControl(const char *name) Q_DECL_OVERRIDE;
|
||||
void releaseControl(QMediaControl *control) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QAndroidMediaPlayerControl *mMediaControl;
|
||||
QAndroidMetaDataReaderControl *mMetadataControl;
|
||||
QAndroidVideoRendererControl *mVideoRendererControl;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDMEDIASERVICE_H
|
||||
107
src/plugins/android/mediaplayer/qandroidmediaserviceplugin.cpp
Normal file
107
src/plugins/android/mediaplayer/qandroidmediaserviceplugin.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 "qandroidmediaserviceplugin.h"
|
||||
|
||||
#include "qandroidmediaservice.h"
|
||||
#include "jmediaplayer.h"
|
||||
#include "jsurfacetexture.h"
|
||||
#include "jsurfacetextureholder.h"
|
||||
#include <qdebug.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QAndroidMediaServicePlugin::QAndroidMediaServicePlugin()
|
||||
{
|
||||
}
|
||||
|
||||
QAndroidMediaServicePlugin::~QAndroidMediaServicePlugin()
|
||||
{
|
||||
}
|
||||
|
||||
QMediaService *QAndroidMediaServicePlugin::create(const QString &key)
|
||||
{
|
||||
if (key == QStringLiteral(Q_MEDIASERVICE_MEDIAPLAYER))
|
||||
return new QAndroidMediaService;
|
||||
|
||||
qWarning() << "Android service plugin: unsupported key:" << key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QAndroidMediaServicePlugin::release(QMediaService *service)
|
||||
{
|
||||
delete service;
|
||||
}
|
||||
|
||||
QMediaServiceProviderHint::Features QAndroidMediaServicePlugin::supportedFeatures(const QByteArray &service) const
|
||||
{
|
||||
if (service == Q_MEDIASERVICE_MEDIAPLAYER)
|
||||
return QMediaServiceProviderHint::VideoSurface;
|
||||
|
||||
return QMediaServiceProviderHint::Features();
|
||||
}
|
||||
|
||||
|
||||
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/)
|
||||
{
|
||||
typedef union {
|
||||
JNIEnv *nativeEnvironment;
|
||||
void *venv;
|
||||
} UnionJNIEnvToVoid;
|
||||
|
||||
UnionJNIEnvToVoid uenv;
|
||||
uenv.venv = NULL;
|
||||
|
||||
if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK)
|
||||
return JNI_ERR;
|
||||
|
||||
JNIEnv *jniEnv = uenv.nativeEnvironment;
|
||||
|
||||
if (!JMediaPlayer::initJNI(jniEnv) ||
|
||||
!JSurfaceTexture::initJNI(jniEnv) ||
|
||||
!JSurfaceTextureHolder::initJNI(jniEnv)) {
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
72
src/plugins/android/mediaplayer/qandroidmediaserviceplugin.h
Normal file
72
src/plugins/android/mediaplayer/qandroidmediaserviceplugin.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 QANDROIDMEDIASERVICEPLUGIN_H
|
||||
#define QANDROIDMEDIASERVICEPLUGIN_H
|
||||
|
||||
#include <QMediaServiceProviderPlugin>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QMediaService;
|
||||
class QAndroidMediaService;
|
||||
|
||||
class QAndroidMediaServicePlugin
|
||||
: public QMediaServiceProviderPlugin
|
||||
, public QMediaServiceFeaturesInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QMediaServiceFeaturesInterface)
|
||||
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0"
|
||||
FILE "mediaplayer.json")
|
||||
|
||||
public:
|
||||
QAndroidMediaServicePlugin();
|
||||
~QAndroidMediaServicePlugin();
|
||||
|
||||
QMediaService* create(QString const& key) Q_DECL_OVERRIDE;
|
||||
void release(QMediaService *service) Q_DECL_OVERRIDE;
|
||||
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDMEDIASERVICEPLUGIN_H
|
||||
@@ -0,0 +1,221 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 "qandroidmetadatareadercontrol.h"
|
||||
|
||||
#include "jmediametadataretriever.h"
|
||||
#include <qsize.h>
|
||||
#include <QDate>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
// Genre name ordered by ID
|
||||
// see: http://id3.org/id3v2.3.0#Appendix_A_-_Genre_List_from_ID3v1
|
||||
static const char* qt_ID3GenreNames[] =
|
||||
{
|
||||
"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz",
|
||||
"Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno",
|
||||
"Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno",
|
||||
"Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental",
|
||||
"Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk",
|
||||
"Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave",
|
||||
"Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy",
|
||||
"Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American",
|
||||
"Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal",
|
||||
"Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk",
|
||||
"Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic",
|
||||
"Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock",
|
||||
"Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour",
|
||||
"Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus",
|
||||
"Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad",
|
||||
"Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A capella",
|
||||
"Euro-House", "Dance Hall"
|
||||
};
|
||||
|
||||
QAndroidMetaDataReaderControl::QAndroidMetaDataReaderControl(QObject *parent)
|
||||
: QMetaDataReaderControl(parent)
|
||||
, m_available(false)
|
||||
, m_retriever(0)
|
||||
{
|
||||
m_retriever = new JMediaMetadataRetriever;
|
||||
if (!m_retriever->isValid()) {
|
||||
delete m_retriever;
|
||||
m_retriever = 0;
|
||||
}
|
||||
}
|
||||
|
||||
QAndroidMetaDataReaderControl::~QAndroidMetaDataReaderControl()
|
||||
{
|
||||
if (m_retriever) {
|
||||
m_retriever->release();
|
||||
delete m_retriever;
|
||||
}
|
||||
}
|
||||
|
||||
bool QAndroidMetaDataReaderControl::isMetaDataAvailable() const
|
||||
{
|
||||
return m_available;
|
||||
}
|
||||
|
||||
QVariant QAndroidMetaDataReaderControl::metaData(const QString &key) const
|
||||
{
|
||||
return m_metadata.value(key);
|
||||
}
|
||||
|
||||
QStringList QAndroidMetaDataReaderControl::availableMetaData() const
|
||||
{
|
||||
return m_metadata.keys();
|
||||
}
|
||||
|
||||
void QAndroidMetaDataReaderControl::onMediaChanged(const QMediaContent &media)
|
||||
{
|
||||
if (!m_retriever)
|
||||
return;
|
||||
|
||||
m_mediaContent = media;
|
||||
updateData();
|
||||
}
|
||||
|
||||
void QAndroidMetaDataReaderControl::onUpdateMetaData()
|
||||
{
|
||||
if (!m_retriever || m_mediaContent.isNull())
|
||||
return;
|
||||
|
||||
updateData();
|
||||
}
|
||||
|
||||
void QAndroidMetaDataReaderControl::updateData()
|
||||
{
|
||||
m_metadata.clear();
|
||||
|
||||
if (!m_mediaContent.isNull()) {
|
||||
if (m_retriever->setDataSource(m_mediaContent.canonicalUrl())) {
|
||||
QString mimeType = m_retriever->extractMetadata(JMediaMetadataRetriever::MimeType);
|
||||
if (!mimeType.isNull())
|
||||
m_metadata.insert(QMediaMetaData::MediaType, mimeType);
|
||||
|
||||
bool isVideo = !m_retriever->extractMetadata(JMediaMetadataRetriever::HasVideo).isNull()
|
||||
|| mimeType.startsWith(QStringLiteral("video"));
|
||||
|
||||
QString string = m_retriever->extractMetadata(JMediaMetadataRetriever::Album);
|
||||
if (!string.isNull())
|
||||
m_metadata.insert(QMediaMetaData::AlbumTitle, string);
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::AlbumArtist);
|
||||
if (!string.isNull())
|
||||
m_metadata.insert(QMediaMetaData::AlbumArtist, string);
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::Artist);
|
||||
if (!string.isNull()) {
|
||||
m_metadata.insert(isVideo ? QMediaMetaData::LeadPerformer
|
||||
: QMediaMetaData::ContributingArtist,
|
||||
string.split('/', QString::SkipEmptyParts));
|
||||
}
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::Author);
|
||||
if (!string.isNull())
|
||||
m_metadata.insert(QMediaMetaData::Author, string.split('/', QString::SkipEmptyParts));
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::Bitrate);
|
||||
if (!string.isNull()) {
|
||||
m_metadata.insert(isVideo ? QMediaMetaData::VideoBitRate
|
||||
: QMediaMetaData::AudioBitRate,
|
||||
string.toInt());
|
||||
}
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::CDTrackNumber);
|
||||
if (!string.isNull())
|
||||
m_metadata.insert(QMediaMetaData::TrackNumber, string.toInt());
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::Composer);
|
||||
if (!string.isNull())
|
||||
m_metadata.insert(QMediaMetaData::Composer, string.split('/', QString::SkipEmptyParts));
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::Date);
|
||||
if (!string.isNull())
|
||||
m_metadata.insert(QMediaMetaData::Date, QDateTime::fromString(string, QStringLiteral("yyyyMMddTHHmmss.zzzZ")).date());
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::Duration);
|
||||
if (!string.isNull())
|
||||
m_metadata.insert(QMediaMetaData::Duration, string.toLongLong());
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::Genre);
|
||||
if (!string.isNull()) {
|
||||
// The genre can be returned as an ID3v2 id, get the name for it in that case
|
||||
if (string.startsWith('(') && string.endsWith(')')) {
|
||||
bool ok = false;
|
||||
int genreId = string.mid(1, string.length() - 2).toInt(&ok);
|
||||
if (ok && genreId >= 0 && genreId <= 125)
|
||||
string = QLatin1String(qt_ID3GenreNames[genreId]);
|
||||
}
|
||||
m_metadata.insert(QMediaMetaData::Genre, string);
|
||||
}
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::Title);
|
||||
if (!string.isNull())
|
||||
m_metadata.insert(QMediaMetaData::Title, string);
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::VideoHeight);
|
||||
if (!string.isNull()) {
|
||||
int height = string.toInt();
|
||||
int width = m_retriever->extractMetadata(JMediaMetadataRetriever::VideoWidth).toInt();
|
||||
m_metadata.insert(QMediaMetaData::Resolution, QSize(width, height));
|
||||
}
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::Writer);
|
||||
if (!string.isNull())
|
||||
m_metadata.insert(QMediaMetaData::Writer, string.split('/', QString::SkipEmptyParts));
|
||||
|
||||
string = m_retriever->extractMetadata(JMediaMetadataRetriever::Year);
|
||||
if (!string.isNull())
|
||||
m_metadata.insert(QMediaMetaData::Year, string.toInt());
|
||||
}
|
||||
}
|
||||
|
||||
bool oldAvailable = m_available;
|
||||
m_available = !m_metadata.isEmpty();
|
||||
if (m_available != oldAvailable)
|
||||
Q_EMIT metaDataAvailableChanged(m_available);
|
||||
|
||||
Q_EMIT metaDataChanged();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
@@ -0,0 +1,80 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 QANDROIDMETADATAREADERCONTROL_H
|
||||
#define QANDROIDMETADATAREADERCONTROL_H
|
||||
|
||||
#include <QMetaDataReaderControl>
|
||||
#include <qmediacontent.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class JMediaMetadataRetriever;
|
||||
|
||||
class QAndroidMetaDataReaderControl : public QMetaDataReaderControl
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QAndroidMetaDataReaderControl(QObject *parent = 0);
|
||||
~QAndroidMetaDataReaderControl() Q_DECL_OVERRIDE;
|
||||
|
||||
bool isMetaDataAvailable() const Q_DECL_OVERRIDE;
|
||||
|
||||
QVariant metaData(const QString &key) const Q_DECL_OVERRIDE;
|
||||
QStringList availableMetaData() const Q_DECL_OVERRIDE;
|
||||
|
||||
public Q_SLOTS:
|
||||
void onMediaChanged(const QMediaContent &media);
|
||||
void onUpdateMetaData();
|
||||
|
||||
private:
|
||||
void updateData();
|
||||
|
||||
QMediaContent m_mediaContent;
|
||||
bool m_available;
|
||||
QVariantMap m_metadata;
|
||||
|
||||
JMediaMetadataRetriever *m_retriever;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDMETADATAREADERCONTROL_H
|
||||
64
src/plugins/android/mediaplayer/qandroidvideooutput.h
Normal file
64
src/plugins/android/mediaplayer/qandroidvideooutput.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 QANDROIDVIDEOOUTPUT_H
|
||||
#define QANDROIDVIDEOOUTPUT_H
|
||||
|
||||
#include <qglobal.h>
|
||||
#include <qsize.h>
|
||||
#include <jni.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QAndroidVideoOutput
|
||||
{
|
||||
public:
|
||||
QAndroidVideoOutput() { }
|
||||
virtual ~QAndroidVideoOutput() { }
|
||||
|
||||
virtual jobject surfaceHolder() = 0;
|
||||
virtual void setVideoSize(const QSize &size) = 0;
|
||||
virtual void stop() = 0;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDVIDEOOUTPUT_H
|
||||
375
src/plugins/android/mediaplayer/qandroidvideorendercontrol.cpp
Normal file
375
src/plugins/android/mediaplayer/qandroidvideorendercontrol.cpp
Normal file
@@ -0,0 +1,375 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 "qandroidvideorendercontrol.h"
|
||||
|
||||
#include <QtPlatformSupport/private/qjnihelpers_p.h>
|
||||
#include "jsurfacetextureholder.h"
|
||||
#include <QAbstractVideoSurface>
|
||||
#include <QOpenGLContext>
|
||||
#include <QOffscreenSurface>
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#include <QVideoSurfaceFormat>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLShaderProgram>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static const GLfloat g_vertex_data[] = {
|
||||
-1.f, 1.f,
|
||||
1.f, 1.f,
|
||||
1.f, -1.f,
|
||||
-1.f, -1.f
|
||||
};
|
||||
|
||||
static const GLfloat g_texture_data[] = {
|
||||
0.f, 0.f,
|
||||
1.f, 0.f,
|
||||
1.f, 1.f,
|
||||
0.f, 1.f
|
||||
};
|
||||
|
||||
class TextureVideoBuffer : public QAbstractVideoBuffer
|
||||
{
|
||||
public:
|
||||
TextureVideoBuffer(GLuint textureId)
|
||||
: QAbstractVideoBuffer(GLTextureHandle)
|
||||
, m_textureId(textureId)
|
||||
{}
|
||||
|
||||
virtual ~TextureVideoBuffer() {}
|
||||
|
||||
MapMode mapMode() const { return NotMapped; }
|
||||
uchar *map(MapMode, int*, int*) { return 0; }
|
||||
void unmap() {}
|
||||
|
||||
QVariant handle() const
|
||||
{
|
||||
return QVariant::fromValue<unsigned int>(m_textureId);
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint m_textureId;
|
||||
};
|
||||
|
||||
class ImageVideoBuffer : public QAbstractVideoBuffer
|
||||
{
|
||||
public:
|
||||
ImageVideoBuffer(const QImage &image)
|
||||
: QAbstractVideoBuffer(NoHandle)
|
||||
, m_image(image)
|
||||
, m_mode(NotMapped)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MapMode mapMode() const { return m_mode; }
|
||||
uchar *map(MapMode mode, int *, int *)
|
||||
{
|
||||
if (mode != NotMapped && m_mode == NotMapped) {
|
||||
m_mode = mode;
|
||||
return m_image.bits();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void unmap()
|
||||
{
|
||||
m_mode = NotMapped;
|
||||
}
|
||||
|
||||
private:
|
||||
QImage m_image;
|
||||
MapMode m_mode;
|
||||
};
|
||||
|
||||
QAndroidVideoRendererControl::QAndroidVideoRendererControl(QObject *parent)
|
||||
: QVideoRendererControl(parent)
|
||||
, m_surface(0)
|
||||
, m_offscreenSurface(0)
|
||||
, m_glContext(0)
|
||||
, m_fbo(0)
|
||||
, m_program(0)
|
||||
, m_useImage(false)
|
||||
, m_androidSurface(0)
|
||||
, m_surfaceTexture(0)
|
||||
, m_surfaceHolder(0)
|
||||
, m_externalTex(0)
|
||||
{
|
||||
}
|
||||
|
||||
QAndroidVideoRendererControl::~QAndroidVideoRendererControl()
|
||||
{
|
||||
if (m_glContext)
|
||||
m_glContext->makeCurrent(m_offscreenSurface);
|
||||
|
||||
if (m_surfaceTexture) {
|
||||
QJNILocalRef<jobject> surfaceTex = m_surfaceTexture->surfaceTexture();
|
||||
QJNIObject obj(surfaceTex.object());
|
||||
obj.callMethod<void>("release");
|
||||
delete m_surfaceTexture;
|
||||
m_surfaceTexture = 0;
|
||||
}
|
||||
if (m_androidSurface) {
|
||||
m_androidSurface->callMethod<void>("release");
|
||||
delete m_androidSurface;
|
||||
m_androidSurface = 0;
|
||||
}
|
||||
if (m_surfaceHolder) {
|
||||
delete m_surfaceHolder;
|
||||
m_surfaceHolder = 0;
|
||||
}
|
||||
if (m_externalTex)
|
||||
glDeleteTextures(1, &m_externalTex);
|
||||
|
||||
delete m_fbo;
|
||||
delete m_program;
|
||||
delete m_glContext;
|
||||
delete m_offscreenSurface;
|
||||
}
|
||||
|
||||
QAbstractVideoSurface *QAndroidVideoRendererControl::surface() const
|
||||
{
|
||||
return m_surface;
|
||||
}
|
||||
|
||||
void QAndroidVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
|
||||
{
|
||||
if (surface == m_surface)
|
||||
return;
|
||||
|
||||
if (m_surface && m_surface->isActive())
|
||||
m_surface->stop();
|
||||
|
||||
m_surface = surface;
|
||||
|
||||
m_useImage = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).contains(QVideoFrame::Format_BGR32);
|
||||
}
|
||||
|
||||
jobject QAndroidVideoRendererControl::surfaceHolder()
|
||||
{
|
||||
if (m_surfaceHolder)
|
||||
return m_surfaceHolder->object();
|
||||
|
||||
QOpenGLContext *currContext = QOpenGLContext::currentContext();
|
||||
|
||||
// If we don't have a GL context in the current thread, create one and share it
|
||||
// with the render thread GL context
|
||||
if (!currContext && !m_glContext) {
|
||||
m_offscreenSurface = new QOffscreenSurface;
|
||||
QSurfaceFormat format;
|
||||
format.setSwapBehavior(QSurfaceFormat::SingleBuffer);
|
||||
m_offscreenSurface->setFormat(format);
|
||||
m_offscreenSurface->create();
|
||||
|
||||
QOpenGLContext *shareContext = 0;
|
||||
if (m_surface)
|
||||
shareContext = qobject_cast<QOpenGLContext*>(m_surface->property("GLContext").value<QObject*>());
|
||||
m_glContext = new QOpenGLContext;
|
||||
m_glContext->setFormat(m_offscreenSurface->requestedFormat());
|
||||
|
||||
if (shareContext)
|
||||
m_glContext->setShareContext(shareContext);
|
||||
|
||||
if (!m_glContext->create())
|
||||
return 0;
|
||||
|
||||
// if sharing contexts is not supported, fallback to image rendering and send the bits
|
||||
// to the video surface
|
||||
if (!m_glContext->shareContext())
|
||||
m_useImage = true;
|
||||
}
|
||||
|
||||
if (m_glContext)
|
||||
m_glContext->makeCurrent(m_offscreenSurface);
|
||||
|
||||
glGenTextures(1, &m_externalTex);
|
||||
m_surfaceTexture = new JSurfaceTexture(m_externalTex);
|
||||
|
||||
if (m_surfaceTexture->isValid()) {
|
||||
connect(m_surfaceTexture, SIGNAL(frameAvailable()), this, SLOT(onFrameAvailable()));
|
||||
|
||||
QJNILocalRef<jobject> surfaceTex = m_surfaceTexture->surfaceTexture();
|
||||
|
||||
m_androidSurface = new QJNIObject("android/view/Surface",
|
||||
"(Landroid/graphics/SurfaceTexture;)V",
|
||||
surfaceTex.object());
|
||||
|
||||
m_surfaceHolder = new JSurfaceTextureHolder(m_androidSurface->object());
|
||||
} else {
|
||||
delete m_surfaceTexture;
|
||||
m_surfaceTexture = 0;
|
||||
glDeleteTextures(1, &m_externalTex);
|
||||
}
|
||||
|
||||
if (m_surfaceHolder)
|
||||
return m_surfaceHolder->object();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QAndroidVideoRendererControl::setVideoSize(const QSize &size)
|
||||
{
|
||||
if (m_nativeSize == size)
|
||||
return;
|
||||
|
||||
m_nativeSize = size;
|
||||
|
||||
delete m_fbo;
|
||||
m_fbo = 0;
|
||||
}
|
||||
|
||||
void QAndroidVideoRendererControl::stop()
|
||||
{
|
||||
if (m_surface && m_surface->isActive())
|
||||
m_surface->stop();
|
||||
m_nativeSize = QSize();
|
||||
}
|
||||
|
||||
void QAndroidVideoRendererControl::onFrameAvailable()
|
||||
{
|
||||
if (m_glContext)
|
||||
m_glContext->makeCurrent(m_offscreenSurface);
|
||||
|
||||
m_surfaceTexture->updateTexImage();
|
||||
|
||||
if (!m_nativeSize.isValid())
|
||||
return;
|
||||
|
||||
renderFrameToFbo();
|
||||
|
||||
QAbstractVideoBuffer *buffer = 0;
|
||||
QVideoFrame frame;
|
||||
|
||||
if (m_useImage) {
|
||||
buffer = new ImageVideoBuffer(m_fbo->toImage().mirrored());
|
||||
frame = QVideoFrame(buffer, m_nativeSize, QVideoFrame::Format_RGB32);
|
||||
} else {
|
||||
buffer = new TextureVideoBuffer(m_fbo->texture());
|
||||
frame = QVideoFrame(buffer, m_nativeSize, QVideoFrame::Format_BGR32);
|
||||
}
|
||||
|
||||
if (m_surface && frame.isValid()) {
|
||||
if (m_surface->isActive() && (m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat()
|
||||
|| m_surface->nativeResolution() != frame.size())) {
|
||||
m_surface->stop();
|
||||
}
|
||||
|
||||
if (!m_surface->isActive()) {
|
||||
QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(),
|
||||
m_useImage ? QAbstractVideoBuffer::NoHandle
|
||||
: QAbstractVideoBuffer::GLTextureHandle);
|
||||
|
||||
m_surface->start(format);
|
||||
}
|
||||
|
||||
if (m_surface->isActive())
|
||||
m_surface->present(frame);
|
||||
}
|
||||
}
|
||||
|
||||
void QAndroidVideoRendererControl::renderFrameToFbo()
|
||||
{
|
||||
createGLResources();
|
||||
|
||||
m_fbo->bind();
|
||||
|
||||
glViewport(0, 0, m_nativeSize.width(), m_nativeSize.height());
|
||||
|
||||
m_program->bind();
|
||||
m_program->enableAttributeArray(0);
|
||||
m_program->enableAttributeArray(1);
|
||||
m_program->setUniformValue("frameTexture", GLuint(0));
|
||||
m_program->setUniformValue("texMatrix", m_surfaceTexture->getTransformMatrix());
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, g_vertex_data);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, g_texture_data);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
m_program->disableAttributeArray(0);
|
||||
m_program->disableAttributeArray(1);
|
||||
m_program->release();
|
||||
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
|
||||
m_fbo->release();
|
||||
|
||||
glFinish();
|
||||
}
|
||||
|
||||
void QAndroidVideoRendererControl::createGLResources()
|
||||
{
|
||||
if (!m_fbo)
|
||||
m_fbo = new QOpenGLFramebufferObject(m_nativeSize);
|
||||
|
||||
if (!m_program) {
|
||||
m_program = new QOpenGLShaderProgram;
|
||||
|
||||
QOpenGLShader *vertexShader = new QOpenGLShader(QOpenGLShader::Vertex, m_program);
|
||||
vertexShader->compileSourceCode("attribute highp vec4 vertexCoordsArray; \n" \
|
||||
"attribute highp vec2 textureCoordArray; \n" \
|
||||
"uniform highp mat4 texMatrix; \n" \
|
||||
"varying highp vec2 textureCoords; \n" \
|
||||
"void main(void) \n" \
|
||||
"{ \n" \
|
||||
" gl_Position = vertexCoordsArray; \n" \
|
||||
" textureCoords = (texMatrix * vec4(textureCoordArray, 0.0, 1.0)).xy; \n" \
|
||||
"}\n");
|
||||
m_program->addShader(vertexShader);
|
||||
|
||||
QOpenGLShader *fragmentShader = new QOpenGLShader(QOpenGLShader::Fragment, m_program);
|
||||
fragmentShader->compileSourceCode("#extension GL_OES_EGL_image_external : require \n" \
|
||||
"varying highp vec2 textureCoords; \n" \
|
||||
"uniform samplerExternalOES frameTexture; \n" \
|
||||
"void main() \n" \
|
||||
"{ \n" \
|
||||
" gl_FragColor = texture2D(frameTexture, textureCoords); \n" \
|
||||
"}\n");
|
||||
m_program->addShader(fragmentShader);
|
||||
|
||||
m_program->bindAttributeLocation("vertexCoordsArray", 0);
|
||||
m_program->bindAttributeLocation("textureCoordArray", 1);
|
||||
m_program->link();
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
95
src/plugins/android/mediaplayer/qandroidvideorendercontrol.h
Normal file
95
src/plugins/android/mediaplayer/qandroidvideorendercontrol.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 QANDROIDVIDEORENDERCONTROL_H
|
||||
#define QANDROIDVIDEORENDERCONTROL_H
|
||||
|
||||
#include <qvideorenderercontrol.h>
|
||||
#include "qandroidvideooutput.h"
|
||||
#include "jsurfacetexture.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QOpenGLContext;
|
||||
class QOffscreenSurface;
|
||||
class QOpenGLFramebufferObject;
|
||||
class QOpenGLShaderProgram;
|
||||
class JSurfaceTextureHolder;
|
||||
|
||||
class QAndroidVideoRendererControl : public QVideoRendererControl, public QAndroidVideoOutput
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QAndroidVideoRendererControl(QObject *parent = 0);
|
||||
~QAndroidVideoRendererControl() Q_DECL_OVERRIDE;
|
||||
|
||||
QAbstractVideoSurface *surface() const Q_DECL_OVERRIDE;
|
||||
void setSurface(QAbstractVideoSurface *surface) Q_DECL_OVERRIDE;
|
||||
|
||||
jobject surfaceHolder() Q_DECL_OVERRIDE;
|
||||
void setVideoSize(const QSize &size) Q_DECL_OVERRIDE;
|
||||
void stop() Q_DECL_OVERRIDE;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onFrameAvailable();
|
||||
|
||||
private:
|
||||
void setupSurface();
|
||||
void renderFrameToFbo();
|
||||
void createGLResources();
|
||||
|
||||
QAbstractVideoSurface *m_surface;
|
||||
QOffscreenSurface *m_offscreenSurface;
|
||||
QOpenGLContext *m_glContext;
|
||||
QOpenGLFramebufferObject *m_fbo;
|
||||
QOpenGLShaderProgram *m_program;
|
||||
bool m_useImage;
|
||||
QSize m_nativeSize;
|
||||
|
||||
QJNIObject *m_androidSurface;
|
||||
JSurfaceTexture *m_surfaceTexture;
|
||||
JSurfaceTextureHolder *m_surfaceHolder;
|
||||
uint m_externalTex;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDVIDEORENDERCONTROL_H
|
||||
126
src/plugins/android/wrappers/jmediametadataretriever.cpp
Normal file
126
src/plugins/android/wrappers/jmediametadataretriever.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 "jmediametadataretriever.h"
|
||||
|
||||
#include <QtPlatformSupport/private/qjnihelpers_p.h>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <qguiapplication.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static jobject g_activity = 0;
|
||||
|
||||
JMediaMetadataRetriever::JMediaMetadataRetriever()
|
||||
: QJNIObject("android/media/MediaMetadataRetriever")
|
||||
{
|
||||
if (!g_activity) {
|
||||
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
|
||||
g_activity = static_cast<jobject>(nativeInterface->nativeResourceForIntegration("QtActivity"));
|
||||
}
|
||||
}
|
||||
|
||||
JMediaMetadataRetriever::~JMediaMetadataRetriever()
|
||||
{
|
||||
}
|
||||
|
||||
QString JMediaMetadataRetriever::extractMetadata(MetadataKey key)
|
||||
{
|
||||
QString value;
|
||||
|
||||
QJNILocalRef<jstring> metadata = callObjectMethod<jstring>("extractMetadata",
|
||||
"(I)Ljava/lang/String;",
|
||||
jint(key));
|
||||
if (!metadata.isNull())
|
||||
value = qt_convertJString(metadata.object());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void JMediaMetadataRetriever::release()
|
||||
{
|
||||
callMethod<void>("release");
|
||||
}
|
||||
|
||||
bool JMediaMetadataRetriever::setDataSource(const QUrl &url)
|
||||
{
|
||||
QAttachedJNIEnv env;
|
||||
|
||||
bool loaded = false;
|
||||
|
||||
QJNILocalRef<jstring> string = qt_toJString(url.toString());
|
||||
|
||||
QJNILocalRef<jobject> uri = callStaticObjectMethod<jobject>("android/net/Uri",
|
||||
"parse",
|
||||
"(Ljava/lang/String;)Landroid/net/Uri;",
|
||||
string.object());
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionClear();
|
||||
} else {
|
||||
callMethod<void>("setDataSource",
|
||||
"(Landroid/content/Context;Landroid/net/Uri;)V",
|
||||
g_activity,
|
||||
uri.object());
|
||||
if (env->ExceptionCheck())
|
||||
env->ExceptionClear();
|
||||
else
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
bool JMediaMetadataRetriever::setDataSource(const QString &path)
|
||||
{
|
||||
QAttachedJNIEnv env;
|
||||
|
||||
bool loaded = false;
|
||||
|
||||
callMethod<void>("setDataSource", "(Ljava/lang/String;)V", qt_toJString(path).object());
|
||||
if (env->ExceptionCheck())
|
||||
env->ExceptionClear();
|
||||
else
|
||||
loaded = true;
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
91
src/plugins/android/wrappers/jmediametadataretriever.h
Normal file
91
src/plugins/android/wrappers/jmediametadataretriever.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 JMEDIAMETADATARETRIEVER_H
|
||||
#define JMEDIAMETADATARETRIEVER_H
|
||||
|
||||
#include <QtPlatformSupport/private/qjniobject_p.h>
|
||||
#include <qurl.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class JMediaMetadataRetriever : public QJNIObject
|
||||
{
|
||||
public:
|
||||
enum MetadataKey {
|
||||
Album = 1,
|
||||
AlbumArtist = 13,
|
||||
Artist = 2,
|
||||
Author = 3,
|
||||
Bitrate = 20,
|
||||
CDTrackNumber = 0,
|
||||
Compilation = 15,
|
||||
Composer = 4,
|
||||
Date = 5,
|
||||
DiscNumber = 14,
|
||||
Duration = 9,
|
||||
Genre = 6,
|
||||
HasAudio = 16,
|
||||
HasVideo = 17,
|
||||
Location = 23,
|
||||
MimeType = 12,
|
||||
NumTracks = 10,
|
||||
Title = 7,
|
||||
VideoHeight = 19,
|
||||
VideoWidth = 18,
|
||||
VideoRotation = 24,
|
||||
Writer = 11,
|
||||
Year = 8
|
||||
};
|
||||
|
||||
JMediaMetadataRetriever();
|
||||
~JMediaMetadataRetriever();
|
||||
|
||||
QString extractMetadata(MetadataKey key);
|
||||
void release();
|
||||
bool setDataSource(const QUrl &url);
|
||||
bool setDataSource(const QString &path);
|
||||
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // JMEDIAMETADATARETRIEVER_H
|
||||
265
src/plugins/android/wrappers/jmediaplayer.cpp
Normal file
265
src/plugins/android/wrappers/jmediaplayer.cpp
Normal file
@@ -0,0 +1,265 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 "jmediaplayer.h"
|
||||
|
||||
#include <QString>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <qguiapplication.h>
|
||||
#include <QtPlatformSupport/private/qjnihelpers_p.h>
|
||||
|
||||
namespace {
|
||||
|
||||
jclass mediaPlayerClass = 0;
|
||||
|
||||
QMap<jlong, JMediaPlayer *> mplayers;
|
||||
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
bool JMediaPlayer::mActivitySet = false;
|
||||
|
||||
JMediaPlayer::JMediaPlayer()
|
||||
: QObject()
|
||||
, QJNIObject(mediaPlayerClass, "(J)V", reinterpret_cast<jlong>(this))
|
||||
, mId(reinterpret_cast<jlong>(this))
|
||||
, mDisplay(0)
|
||||
{
|
||||
mplayers.insert(mId, this);
|
||||
|
||||
if (!mActivitySet) {
|
||||
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
|
||||
jobject activity = static_cast<jobject>(nativeInterface->nativeResourceForIntegration("QtActivity"));
|
||||
QJNIObject::callStaticMethod<void>(mediaPlayerClass,
|
||||
"setActivity",
|
||||
"(Landroid/app/Activity;)V",
|
||||
activity);
|
||||
mActivitySet = true;
|
||||
}
|
||||
}
|
||||
|
||||
JMediaPlayer::~JMediaPlayer()
|
||||
{
|
||||
mplayers.remove(mId);
|
||||
}
|
||||
|
||||
void JMediaPlayer::onError(qint32 what, qint32 extra)
|
||||
{
|
||||
Q_EMIT error(what, extra);
|
||||
}
|
||||
|
||||
void JMediaPlayer::onBufferingUpdate(qint32 percent)
|
||||
{
|
||||
Q_EMIT bufferingUpdate(percent);
|
||||
}
|
||||
|
||||
void JMediaPlayer::onInfo(qint32 what, qint32 extra)
|
||||
{
|
||||
Q_EMIT info(what, extra);
|
||||
}
|
||||
|
||||
void JMediaPlayer::onMediaPlayerInfo(qint32 what, qint32 extra)
|
||||
{
|
||||
Q_EMIT mediaPlayerInfo(what, extra);
|
||||
}
|
||||
|
||||
void JMediaPlayer::onVideoSizeChanged(qint32 width, qint32 height)
|
||||
{
|
||||
Q_EMIT videoSizeChanged(width, height);
|
||||
}
|
||||
|
||||
int JMediaPlayer::getCurrentPosition()
|
||||
{
|
||||
return callMethod<jint>("getCurrentPosition");
|
||||
}
|
||||
|
||||
int JMediaPlayer::getDuration()
|
||||
{
|
||||
return callMethod<jint>("getDuration");
|
||||
}
|
||||
|
||||
bool JMediaPlayer::isPlaying()
|
||||
{
|
||||
return callMethod<jboolean>("isPlaying");
|
||||
}
|
||||
|
||||
int JMediaPlayer::volume()
|
||||
{
|
||||
return callMethod<jint>("getVolume");
|
||||
}
|
||||
|
||||
bool JMediaPlayer::isMuted()
|
||||
{
|
||||
return callMethod<jboolean>("isMuted");
|
||||
}
|
||||
|
||||
void JMediaPlayer::play()
|
||||
{
|
||||
callMethod<void>("start");
|
||||
}
|
||||
|
||||
void JMediaPlayer::pause()
|
||||
{
|
||||
callMethod<void>("pause");
|
||||
}
|
||||
|
||||
void JMediaPlayer::stop()
|
||||
{
|
||||
callMethod<void>("stop");
|
||||
}
|
||||
|
||||
void JMediaPlayer::seekTo(qint32 msec)
|
||||
{
|
||||
callMethod<void>("seekTo", "(I)V", jint(msec));
|
||||
}
|
||||
|
||||
void JMediaPlayer::setMuted(bool mute)
|
||||
{
|
||||
callMethod<void>("mute", "(Z)V", jboolean(mute));
|
||||
}
|
||||
|
||||
void JMediaPlayer::setDataSource(const QString &path)
|
||||
{
|
||||
QJNILocalRef<jstring> string = qt_toJString(path);
|
||||
callMethod<void>("setMediaPath", "(Ljava/lang/String;)V", string.object());
|
||||
}
|
||||
|
||||
void JMediaPlayer::setVolume(int volume)
|
||||
{
|
||||
callMethod<void>("setVolume", "(I)V", jint(volume));
|
||||
}
|
||||
|
||||
void JMediaPlayer::setDisplay(jobject surfaceHolder)
|
||||
{
|
||||
mDisplay = surfaceHolder;
|
||||
callMethod<void>("setDisplay", "(Landroid/view/SurfaceHolder;)V", mDisplay);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
static void onErrorNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id)
|
||||
{
|
||||
Q_UNUSED(env);
|
||||
Q_UNUSED(thiz);
|
||||
JMediaPlayer *const mp = mplayers[id];
|
||||
if (!mp)
|
||||
return;
|
||||
|
||||
mp->onError(what, extra);
|
||||
}
|
||||
|
||||
static void onBufferingUpdateNative(JNIEnv *env, jobject thiz, jint percent, jlong id)
|
||||
{
|
||||
Q_UNUSED(env);
|
||||
Q_UNUSED(thiz);
|
||||
JMediaPlayer *const mp = mplayers[id];
|
||||
if (!mp)
|
||||
return;
|
||||
|
||||
mp->onBufferingUpdate(percent);
|
||||
}
|
||||
|
||||
static void onInfoNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id)
|
||||
{
|
||||
Q_UNUSED(env);
|
||||
Q_UNUSED(thiz);
|
||||
JMediaPlayer *const mp = mplayers[id];
|
||||
if (!mp)
|
||||
return;
|
||||
|
||||
mp->onInfo(what, extra);
|
||||
}
|
||||
|
||||
static void onMediaPlayerInfoNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id)
|
||||
{
|
||||
Q_UNUSED(env);
|
||||
Q_UNUSED(thiz);
|
||||
JMediaPlayer *const mp = mplayers[id];
|
||||
if (!mp)
|
||||
return;
|
||||
|
||||
mp->onMediaPlayerInfo(what, extra);
|
||||
}
|
||||
|
||||
static void onVideoSizeChangedNative(JNIEnv *env,
|
||||
jobject thiz,
|
||||
jint width,
|
||||
jint height,
|
||||
jlong id)
|
||||
{
|
||||
Q_UNUSED(env);
|
||||
Q_UNUSED(thiz);
|
||||
JMediaPlayer *const mp = mplayers[id];
|
||||
if (!mp)
|
||||
return;
|
||||
|
||||
mp->onVideoSizeChanged(width, height);
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
bool JMediaPlayer::initJNI(JNIEnv *env)
|
||||
{
|
||||
jclass jClass = env->FindClass("org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer");
|
||||
|
||||
if (jClass) {
|
||||
mediaPlayerClass = static_cast<jclass>(env->NewGlobalRef(jClass));
|
||||
|
||||
JNINativeMethod methods[] = {
|
||||
{"onErrorNative", "(IIJ)V", reinterpret_cast<void *>(onErrorNative)},
|
||||
{"onBufferingUpdateNative", "(IJ)V", reinterpret_cast<void *>(onBufferingUpdateNative)},
|
||||
{"onInfoNative", "(IIJ)V", reinterpret_cast<void *>(onInfoNative)},
|
||||
{"onMediaPlayerInfoNative", "(IIJ)V", reinterpret_cast<void *>(onMediaPlayerInfoNative)},
|
||||
{"onVideoSizeChangedNative", "(IIJ)V", reinterpret_cast<void *>(onVideoSizeChangedNative)}
|
||||
};
|
||||
|
||||
if (env->RegisterNatives(mediaPlayerClass,
|
||||
methods,
|
||||
sizeof(methods) / sizeof(methods[0])) < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
133
src/plugins/android/wrappers/jmediaplayer.h
Normal file
133
src/plugins/android/wrappers/jmediaplayer.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 QANDROIDMEDIAPLAYER_H
|
||||
#define QANDROIDMEDIAPLAYER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtPlatformSupport/private/qjniobject_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class JMediaPlayer : public QObject, public QJNIObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JMediaPlayer();
|
||||
~JMediaPlayer();
|
||||
|
||||
enum MediaError
|
||||
{
|
||||
// What
|
||||
MEDIA_ERROR_UNKNOWN = 1,
|
||||
MEDIA_ERROR_SERVER_DIED = 100,
|
||||
// Extra
|
||||
MEDIA_ERROR_IO = -1004,
|
||||
MEDIA_ERROR_MALFORMED = -1007,
|
||||
MEDIA_ERROR_UNSUPPORTED = -1010,
|
||||
MEDIA_ERROR_TIMED_OUT = -110,
|
||||
MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200
|
||||
};
|
||||
|
||||
enum MediaInfo
|
||||
{
|
||||
MEDIA_INFO_UNKNOWN = 1,
|
||||
MEDIA_INFO_VIDEO_TRACK_LAGGING = 700,
|
||||
MEDIA_INFO_VIDEO_RENDERING_START = 3,
|
||||
MEDIA_INFO_BUFFERING_START = 701,
|
||||
MEDIA_INFO_BUFFERING_END = 702,
|
||||
MEDIA_INFO_BAD_INTERLEAVING = 800,
|
||||
MEDIA_INFO_NOT_SEEKABLE = 801,
|
||||
MEDIA_INFO_METADATA_UPDATE = 802
|
||||
};
|
||||
|
||||
enum MediaPlayerInfo
|
||||
{
|
||||
MEDIA_PLAYER_INVALID_STATE = 1,
|
||||
MEDIA_PLAYER_PREPARING = 2,
|
||||
MEDIA_PLAYER_READY = 3,
|
||||
MEDIA_PLAYER_DURATION = 4,
|
||||
MEDIA_PLAYER_PROGRESS = 5,
|
||||
MEDIA_PLAYER_FINISHED = 6
|
||||
};
|
||||
|
||||
int getCurrentPosition();
|
||||
int getDuration();
|
||||
bool isPlaying();
|
||||
int volume();
|
||||
bool isMuted();
|
||||
jobject display() { return mDisplay; }
|
||||
|
||||
void play();
|
||||
void pause();
|
||||
void stop();
|
||||
void seekTo(qint32 msec);
|
||||
void setMuted(bool mute);
|
||||
void setDataSource(const QString &path);
|
||||
void setVolume(int volume);
|
||||
void setDisplay(jobject surfaceHolder);
|
||||
|
||||
void onError(qint32 what, qint32 extra);
|
||||
void onBufferingUpdate(qint32 percent);
|
||||
void onInfo(qint32 what, qint32 extra);
|
||||
void onMediaPlayerInfo(qint32 what, qint32 extra);
|
||||
void onVideoSizeChanged(qint32 width, qint32 height);
|
||||
|
||||
static bool initJNI(JNIEnv *env);
|
||||
|
||||
Q_SIGNALS:
|
||||
void error(qint32 what, qint32 extra);
|
||||
void bufferingUpdate(qint32 percent);
|
||||
void completion();
|
||||
void info(qint32 what, qint32 extra);
|
||||
void mediaPlayerInfo(qint32 what, qint32 extra);
|
||||
void videoSizeChanged(qint32 width, qint32 height);
|
||||
|
||||
private:
|
||||
jlong mId;
|
||||
jobject mDisplay;
|
||||
|
||||
static bool mActivitySet;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDMEDIAPLAYER_H
|
||||
118
src/plugins/android/wrappers/jsurfacetexture.cpp
Normal file
118
src/plugins/android/wrappers/jsurfacetexture.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 "jsurfacetexture.h"
|
||||
#include <QtPlatformSupport/private/qjnihelpers_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static jclass g_qtSurfaceTextureClass = 0;
|
||||
static QHash<int, JSurfaceTexture*> g_objectMap;
|
||||
|
||||
// native method for QtSurfaceTexture.java
|
||||
static void notifyFrameAvailable(JNIEnv* , jobject, int id)
|
||||
{
|
||||
JSurfaceTexture *obj = g_objectMap.value(id, 0);
|
||||
if (obj)
|
||||
Q_EMIT obj->frameAvailable();
|
||||
}
|
||||
|
||||
JSurfaceTexture::JSurfaceTexture(unsigned int texName)
|
||||
: QObject()
|
||||
, QJNIObject(g_qtSurfaceTextureClass, "(I)V", jint(texName))
|
||||
, m_texID(int(texName))
|
||||
{
|
||||
if (m_jobject)
|
||||
g_objectMap.insert(int(texName), this);
|
||||
}
|
||||
|
||||
JSurfaceTexture::~JSurfaceTexture()
|
||||
{
|
||||
if (m_jobject)
|
||||
g_objectMap.remove(m_texID);
|
||||
}
|
||||
|
||||
QMatrix4x4 JSurfaceTexture::getTransformMatrix()
|
||||
{
|
||||
QAttachedJNIEnv env;
|
||||
|
||||
QMatrix4x4 matrix;
|
||||
jfloatArray array = env->NewFloatArray(16);
|
||||
callMethod<void>("getTransformMatrix", "([F)V", array);
|
||||
env->GetFloatArrayRegion(array, 0, 16, matrix.data());
|
||||
env->DeleteLocalRef(array);
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
void JSurfaceTexture::updateTexImage()
|
||||
{
|
||||
callMethod<void>("updateTexImage");
|
||||
}
|
||||
|
||||
QJNILocalRef<jobject> JSurfaceTexture::surfaceTexture()
|
||||
{
|
||||
return getObjectField<jobject>("surfaceTexture", "Landroid/graphics/SurfaceTexture;");
|
||||
}
|
||||
|
||||
static JNINativeMethod methods[] = {
|
||||
{"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable}
|
||||
};
|
||||
|
||||
bool JSurfaceTexture::initJNI(JNIEnv *env)
|
||||
{
|
||||
jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTexture");
|
||||
if (env->ExceptionCheck())
|
||||
env->ExceptionClear();
|
||||
|
||||
if (clazz) {
|
||||
g_qtSurfaceTextureClass = static_cast<jclass>(env->NewGlobalRef(clazz));
|
||||
if (env->RegisterNatives(g_qtSurfaceTextureClass,
|
||||
methods,
|
||||
sizeof(methods) / sizeof(methods[0])) < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
75
src/plugins/android/wrappers/jsurfacetexture.h
Normal file
75
src/plugins/android/wrappers/jsurfacetexture.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 JSURFACETEXTURE_H
|
||||
#define JSURFACETEXTURE_H
|
||||
|
||||
#include <qobject.h>
|
||||
#include <QtPlatformSupport/private/qjniobject_p.h>
|
||||
|
||||
#include <QMatrix4x4>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class JSurfaceTexture : public QObject, public QJNIObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit JSurfaceTexture(unsigned int texName);
|
||||
~JSurfaceTexture();
|
||||
|
||||
QMatrix4x4 getTransformMatrix();
|
||||
void updateTexImage();
|
||||
|
||||
QJNILocalRef<jobject> surfaceTexture();
|
||||
|
||||
static bool initJNI(JNIEnv *env);
|
||||
|
||||
Q_SIGNALS:
|
||||
void frameAvailable();
|
||||
|
||||
private:
|
||||
int m_texID;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // JSURFACETEXTURE_H
|
||||
65
src/plugins/android/wrappers/jsurfacetextureholder.cpp
Normal file
65
src/plugins/android/wrappers/jsurfacetextureholder.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 "jsurfacetextureholder.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static jclass g_qtSurfaceTextureHolderClass = 0;
|
||||
|
||||
JSurfaceTextureHolder::JSurfaceTextureHolder(jobject surface)
|
||||
: QJNIObject(g_qtSurfaceTextureHolderClass, "(Landroid/view/Surface;)V", surface)
|
||||
{
|
||||
}
|
||||
|
||||
bool JSurfaceTextureHolder::initJNI(JNIEnv *env)
|
||||
{
|
||||
jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder");
|
||||
if (env->ExceptionCheck())
|
||||
env->ExceptionClear();
|
||||
|
||||
if (clazz)
|
||||
g_qtSurfaceTextureHolderClass = static_cast<jclass>(env->NewGlobalRef(clazz));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
59
src/plugins/android/wrappers/jsurfacetextureholder.h
Normal file
59
src/plugins/android/wrappers/jsurfacetextureholder.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** 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 JSURFACETEXTUREHOLDER_H
|
||||
#define JSURFACETEXTUREHOLDER_H
|
||||
|
||||
#include <QtPlatformSupport/private/qjniobject_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class JSurfaceTextureHolder : public QJNIObject
|
||||
{
|
||||
public:
|
||||
JSurfaceTextureHolder(jobject surface);
|
||||
|
||||
static bool initJNI(JNIEnv *env);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // JSURFACETEXTUREHOLDER_H
|
||||
15
src/plugins/android/wrappers/wrappers.pri
Normal file
15
src/plugins/android/wrappers/wrappers.pri
Normal file
@@ -0,0 +1,15 @@
|
||||
QT += platformsupport-private
|
||||
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/jmediaplayer.h \
|
||||
$$PWD/jsurfacetexture.h \
|
||||
$$PWD/jsurfacetextureholder.h \
|
||||
$$PWD/jmediametadataretriever.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/jmediaplayer.cpp \
|
||||
$$PWD/jsurfacetexture.cpp \
|
||||
$$PWD/jsurfacetextureholder.cpp \
|
||||
$$PWD/jmediametadataretriever.cpp
|
||||
@@ -8,6 +8,10 @@ TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += m3u
|
||||
|
||||
android {
|
||||
SUBDIRS += android
|
||||
}
|
||||
|
||||
blackberry {
|
||||
SUBDIRS += blackberry
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user