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(recording/recording.pri)
|
||||||
include(video/video.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 {
|
mac {
|
||||||
LIBS += -framework AppKit -framework QuartzCore -framework QTKit
|
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
|
SUBDIRS += m3u
|
||||||
|
|
||||||
|
android {
|
||||||
|
SUBDIRS += android
|
||||||
|
}
|
||||||
|
|
||||||
blackberry {
|
blackberry {
|
||||||
SUBDIRS += blackberry
|
SUBDIRS += blackberry
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user