From 0a7882f6b308296ff9d44d891d3bdfed91679ce2 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Mon, 25 Mar 2013 18:11:27 +0100 Subject: Android: added camera support. This patch includes all camera features: viewport, settings, image capture, and video recording. It also adds support for QAudioRecorder. Change-Id: Ib962177cc8de4bac03f42a2bc0f534e03464bbfc Reviewed-by: Christian Stromme --- src/plugins/android/android.pro | 2 +- src/plugins/android/jar/jar.pri | 7 +- .../qtproject/qt5/android/multimedia/QtCamera.java | 182 ++++++ .../qt5/android/multimedia/QtMediaRecorder.java | 72 +++ .../qt5/android/multimedia/QtMultimediaUtils.java | 136 ++++ .../qt5/android/multimedia/QtSurfaceTexture.java | 18 +- .../android/multimedia/QtSurfaceTextureHolder.java | 13 + src/plugins/android/mediaplayer/mediaplayer.json | 4 - src/plugins/android/mediaplayer/mediaplayer.pro | 24 - .../mediaplayer/qandroidmediaplayercontrol.cpp | 534 ---------------- .../mediaplayer/qandroidmediaplayercontrol.h | 131 ---- .../android/mediaplayer/qandroidmediaservice.cpp | 97 --- .../android/mediaplayer/qandroidmediaservice.h | 71 -- .../mediaplayer/qandroidmediaserviceplugin.cpp | 107 ---- .../mediaplayer/qandroidmediaserviceplugin.h | 72 --- .../mediaplayer/qandroidmetadatareadercontrol.cpp | 222 ------- .../mediaplayer/qandroidmetadatareadercontrol.h | 80 --- .../android/mediaplayer/qandroidvideooutput.h | 70 -- .../mediaplayer/qandroidvideorendercontrol.cpp | 424 ------------ .../mediaplayer/qandroidvideorendercontrol.h | 102 --- src/plugins/android/src/android_mediaservice.json | 3 + src/plugins/android/src/common/common.pri | 10 + .../android/src/common/qandroidmultimediautils.cpp | 79 +++ .../android/src/common/qandroidmultimediautils.h | 58 ++ .../android/src/common/qandroidvideooutput.h | 73 +++ .../src/common/qandroidvideorendercontrol.cpp | 438 +++++++++++++ .../src/common/qandroidvideorendercontrol.h | 104 +++ .../android/src/mediacapture/mediacapture.pri | 47 ++ .../qandroidaudioencodersettingscontrol.cpp | 98 +++ .../qandroidaudioencodersettingscontrol.h | 69 ++ .../qandroidaudioinputselectorcontrol.cpp | 113 ++++ .../qandroidaudioinputselectorcontrol.h | 73 +++ .../qandroidcameracapturebufferformatcontrol.cpp | 66 ++ .../qandroidcameracapturebufferformatcontrol.h | 62 ++ .../qandroidcameracapturedestinationcontrol.cpp | 71 ++ .../qandroidcameracapturedestinationcontrol.h | 67 ++ .../src/mediacapture/qandroidcameracontrol.cpp | 114 ++++ .../src/mediacapture/qandroidcameracontrol.h | 76 +++ .../mediacapture/qandroidcameraexposurecontrol.cpp | 227 +++++++ .../mediacapture/qandroidcameraexposurecontrol.h | 85 +++ .../mediacapture/qandroidcameraflashcontrol.cpp | 120 ++++ .../src/mediacapture/qandroidcameraflashcontrol.h | 73 +++ .../mediacapture/qandroidcamerafocuscontrol.cpp | 304 +++++++++ .../src/mediacapture/qandroidcamerafocuscontrol.h | 95 +++ .../qandroidcameraimagecapturecontrol.cpp | 86 +++ .../qandroidcameraimagecapturecontrol.h | 71 ++ .../qandroidcameraimageprocessingcontrol.cpp | 135 ++++ .../qandroidcameraimageprocessingcontrol.h | 73 +++ .../mediacapture/qandroidcameralockscontrol.cpp | 254 ++++++++ .../src/mediacapture/qandroidcameralockscontrol.h | 87 +++ .../src/mediacapture/qandroidcamerasession.cpp | 553 ++++++++++++++++ .../src/mediacapture/qandroidcamerasession.h | 158 +++++ .../src/mediacapture/qandroidcamerazoomcontrol.cpp | 141 ++++ .../src/mediacapture/qandroidcamerazoomcontrol.h | 80 +++ .../src/mediacapture/qandroidcaptureservice.cpp | 216 +++++++ .../src/mediacapture/qandroidcaptureservice.h | 109 ++++ .../src/mediacapture/qandroidcapturesession.cpp | 547 ++++++++++++++++ .../src/mediacapture/qandroidcapturesession.h | 184 ++++++ .../mediacapture/qandroidimageencodercontrol.cpp | 95 +++ .../src/mediacapture/qandroidimageencodercontrol.h | 72 +++ .../mediacapture/qandroidmediacontainercontrol.cpp | 86 +++ .../mediacapture/qandroidmediacontainercontrol.h | 68 ++ .../mediacapture/qandroidmediarecordercontrol.cpp | 120 ++++ .../mediacapture/qandroidmediarecordercontrol.h | 77 +++ .../mediacapture/qandroidmediastoragelocation.cpp | 130 ++++ .../mediacapture/qandroidmediastoragelocation.h | 75 +++ .../qandroidvideodeviceselectorcontrol.cpp | 150 +++++ .../qandroidvideodeviceselectorcontrol.h | 84 +++ .../qandroidvideoencodersettingscontrol.cpp | 99 +++ .../qandroidvideoencodersettingscontrol.h | 70 ++ .../android/src/mediaplayer/mediaplayer.pri | 11 + .../src/mediaplayer/qandroidmediaplayercontrol.cpp | 535 ++++++++++++++++ .../src/mediaplayer/qandroidmediaplayercontrol.h | 131 ++++ .../src/mediaplayer/qandroidmediaservice.cpp | 97 +++ .../android/src/mediaplayer/qandroidmediaservice.h | 71 ++ .../mediaplayer/qandroidmetadatareadercontrol.cpp | 222 +++++++ .../mediaplayer/qandroidmetadatareadercontrol.h | 80 +++ .../android/src/qandroidmediaserviceplugin.cpp | 149 +++++ .../android/src/qandroidmediaserviceplugin.h | 75 +++ src/plugins/android/src/src.pro | 19 + src/plugins/android/src/wrappers/jcamera.cpp | 712 +++++++++++++++++++++ src/plugins/android/src/wrappers/jcamera.h | 166 +++++ .../src/wrappers/jmediametadataretriever.cpp | 126 ++++ .../android/src/wrappers/jmediametadataretriever.h | 91 +++ src/plugins/android/src/wrappers/jmediaplayer.cpp | 270 ++++++++ src/plugins/android/src/wrappers/jmediaplayer.h | 135 ++++ .../android/src/wrappers/jmediarecorder.cpp | 242 +++++++ src/plugins/android/src/wrappers/jmediarecorder.h | 134 ++++ .../android/src/wrappers/jmultimediautils.cpp | 95 +++ .../android/src/wrappers/jmultimediautils.h | 73 +++ .../android/src/wrappers/jsurfacetexture.cpp | 113 ++++ src/plugins/android/src/wrappers/jsurfacetexture.h | 73 +++ .../android/src/wrappers/jsurfacetextureholder.cpp | 65 ++ .../android/src/wrappers/jsurfacetextureholder.h | 59 ++ src/plugins/android/src/wrappers/wrappers.pri | 21 + .../android/wrappers/jmediametadataretriever.cpp | 126 ---- .../android/wrappers/jmediametadataretriever.h | 91 --- src/plugins/android/wrappers/jmediaplayer.cpp | 270 -------- src/plugins/android/wrappers/jmediaplayer.h | 135 ---- src/plugins/android/wrappers/jsurfacetexture.cpp | 118 ---- src/plugins/android/wrappers/jsurfacetexture.h | 75 --- .../android/wrappers/jsurfacetextureholder.cpp | 65 -- .../android/wrappers/jsurfacetextureholder.h | 59 -- src/plugins/android/wrappers/wrappers.pri | 15 - src/plugins/plugins.pro | 2 +- 105 files changed, 10525 insertions(+), 2909 deletions(-) create mode 100644 src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCamera.java create mode 100644 src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtMediaRecorder.java create mode 100644 src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtMultimediaUtils.java delete mode 100644 src/plugins/android/mediaplayer/mediaplayer.json delete mode 100644 src/plugins/android/mediaplayer/mediaplayer.pro delete mode 100644 src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp delete mode 100644 src/plugins/android/mediaplayer/qandroidmediaplayercontrol.h delete mode 100644 src/plugins/android/mediaplayer/qandroidmediaservice.cpp delete mode 100644 src/plugins/android/mediaplayer/qandroidmediaservice.h delete mode 100644 src/plugins/android/mediaplayer/qandroidmediaserviceplugin.cpp delete mode 100644 src/plugins/android/mediaplayer/qandroidmediaserviceplugin.h delete mode 100644 src/plugins/android/mediaplayer/qandroidmetadatareadercontrol.cpp delete mode 100644 src/plugins/android/mediaplayer/qandroidmetadatareadercontrol.h delete mode 100644 src/plugins/android/mediaplayer/qandroidvideooutput.h delete mode 100644 src/plugins/android/mediaplayer/qandroidvideorendercontrol.cpp delete mode 100644 src/plugins/android/mediaplayer/qandroidvideorendercontrol.h create mode 100644 src/plugins/android/src/android_mediaservice.json create mode 100644 src/plugins/android/src/common/common.pri create mode 100644 src/plugins/android/src/common/qandroidmultimediautils.cpp create mode 100644 src/plugins/android/src/common/qandroidmultimediautils.h create mode 100644 src/plugins/android/src/common/qandroidvideooutput.h create mode 100644 src/plugins/android/src/common/qandroidvideorendercontrol.cpp create mode 100644 src/plugins/android/src/common/qandroidvideorendercontrol.h create mode 100644 src/plugins/android/src/mediacapture/mediacapture.pri create mode 100644 src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcameracapturebufferformatcontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcameracapturebufferformatcontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcameracapturedestinationcontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcameracapturedestinationcontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcameracontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcameracontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcameralockscontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcameralockscontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcamerasession.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcamerasession.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcaptureservice.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcaptureservice.h create mode 100644 src/plugins/android/src/mediacapture/qandroidcapturesession.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidcapturesession.h create mode 100644 src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidmediastoragelocation.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidmediastoragelocation.h create mode 100644 src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.h create mode 100644 src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.cpp create mode 100644 src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.h create mode 100644 src/plugins/android/src/mediaplayer/mediaplayer.pri create mode 100644 src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp create mode 100644 src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h create mode 100644 src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp create mode 100644 src/plugins/android/src/mediaplayer/qandroidmediaservice.h create mode 100644 src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp create mode 100644 src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h create mode 100644 src/plugins/android/src/qandroidmediaserviceplugin.cpp create mode 100644 src/plugins/android/src/qandroidmediaserviceplugin.h create mode 100644 src/plugins/android/src/src.pro create mode 100644 src/plugins/android/src/wrappers/jcamera.cpp create mode 100644 src/plugins/android/src/wrappers/jcamera.h create mode 100644 src/plugins/android/src/wrappers/jmediametadataretriever.cpp create mode 100644 src/plugins/android/src/wrappers/jmediametadataretriever.h create mode 100644 src/plugins/android/src/wrappers/jmediaplayer.cpp create mode 100644 src/plugins/android/src/wrappers/jmediaplayer.h create mode 100644 src/plugins/android/src/wrappers/jmediarecorder.cpp create mode 100644 src/plugins/android/src/wrappers/jmediarecorder.h create mode 100644 src/plugins/android/src/wrappers/jmultimediautils.cpp create mode 100644 src/plugins/android/src/wrappers/jmultimediautils.h create mode 100644 src/plugins/android/src/wrappers/jsurfacetexture.cpp create mode 100644 src/plugins/android/src/wrappers/jsurfacetexture.h create mode 100644 src/plugins/android/src/wrappers/jsurfacetextureholder.cpp create mode 100644 src/plugins/android/src/wrappers/jsurfacetextureholder.h create mode 100644 src/plugins/android/src/wrappers/wrappers.pri delete mode 100644 src/plugins/android/wrappers/jmediametadataretriever.cpp delete mode 100644 src/plugins/android/wrappers/jmediametadataretriever.h delete mode 100644 src/plugins/android/wrappers/jmediaplayer.cpp delete mode 100644 src/plugins/android/wrappers/jmediaplayer.h delete mode 100644 src/plugins/android/wrappers/jsurfacetexture.cpp delete mode 100644 src/plugins/android/wrappers/jsurfacetexture.h delete mode 100644 src/plugins/android/wrappers/jsurfacetextureholder.cpp delete mode 100644 src/plugins/android/wrappers/jsurfacetextureholder.h delete mode 100644 src/plugins/android/wrappers/wrappers.pri (limited to 'src/plugins') diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro index 2cfc83f0e..288ae8528 100644 --- a/src/plugins/android/android.pro +++ b/src/plugins/android/android.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs -SUBDIRS += mediaplayer \ +SUBDIRS += src \ jar diff --git a/src/plugins/android/jar/jar.pri b/src/plugins/android/jar/jar.pri index e6a3c63c2..9e235144b 100644 --- a/src/plugins/android/jar/jar.pri +++ b/src/plugins/android/jar/jar.pri @@ -6,9 +6,14 @@ API_VERSION = android-11 JAVACLASSPATH += $$PWD/src JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java \ + $$PWD/src/org/qtproject/qt5/android/multimedia/QtCamera.java \ $$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java \ - $$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java + $$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java \ + $$PWD/src/org/qtproject/qt5/android/multimedia/QtMultimediaUtils.java \ + $$PWD/src/org/qtproject/qt5/android/multimedia/QtMediaRecorder.java # install target.path = $$[QT_INSTALL_PREFIX]/jar INSTALLS += target + +OTHER_FILES += $$JAVASOURCES diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCamera.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCamera.java new file mode 100644 index 000000000..b0a4954cf --- /dev/null +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCamera.java @@ -0,0 +1,182 @@ +/**************************************************************************** + ** + ** 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.hardware.Camera; +import android.graphics.SurfaceTexture; +import android.util.Log; + +public class QtCamera implements Camera.ShutterCallback, Camera.PictureCallback, Camera.AutoFocusCallback +{ + private int m_cameraId = -1; + private Camera m_camera = null; + + private static final String TAG = "Qt Camera"; + + private QtCamera(int id, Camera cam) + { + m_cameraId = id; + m_camera = cam; + } + + public static QtCamera open(int cameraId) + { + try { + Camera cam = Camera.open(cameraId); + return new QtCamera(cameraId, cam); + } catch(Exception e) { + Log.d(TAG, e.getMessage()); + } + return null; + } + + public Camera.Parameters getParameters() + { + return m_camera.getParameters(); + } + + public void lock() + { + try { + m_camera.lock(); + } catch(Exception e) { + Log.d(TAG, e.getMessage()); + } + } + + public void unlock() + { + try { + m_camera.unlock(); + } catch(Exception e) { + Log.d(TAG, e.getMessage()); + } + } + + public void release() + { + m_camera.release(); + } + + public void reconnect() + { + try { + m_camera.reconnect(); + } catch(Exception e) { + Log.d(TAG, e.getMessage()); + } + } + + public void setDisplayOrientation(int degrees) + { + m_camera.setDisplayOrientation(degrees); + } + + public void setParameters(Camera.Parameters params) + { + try { + m_camera.setParameters(params); + } catch(Exception e) { + Log.d(TAG, e.getMessage()); + } + } + + public void setPreviewTexture(SurfaceTexture surfaceTexture) + { + try { + m_camera.setPreviewTexture(surfaceTexture); + } catch(Exception e) { + Log.d(TAG, e.getMessage()); + } + } + + public void startPreview() + { + m_camera.startPreview(); + } + + public void stopPreview() + { + m_camera.stopPreview(); + } + + public void autoFocus() + { + m_camera.autoFocus(this); + } + + public void cancelAutoFocus() + { + m_camera.cancelAutoFocus(); + } + + public void takePicture() + { + try { + m_camera.takePicture(this, null, this); + } catch(Exception e) { + Log.d(TAG, e.getMessage()); + } + } + + @Override + public void onShutter() + { + notifyPictureExposed(m_cameraId); + } + + @Override + public void onPictureTaken(byte[] data, Camera camera) + { + notifyPictureCaptured(m_cameraId, data); + } + + @Override + public void onAutoFocus(boolean success, Camera camera) + { + notifyAutoFocusComplete(m_cameraId, success); + } + + private static native void notifyAutoFocusComplete(int id, boolean success); + private static native void notifyPictureExposed(int id); + private static native void notifyPictureCaptured(int id, byte[] data); +} diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtMediaRecorder.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtMediaRecorder.java new file mode 100644 index 000000000..d76cd2221 --- /dev/null +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtMediaRecorder.java @@ -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 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.media.MediaRecorder; + +public class QtMediaRecorder extends MediaRecorder implements MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener +{ + private long m_id = -1; + + public QtMediaRecorder(long id) + { + super(); + m_id = id; + setOnErrorListener(this); + setOnInfoListener(this); + } + + @Override + public void onError(MediaRecorder mr, int what, int extra) + { + notifyError(m_id, what, extra); + } + + @Override + public void onInfo(MediaRecorder mr, int what, int extra) + { + notifyInfo(m_id, what, extra); + } + + private static native void notifyError(long id, int what, int extra); + private static native void notifyInfo(long id, int what, int extra); +} diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtMultimediaUtils.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtMultimediaUtils.java new file mode 100644 index 000000000..69422d0f8 --- /dev/null +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtMultimediaUtils.java @@ -0,0 +1,136 @@ +/**************************************************************************** + ** + ** 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.content.Context; +import android.app.Activity; +import android.view.OrientationEventListener; +import android.os.Environment; +import android.media.MediaScannerConnection; +import java.lang.String; +import java.io.File; + +public class QtMultimediaUtils +{ + static private class OrientationListener extends OrientationEventListener + { + static public int deviceOrientation = 0; + + public OrientationListener(Context context) + { + super(context); + } + + @Override + public void onOrientationChanged(int orientation) + { + if (orientation == ORIENTATION_UNKNOWN) + return; + + deviceOrientation = orientation; + } + } + + static private Activity m_activity = null; + static private OrientationListener m_orientationListener = null; + + static public void setActivity(Activity activity, Object activityDelegate) + { + m_activity = activity; + m_orientationListener = new OrientationListener(activity); + } + + public QtMultimediaUtils() + { + } + + static void enableOrientationListener(boolean enable) + { + if (enable) + m_orientationListener.enable(); + else + m_orientationListener.disable(); + } + + static int getDeviceOrientation() + { + return m_orientationListener.deviceOrientation; + } + + static String getDefaultMediaDirectory(int type) + { + String dirType = new String(); + switch (type) { + case 0: + dirType = Environment.DIRECTORY_MUSIC; + break; + case 1: + dirType = Environment.DIRECTORY_MOVIES; + break; + case 2: + dirType = Environment.DIRECTORY_DCIM; + break; + default: + break; + } + + File path = new File(""); + if (type == 3) { + // There is no API for knowing the standard location for sounds + // such as voice recording. Though, it's typically in the 'Sounds' + // directory at the root of the external storage + path = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + + File.separator + "Sounds"); + } else { + path = Environment.getExternalStoragePublicDirectory(dirType); + } + + path.mkdirs(); // make sure the directory exists + + return path.getAbsolutePath(); + } + + static void registerMediaFile(String file) + { + MediaScannerConnection.scanFile(m_activity, new String[] { file }, null, null); + } +} diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java index b8837d557..7632abd2d 100644 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTexture.java @@ -43,28 +43,18 @@ package org.qtproject.qt5.android.multimedia; import android.graphics.SurfaceTexture; -public class QtSurfaceTexture implements SurfaceTexture.OnFrameAvailableListener +public class QtSurfaceTexture extends SurfaceTexture implements SurfaceTexture.OnFrameAvailableListener { - public SurfaceTexture surfaceTexture; private int texID; public QtSurfaceTexture(int texName) { + super(texName); texID = texName; - surfaceTexture = new SurfaceTexture(texName); - surfaceTexture.setOnFrameAvailableListener(this); - } - - public void getTransformMatrix(float[] mtx) - { - surfaceTexture.getTransformMatrix(mtx); - } - - public void updateTexImage() - { - surfaceTexture.updateTexImage(); + setOnFrameAvailableListener(this); } + @Override public void onFrameAvailable(SurfaceTexture surfaceTexture) { notifyFrameAvailable(texID); diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java index 15c5f231f..e676559d9 100644 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java @@ -55,59 +55,72 @@ public class QtSurfaceTextureHolder implements SurfaceHolder surfaceTexture = surface; } + @Override public void addCallback(SurfaceHolder.Callback callback) { } + @Override public Surface getSurface() { return surfaceTexture; } + @Override public Rect getSurfaceFrame() { return new Rect(); } + @Override public boolean isCreating() { return false; } + @Override public Canvas lockCanvas(Rect dirty) { return new Canvas(); } + @Override public Canvas lockCanvas() { return new Canvas(); } + @Override public void removeCallback(SurfaceHolder.Callback callback) { } + @Override public void setFixedSize(int width, int height) { } + @Override public void setFormat(int format) { } + @Override public void setKeepScreenOn(boolean screenOn) { } + @Override public void setSizeFromLayout() { } + @Override public void setType(int type) { } + @Override public void unlockCanvasAndPost(Canvas canvas) { } diff --git a/src/plugins/android/mediaplayer/mediaplayer.json b/src/plugins/android/mediaplayer/mediaplayer.json deleted file mode 100644 index f371ebfd7..000000000 --- a/src/plugins/android/mediaplayer/mediaplayer.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["androidmultimedia"], - "Services": ["org.qt-project.qt.mediaplayer"] -} diff --git a/src/plugins/android/mediaplayer/mediaplayer.pro b/src/plugins/android/mediaplayer/mediaplayer.pro deleted file mode 100644 index cabe4c666..000000000 --- a/src/plugins/android/mediaplayer/mediaplayer.pro +++ /dev/null @@ -1,24 +0,0 @@ -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) diff --git a/src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp deleted file mode 100644 index 4dc56ebd9..000000000 --- a/src/plugins/android/mediaplayer/qandroidmediaplayercontrol.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/**************************************************************************** -** -** 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 - -static void textureReadyCallback(void *context) -{ - if (context) - reinterpret_cast(context)->onSurfaceTextureReady(); -} - -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), - mPendingSetMedia(false) -{ - 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() -{ - mMediaPlayer->release(); - 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 - || !mMediaPlayerReady) ? 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; - - if (mVideoOutput && !mMediaPlayer->display()) { - // if a video output is set but the video texture is not ready, delay loading the media - // since it can cause problems on some hardware - mPendingSetMedia = true; - return; - } - - 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; - - if (mVideoOutput && !mMediaPlayer->display()) { - if (mVideoOutput->isTextureReady()) - mMediaPlayer->setDisplay(mVideoOutput->surfaceHolder()); - else - mVideoOutput->setTextureReadyCallback(textureReadyCallback, this); - } -} - -void QAndroidMediaPlayerControl::play() -{ - if (!mMediaPlayerReady) { - mPendingState = QMediaPlayer::PlayingState; - if (mCurrentState == QMediaPlayer::StoppedState - && !mMediaContent.isNull() - && mCurrentMediaStatus != QMediaPlayer::LoadingMedia - && !mPendingSetMedia) { - 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: - setMediaStatus(QMediaPlayer::LoadedMedia); - if (mBuffering) { - setMediaStatus(mBufferPercent == 100 ? QMediaPlayer::BufferedMedia - : QMediaPlayer::BufferingMedia); - } else { - onBufferChanged(100); - } - 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 = percent != 100; - mBufferPercent = percent; - Q_EMIT bufferStatusChanged(mBufferPercent); - - updateAvailablePlaybackRanges(); - - if (mBufferPercent == 100) - setMediaStatus(QMediaPlayer::BufferedMedia); -} - -void QAndroidMediaPlayerControl::onVideoSizeChanged(qint32 width, qint32 height) -{ - QSize newSize(width, height); - - if (width == 0 || height == 0 || newSize == mVideoSize) - return; - - setVideoAvailable(true); - mVideoSize = newSize; - - if (mVideoOutput) - mVideoOutput->setVideoSize(mVideoSize); -} - -void QAndroidMediaPlayerControl::onSurfaceTextureReady() -{ - if (!mMediaPlayer->display() && mVideoOutput) { - mMediaPlayer->setDisplay(mVideoOutput->surfaceHolder()); - flushPendingStates(); - } -} - -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; - - if (!available) - mVideoSize = QSize(); - - mVideoAvailable = available; - Q_EMIT videoAvailableChanged(mVideoAvailable); -} - -void QAndroidMediaPlayerControl::resetBufferingProgress() -{ - mBuffering = false; - mBufferPercent = 0; - mAvailablePlaybackRange = QMediaTimeRange(); - Q_EMIT bufferStatusChanged(mBufferPercent); -} - -void QAndroidMediaPlayerControl::flushPendingStates() -{ - if (mPendingSetMedia) { - setMedia(mMediaContent, 0); - mPendingSetMedia = false; - return; - } - - 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 diff --git a/src/plugins/android/mediaplayer/qandroidmediaplayercontrol.h b/src/plugins/android/mediaplayer/qandroidmediaplayercontrol.h deleted file mode 100644 index 93eced853..000000000 --- a/src/plugins/android/mediaplayer/qandroidmediaplayercontrol.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** 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 -#include -#include - -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); - void onSurfaceTextureReady(); - -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; - QSize mVideoSize; - bool mBuffering; - QMediaTimeRange mAvailablePlaybackRange; - bool mMediaPlayerReady; - QMediaPlayer::State mPendingState; - qint64 mPendingPosition; - bool mPendingSetMedia; - - 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 diff --git a/src/plugins/android/mediaplayer/qandroidmediaservice.cpp b/src/plugins/android/mediaplayer/qandroidmediaservice.cpp deleted file mode 100644 index 175958676..000000000 --- a/src/plugins/android/mediaplayer/qandroidmediaservice.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** 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 diff --git a/src/plugins/android/mediaplayer/qandroidmediaservice.h b/src/plugins/android/mediaplayer/qandroidmediaservice.h deleted file mode 100644 index 4d310e8e0..000000000 --- a/src/plugins/android/mediaplayer/qandroidmediaservice.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** 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 - -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 diff --git a/src/plugins/android/mediaplayer/qandroidmediaserviceplugin.cpp b/src/plugins/android/mediaplayer/qandroidmediaserviceplugin.cpp deleted file mode 100644 index 3bf703413..000000000 --- a/src/plugins/android/mediaplayer/qandroidmediaserviceplugin.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** 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 - -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 diff --git a/src/plugins/android/mediaplayer/qandroidmediaserviceplugin.h b/src/plugins/android/mediaplayer/qandroidmediaserviceplugin.h deleted file mode 100644 index d004635f2..000000000 --- a/src/plugins/android/mediaplayer/qandroidmediaserviceplugin.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** 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 - -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 diff --git a/src/plugins/android/mediaplayer/qandroidmetadatareadercontrol.cpp b/src/plugins/android/mediaplayer/qandroidmetadatareadercontrol.cpp deleted file mode 100644 index e52c46387..000000000 --- a/src/plugins/android/mediaplayer/qandroidmetadatareadercontrol.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/**************************************************************************** -** -** 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 -#include -#include - -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 diff --git a/src/plugins/android/mediaplayer/qandroidmetadatareadercontrol.h b/src/plugins/android/mediaplayer/qandroidmetadatareadercontrol.h deleted file mode 100644 index 7ea736ffd..000000000 --- a/src/plugins/android/mediaplayer/qandroidmetadatareadercontrol.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** 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 -#include - -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 diff --git a/src/plugins/android/mediaplayer/qandroidvideooutput.h b/src/plugins/android/mediaplayer/qandroidvideooutput.h deleted file mode 100644 index d59971f3b..000000000 --- a/src/plugins/android/mediaplayer/qandroidvideooutput.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** 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 -#include -#include - -QT_BEGIN_NAMESPACE - -typedef void (*TextureReadyCallback)(void*); - -class QAndroidVideoOutput -{ -public: - QAndroidVideoOutput() { } - virtual ~QAndroidVideoOutput() { } - - virtual jobject surfaceHolder() = 0; - - virtual bool isTextureReady() = 0; - virtual void setTextureReadyCallback(TextureReadyCallback cb, void *context = 0) = 0; - - virtual void setVideoSize(const QSize &size) = 0; - virtual void stop() = 0; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDVIDEOOUTPUT_H diff --git a/src/plugins/android/mediaplayer/qandroidvideorendercontrol.cpp b/src/plugins/android/mediaplayer/qandroidvideorendercontrol.cpp deleted file mode 100644 index fe26b455a..000000000 --- a/src/plugins/android/mediaplayer/qandroidvideorendercontrol.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/**************************************************************************** -** -** 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 -#include "jsurfacetextureholder.h" -#include -#include -#include -#include -#include -#include -#include -#include - -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(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) - , m_textureReadyCallback(0) - , m_textureReadyContext(0) -{ -} - -QAndroidVideoRendererControl::~QAndroidVideoRendererControl() -{ - if (m_glContext) - m_glContext->makeCurrent(m_offscreenSurface); - - if (m_surfaceTexture) { - QJNILocalRef surfaceTex = m_surfaceTexture->surfaceTexture(); - QJNIObject obj(surfaceTex.object()); - obj.callMethod("release"); - delete m_surfaceTexture; - m_surfaceTexture = 0; - } - if (m_androidSurface) { - m_androidSurface->callMethod("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->removeEventFilter(this); - } - - m_surface = surface; - - if (m_surface) { - m_useImage = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).contains(QVideoFrame::Format_BGR32); - m_surface->installEventFilter(this); - } -} - -bool QAndroidVideoRendererControl::isTextureReady() -{ - return QOpenGLContext::currentContext() || (m_surface && m_surface->property("GLContext").isValid()); -} - -void QAndroidVideoRendererControl::setTextureReadyCallback(TextureReadyCallback cb, void *context) -{ - m_textureReadyCallback = cb; - m_textureReadyContext = context; -} - -bool QAndroidVideoRendererControl::initSurfaceTexture() -{ - if (m_surfaceTexture) - return true; - - if (!m_surface) - return false; - - 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) { - QOpenGLContext *shareContext = qobject_cast(m_surface->property("GLContext").value()); - if (!shareContext) - return false; - - m_offscreenSurface = new QOffscreenSurface; - QSurfaceFormat format; - format.setSwapBehavior(QSurfaceFormat::SingleBuffer); - m_offscreenSurface->setFormat(format); - m_offscreenSurface->create(); - - m_glContext = new QOpenGLContext; - m_glContext->setFormat(m_offscreenSurface->requestedFormat()); - - if (shareContext) - m_glContext->setShareContext(shareContext); - - if (!m_glContext->create()) { - delete m_glContext; - m_glContext = 0; - delete m_offscreenSurface; - m_offscreenSurface = 0; - return false; - } - - // 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())); - } else { - delete m_surfaceTexture; - m_surfaceTexture = 0; - glDeleteTextures(1, &m_externalTex); - } - - return m_surfaceTexture != 0; -} - -jobject QAndroidVideoRendererControl::surfaceHolder() -{ - if (!initSurfaceTexture()) - return 0; - - if (!m_surfaceHolder) { - QJNILocalRef surfaceTex = m_surfaceTexture->surfaceTexture(); - - m_androidSurface = new QJNIObject("android/view/Surface", - "(Landroid/graphics/SurfaceTexture;)V", - surfaceTex.object()); - - m_surfaceHolder = new JSurfaceTextureHolder(m_androidSurface->object()); - } - - return m_surfaceHolder->object(); -} - -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(); - } -} - -bool QAndroidVideoRendererControl::eventFilter(QObject *, QEvent *e) -{ - if (e->type() == QEvent::DynamicPropertyChange) { - QDynamicPropertyChangeEvent *event = static_cast(e); - if (event->propertyName() == "GLContext" && m_textureReadyCallback) { - m_textureReadyCallback(m_textureReadyContext); - m_textureReadyCallback = 0; - m_textureReadyContext = 0; - } - } - - return false; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/mediaplayer/qandroidvideorendercontrol.h b/src/plugins/android/mediaplayer/qandroidvideorendercontrol.h deleted file mode 100644 index cd935502c..000000000 --- a/src/plugins/android/mediaplayer/qandroidvideorendercontrol.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** 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 -#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; - bool isTextureReady() Q_DECL_OVERRIDE; - void setTextureReadyCallback(TextureReadyCallback cb, void *context = 0) Q_DECL_OVERRIDE; - void setVideoSize(const QSize &size) Q_DECL_OVERRIDE; - void stop() Q_DECL_OVERRIDE; - - bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; - -private Q_SLOTS: - void onFrameAvailable(); - -private: - bool initSurfaceTexture(); - 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; - - TextureReadyCallback m_textureReadyCallback; - void *m_textureReadyContext; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDVIDEORENDERCONTROL_H diff --git a/src/plugins/android/src/android_mediaservice.json b/src/plugins/android/src/android_mediaservice.json new file mode 100644 index 000000000..a12be52bc --- /dev/null +++ b/src/plugins/android/src/android_mediaservice.json @@ -0,0 +1,3 @@ +{ + "Keys": ["org.qt-project.qt.camera", "org.qt-project.qt.mediaplayer", "org.qt-project.qt.audiosource"] +} diff --git a/src/plugins/android/src/common/common.pri b/src/plugins/android/src/common/common.pri new file mode 100644 index 000000000..f99dad507 --- /dev/null +++ b/src/plugins/android/src/common/common.pri @@ -0,0 +1,10 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qandroidvideooutput.h \ + $$PWD/qandroidvideorendercontrol.h \ + $$PWD/qandroidmultimediautils.h + +SOURCES += \ + $$PWD/qandroidvideorendercontrol.cpp \ + $$PWD/qandroidmultimediautils.cpp diff --git a/src/plugins/android/src/common/qandroidmultimediautils.cpp b/src/plugins/android/src/common/qandroidmultimediautils.cpp new file mode 100644 index 000000000..7ae40358f --- /dev/null +++ b/src/plugins/android/src/common/qandroidmultimediautils.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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 "qandroidmultimediautils.h" + +#include + +QT_BEGIN_NAMESPACE + +int qt_findClosestValue(const QList &list, int value) +{ + if (list.size() < 2) + return 0; + + int begin = 0; + int end = list.size() - 1; + int pivot = begin + (end - begin) / 2; + int v = list.at(pivot); + + while (end - begin > 1) { + if (value == v) + return pivot; + + if (value > v) + begin = pivot; + else + end = pivot; + + pivot = begin + (end - begin) / 2; + v = list.at(pivot); + } + + return value - v >= list.at(pivot + 1) - value ? pivot + 1 : pivot; +} + +bool qt_sizeLessThan(const QSize &s1, const QSize &s2) +{ + return s1.width() * s1.height() < s2.width() * s2.height(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/common/qandroidmultimediautils.h b/src/plugins/android/src/common/qandroidmultimediautils.h new file mode 100644 index 000000000..1996209b0 --- /dev/null +++ b/src/plugins/android/src/common/qandroidmultimediautils.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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 QANDROIDMULTIMEDIAUTILS_H +#define QANDROIDMULTIMEDIAUTILS_H + +#include +#include + +QT_BEGIN_NAMESPACE + +// return the index of the closest value to in +// (binary search) +int qt_findClosestValue(const QList &list, int value); + +bool qt_sizeLessThan(const QSize &s1, const QSize &s2); + +QT_END_NAMESPACE + +#endif // QANDROIDMULTIMEDIAUTILS_H diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h new file mode 100644 index 000000000..8110b67b0 --- /dev/null +++ b/src/plugins/android/src/common/qandroidvideooutput.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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 +#include +#include + +QT_BEGIN_NAMESPACE + +typedef void (*TextureReadyCallback)(void*); + +class QAndroidVideoOutput +{ +public: + QAndroidVideoOutput() { } + virtual ~QAndroidVideoOutput() { } + + virtual jobject surfaceHolder() = 0; + + virtual bool isTextureReady() = 0; + virtual void setTextureReadyCallback(TextureReadyCallback cb, void *context = 0) = 0; + virtual jobject surfaceTexture() = 0; + + virtual void setVideoSize(const QSize &size) = 0; + virtual void stop() = 0; + + virtual QImage toImage() = 0; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDVIDEOOUTPUT_H diff --git a/src/plugins/android/src/common/qandroidvideorendercontrol.cpp b/src/plugins/android/src/common/qandroidvideorendercontrol.cpp new file mode 100644 index 000000000..c5d38aebe --- /dev/null +++ b/src/plugins/android/src/common/qandroidvideorendercontrol.cpp @@ -0,0 +1,438 @@ +/**************************************************************************** +** +** 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 +#include "jsurfacetextureholder.h" +#include +#include +#include +#include +#include +#include +#include +#include + +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(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) + , m_textureReadyCallback(0) + , m_textureReadyContext(0) +{ +} + +QAndroidVideoRendererControl::~QAndroidVideoRendererControl() +{ + if (m_glContext) + m_glContext->makeCurrent(m_offscreenSurface); + + if (m_surfaceTexture) { + m_surfaceTexture->callMethod("release"); + delete m_surfaceTexture; + m_surfaceTexture = 0; + } + if (m_androidSurface) { + m_androidSurface->callMethod("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->removeEventFilter(this); + } + + m_surface = surface; + + if (m_surface) { + m_useImage = !m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).contains(QVideoFrame::Format_BGR32); + m_surface->installEventFilter(this); + } +} + +bool QAndroidVideoRendererControl::isTextureReady() +{ + return QOpenGLContext::currentContext() || (m_surface && m_surface->property("GLContext").isValid()); +} + +void QAndroidVideoRendererControl::setTextureReadyCallback(TextureReadyCallback cb, void *context) +{ + m_textureReadyCallback = cb; + m_textureReadyContext = context; +} + +bool QAndroidVideoRendererControl::initSurfaceTexture() +{ + if (m_surfaceTexture) + return true; + + if (!m_surface) + return false; + + 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) { + QOpenGLContext *shareContext = qobject_cast(m_surface->property("GLContext").value()); + if (!shareContext) + return false; + + m_offscreenSurface = new QOffscreenSurface; + QSurfaceFormat format; + format.setSwapBehavior(QSurfaceFormat::SingleBuffer); + m_offscreenSurface->setFormat(format); + m_offscreenSurface->create(); + + m_glContext = new QOpenGLContext; + m_glContext->setFormat(m_offscreenSurface->requestedFormat()); + + if (shareContext) + m_glContext->setShareContext(shareContext); + + if (!m_glContext->create()) { + delete m_glContext; + m_glContext = 0; + delete m_offscreenSurface; + m_offscreenSurface = 0; + return false; + } + + // 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())); + } else { + delete m_surfaceTexture; + m_surfaceTexture = 0; + glDeleteTextures(1, &m_externalTex); + } + + return m_surfaceTexture != 0; +} + +jobject QAndroidVideoRendererControl::surfaceHolder() +{ + if (!initSurfaceTexture()) + return 0; + + if (!m_surfaceHolder) { + m_androidSurface = new QJNIObject("android/view/Surface", + "(Landroid/graphics/SurfaceTexture;)V", + m_surfaceTexture->object()); + + m_surfaceHolder = new JSurfaceTextureHolder(m_androidSurface->object()); + } + + return m_surfaceHolder->object(); +} + +jobject QAndroidVideoRendererControl::surfaceTexture() +{ + if (!initSurfaceTexture()) + return 0; + + return m_surfaceTexture->object(); +} + +void QAndroidVideoRendererControl::setVideoSize(const QSize &size) +{ + if (m_nativeSize == size) + return; + + stop(); + + m_nativeSize = size; + + delete m_fbo; + m_fbo = 0; +} + +void QAndroidVideoRendererControl::stop() +{ + if (m_surface && m_surface->isActive()) + m_surface->stop(); + m_nativeSize = QSize(); +} + +QImage QAndroidVideoRendererControl::toImage() +{ + if (!m_fbo) + return QImage(); + + return m_fbo->toImage().mirrored(); +} + +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(); + } +} + +bool QAndroidVideoRendererControl::eventFilter(QObject *, QEvent *e) +{ + if (e->type() == QEvent::DynamicPropertyChange) { + QDynamicPropertyChangeEvent *event = static_cast(e); + if (event->propertyName() == "GLContext" && m_textureReadyCallback) { + m_textureReadyCallback(m_textureReadyContext); + m_textureReadyCallback = 0; + m_textureReadyContext = 0; + } + } + + return false; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/common/qandroidvideorendercontrol.h b/src/plugins/android/src/common/qandroidvideorendercontrol.h new file mode 100644 index 000000000..d8078f075 --- /dev/null +++ b/src/plugins/android/src/common/qandroidvideorendercontrol.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** 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 +#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; + bool isTextureReady() Q_DECL_OVERRIDE; + void setTextureReadyCallback(TextureReadyCallback cb, void *context = 0) Q_DECL_OVERRIDE; + jobject surfaceTexture() Q_DECL_OVERRIDE; + void setVideoSize(const QSize &size) Q_DECL_OVERRIDE; + void stop() Q_DECL_OVERRIDE; + QImage toImage() Q_DECL_OVERRIDE; + + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onFrameAvailable(); + +private: + bool initSurfaceTexture(); + 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; + + TextureReadyCallback m_textureReadyCallback; + void *m_textureReadyContext; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDVIDEORENDERCONTROL_H diff --git a/src/plugins/android/src/mediacapture/mediacapture.pri b/src/plugins/android/src/mediacapture/mediacapture.pri new file mode 100644 index 000000000..d994bebfd --- /dev/null +++ b/src/plugins/android/src/mediacapture/mediacapture.pri @@ -0,0 +1,47 @@ +INCLUDEPATH += $$PWD + +SOURCES += \ + $$PWD/qandroidcaptureservice.cpp \ + $$PWD/qandroidcameracontrol.cpp \ + $$PWD/qandroidvideodeviceselectorcontrol.cpp \ + $$PWD/qandroidcamerasession.cpp \ + $$PWD/qandroidcamerazoomcontrol.cpp \ + $$PWD/qandroidcameraexposurecontrol.cpp \ + $$PWD/qandroidcameraimageprocessingcontrol.cpp \ + $$PWD/qandroidimageencodercontrol.cpp \ + $$PWD/qandroidcameraimagecapturecontrol.cpp \ + $$PWD/qandroidcameracapturedestinationcontrol.cpp \ + $$PWD/qandroidcameracapturebufferformatcontrol.cpp \ + $$PWD/qandroidmediastoragelocation.cpp \ + $$PWD/qandroidcameraflashcontrol.cpp \ + $$PWD/qandroidcamerafocuscontrol.cpp \ + $$PWD/qandroidcameralockscontrol.cpp \ + $$PWD/qandroidcapturesession.cpp \ + $$PWD/qandroidmediarecordercontrol.cpp \ + $$PWD/qandroidaudioencodersettingscontrol.cpp \ + $$PWD/qandroidmediacontainercontrol.cpp \ + $$PWD/qandroidvideoencodersettingscontrol.cpp \ + $$PWD/qandroidaudioinputselectorcontrol.cpp + +HEADERS += \ + $$PWD/qandroidcaptureservice.h \ + $$PWD/qandroidcameracontrol.h \ + $$PWD/qandroidvideodeviceselectorcontrol.h \ + $$PWD/qandroidcamerasession.h \ + $$PWD/qandroidcamerazoomcontrol.h \ + $$PWD/qandroidcameraexposurecontrol.h \ + $$PWD/qandroidcameraimageprocessingcontrol.h \ + $$PWD/qandroidimageencodercontrol.h \ + $$PWD/qandroidcameraimagecapturecontrol.h \ + $$PWD/qandroidcameracapturedestinationcontrol.h \ + $$PWD/qandroidcameracapturebufferformatcontrol.h \ + $$PWD/qandroidmediastoragelocation.h \ + $$PWD/qandroidcameraflashcontrol.h \ + $$PWD/qandroidcamerafocuscontrol.h \ + $$PWD/qandroidcameralockscontrol.h \ + $$PWD/qandroidcapturesession.h \ + $$PWD/qandroidmediarecordercontrol.h \ + $$PWD/qandroidaudioencodersettingscontrol.h \ + $$PWD/qandroidmediacontainercontrol.h \ + $$PWD/qandroidvideoencodersettingscontrol.h \ + $$PWD/qandroidaudioinputselectorcontrol.h diff --git a/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.cpp b/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.cpp new file mode 100644 index 000000000..8015ec38c --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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 "qandroidaudioencodersettingscontrol.h" + +#include "qandroidcapturesession.h" + +QT_BEGIN_NAMESPACE + +QAndroidAudioEncoderSettingsControl::QAndroidAudioEncoderSettingsControl(QAndroidCaptureSession *session) + : QAudioEncoderSettingsControl() + , m_session(session) +{ +} + +QStringList QAndroidAudioEncoderSettingsControl::supportedAudioCodecs() const +{ + return QStringList() << QLatin1String("amr-nb") << QLatin1String("amr-wb") << QLatin1String("aac"); +} + +QString QAndroidAudioEncoderSettingsControl::codecDescription(const QString &codecName) const +{ + if (codecName == QLatin1String("amr-nb")) + return tr("Adaptive Multi-Rate Narrowband (AMR-NB) audio codec"); + else if (codecName == QLatin1String("amr-wb")) + return tr("Adaptive Multi-Rate Wideband (AMR-WB) audio codec"); + else if (codecName == QLatin1String("aac")) + return tr("AAC Low Complexity (AAC-LC) audio codec"); + + return QString(); +} + +QList QAndroidAudioEncoderSettingsControl::supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const +{ + if (continuous) + *continuous = false; + + if (settings.isNull() || settings.codec().isNull() || settings.codec() == QLatin1String("aac")) { + return QList() << 8000 << 11025 << 12000 << 16000 << 22050 + << 24000 << 32000 << 44100 << 48000 << 96000; + } else if (settings.codec() == QLatin1String("amr-nb")) { + return QList() << 8000; + } else if (settings.codec() == QLatin1String("amr-wb")) { + return QList() << 16000; + } + + return QList(); +} + +QAudioEncoderSettings QAndroidAudioEncoderSettingsControl::audioSettings() const +{ + return m_session->audioSettings(); +} + +void QAndroidAudioEncoderSettingsControl::setAudioSettings(const QAudioEncoderSettings &settings) +{ + m_session->setAudioSettings(settings); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.h b/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.h new file mode 100644 index 000000000..11a35fe6a --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidaudioencodersettingscontrol.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** 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 QANDROIDAUDIOENCODERSETTINGSCONTROL_H +#define QANDROIDAUDIOENCODERSETTINGSCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCaptureSession; + +class QAndroidAudioEncoderSettingsControl : public QAudioEncoderSettingsControl +{ + Q_OBJECT +public: + explicit QAndroidAudioEncoderSettingsControl(QAndroidCaptureSession *session); + + QStringList supportedAudioCodecs() const Q_DECL_OVERRIDE; + QString codecDescription(const QString &codecName) const Q_DECL_OVERRIDE; + QList supportedSampleRates(const QAudioEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE; + QAudioEncoderSettings audioSettings() const Q_DECL_OVERRIDE; + void setAudioSettings(const QAudioEncoderSettings &settings) Q_DECL_OVERRIDE; + +private: + QAndroidCaptureSession *m_session; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDAUDIOENCODERSETTINGSCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.cpp new file mode 100644 index 000000000..4032b2d0b --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** 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 "qandroidaudioinputselectorcontrol.h" + +#include "qandroidcapturesession.h" + +QT_BEGIN_NAMESPACE + +QAndroidAudioInputSelectorControl::QAndroidAudioInputSelectorControl(QAndroidCaptureSession *session) + : QAudioInputSelectorControl() + , m_session(session) +{ + connect(m_session, SIGNAL(audioInputChanged(QString)), this, SIGNAL(activeInputChanged(QString))); +} + +QList QAndroidAudioInputSelectorControl::availableInputs() const +{ + return QList() << QLatin1String("default") + << QLatin1String("mic") + << QLatin1String("voice_uplink") + << QLatin1String("voice_downlink") + << QLatin1String("voice_call") + << QLatin1String("voice_recognition"); +} + +QString QAndroidAudioInputSelectorControl::inputDescription(const QString& name) const +{ + return availableDeviceDescription(name.toLatin1()); +} + +QString QAndroidAudioInputSelectorControl::defaultInput() const +{ + return QLatin1String("default"); +} + +QString QAndroidAudioInputSelectorControl::activeInput() const +{ + return m_session->audioInput(); +} + +void QAndroidAudioInputSelectorControl::setActiveInput(const QString& name) +{ + m_session->setAudioInput(name); +} + +QList QAndroidAudioInputSelectorControl::availableDevices() +{ + return QList() << "default" + << "mic" + << "voice_uplink" + << "voice_downlink" + << "voice_call" + << "voice_recognition"; +} + +QString QAndroidAudioInputSelectorControl::availableDeviceDescription(const QByteArray &device) +{ + if (device == "default") + return QLatin1String("Default audio source"); + else if (device == "mic") + return QLatin1String("Microphone audio source"); + else if (device == "voice_uplink") + return QLatin1String("Voice call uplink (Tx) audio source"); + else if (device == "voice_downlink") + return QLatin1String("Voice call downlink (Rx) audio source"); + else if (device == "voice_call") + return QLatin1String("Voice call uplink + downlink audio source"); + else if (device == "voice_recognition") + return QLatin1String("Microphone audio source tuned for voice recognition"); + else + return QString(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.h b/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.h new file mode 100644 index 000000000..3dfa7c712 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidaudioinputselectorcontrol.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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 QANDROIDAUDIOINPUTSELECTORCONTROL_H +#define QANDROIDAUDIOINPUTSELECTORCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCaptureSession; + +class QAndroidAudioInputSelectorControl : public QAudioInputSelectorControl +{ + Q_OBJECT +public: + explicit QAndroidAudioInputSelectorControl(QAndroidCaptureSession *session); + + QList availableInputs() const; + QString inputDescription(const QString& name) const; + QString defaultInput() const; + + QString activeInput() const; + void setActiveInput(const QString& name); + + static QList availableDevices(); + static QString availableDeviceDescription(const QByteArray &device); + +private: + QAndroidCaptureSession *m_session; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDAUDIOINPUTSELECTORCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameracapturebufferformatcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameracapturebufferformatcontrol.cpp new file mode 100644 index 000000000..dc7f20ee7 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameracapturebufferformatcontrol.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** 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 "qandroidcameracapturebufferformatcontrol.h" + +QT_BEGIN_NAMESPACE + +QAndroidCameraCaptureBufferFormatControl::QAndroidCameraCaptureBufferFormatControl() + : QCameraCaptureBufferFormatControl() +{ +} + +QList QAndroidCameraCaptureBufferFormatControl::supportedBufferFormats() const +{ + return (QList() << QVideoFrame::Format_Jpeg); +} + +QVideoFrame::PixelFormat QAndroidCameraCaptureBufferFormatControl::bufferFormat() const +{ + return QVideoFrame::Format_Jpeg; +} + +void QAndroidCameraCaptureBufferFormatControl::setBufferFormat(QVideoFrame::PixelFormat format) +{ + Q_UNUSED(format) +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameracapturebufferformatcontrol.h b/src/plugins/android/src/mediacapture/qandroidcameracapturebufferformatcontrol.h new file mode 100644 index 000000000..cf8bd4933 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameracapturebufferformatcontrol.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** 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 QANDROIDCAMERACAPTUREBUFFERFORMATCONTROL_H +#define QANDROIDCAMERACAPTUREBUFFERFORMATCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraCaptureBufferFormatControl : public QCameraCaptureBufferFormatControl +{ + Q_OBJECT +public: + QAndroidCameraCaptureBufferFormatControl(); + + QList supportedBufferFormats() const Q_DECL_OVERRIDE; + QVideoFrame::PixelFormat bufferFormat() const Q_DECL_OVERRIDE; + void setBufferFormat(QVideoFrame::PixelFormat format) Q_DECL_OVERRIDE; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERACAPTUREBUFFERFORMATCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameracapturedestinationcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameracapturedestinationcontrol.cpp new file mode 100644 index 000000000..870a4240d --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameracapturedestinationcontrol.cpp @@ -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$ +** +****************************************************************************/ + +#include "qandroidcameracapturedestinationcontrol.h" + +#include "qandroidcamerasession.h" + +QT_BEGIN_NAMESPACE + +QAndroidCameraCaptureDestinationControl::QAndroidCameraCaptureDestinationControl(QAndroidCameraSession *session) + : QCameraCaptureDestinationControl() + , m_session(session) +{ + connect(m_session, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)), + this, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations))); +} + +bool QAndroidCameraCaptureDestinationControl::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const +{ + return m_session->isCaptureDestinationSupported(destination); +} + +QCameraImageCapture::CaptureDestinations QAndroidCameraCaptureDestinationControl::captureDestination() const +{ + return m_session->captureDestination();; +} + +void QAndroidCameraCaptureDestinationControl::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) +{ + m_session->setCaptureDestination(destination); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameracapturedestinationcontrol.h b/src/plugins/android/src/mediacapture/qandroidcameracapturedestinationcontrol.h new file mode 100644 index 000000000..46ff96bca --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameracapturedestinationcontrol.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** 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 QANDROIDCAMERACAPTUREDESTINATIONCONTROL_H +#define QANDROIDCAMERACAPTUREDESTINATIONCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidCameraCaptureDestinationControl : public QCameraCaptureDestinationControl +{ + Q_OBJECT +public: + explicit QAndroidCameraCaptureDestinationControl(QAndroidCameraSession *session); + + bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const Q_DECL_OVERRIDE; + QCameraImageCapture::CaptureDestinations captureDestination() const Q_DECL_OVERRIDE; + void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) Q_DECL_OVERRIDE; + +private: + QAndroidCameraSession *m_session; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERACAPTUREDESTINATIONCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameracontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameracontrol.cpp new file mode 100644 index 000000000..f91ae1e89 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameracontrol.cpp @@ -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 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 "qandroidcameracontrol.h" + +#include "qandroidcamerasession.h" + +QT_BEGIN_NAMESPACE + +QAndroidCameraControl::QAndroidCameraControl(QAndroidCameraSession *session) + : QCameraControl(0) + , m_cameraSession(session) + +{ + connect(m_cameraSession, SIGNAL(statusChanged(QCamera::Status)), + this, SIGNAL(statusChanged(QCamera::Status))); + + connect(m_cameraSession, SIGNAL(stateChanged(QCamera::State)), + this, SIGNAL(stateChanged(QCamera::State))); + + connect(m_cameraSession, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString))); + + connect(m_cameraSession, SIGNAL(captureModeChanged(QCamera::CaptureModes)), + this, SIGNAL(captureModeChanged(QCamera::CaptureModes))); +} + +QAndroidCameraControl::~QAndroidCameraControl() +{ +} + +QCamera::CaptureModes QAndroidCameraControl::captureMode() const +{ + return m_cameraSession->captureMode(); +} + +void QAndroidCameraControl::setCaptureMode(QCamera::CaptureModes mode) +{ + m_cameraSession->setCaptureMode(mode); +} + +bool QAndroidCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const +{ + return m_cameraSession->isCaptureModeSupported(mode); +} + +void QAndroidCameraControl::setState(QCamera::State state) +{ + m_cameraSession->setState(state); +} + +QCamera::State QAndroidCameraControl::state() const +{ + return m_cameraSession->state(); +} + +QCamera::Status QAndroidCameraControl::status() const +{ + return m_cameraSession->status(); +} + +bool QAndroidCameraControl::canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const +{ + Q_UNUSED(status); + + switch (changeType) { + case QCameraControl::CaptureMode: + case QCameraControl::ImageEncodingSettings: + case QCameraControl::VideoEncodingSettings: + case QCameraControl::Viewfinder: + return true; + default: + return false; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameracontrol.h b/src/plugins/android/src/mediacapture/qandroidcameracontrol.h new file mode 100644 index 000000000..f5070c13e --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameracontrol.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** 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 QANDROIDCAMERACONTROL_H +#define QANDROIDCAMERACONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidCameraControl : public QCameraControl +{ + Q_OBJECT +public: + explicit QAndroidCameraControl(QAndroidCameraSession *session); + virtual ~QAndroidCameraControl(); + + QCamera::State state() const; + void setState(QCamera::State state); + + QCamera::Status status() const; + + QCamera::CaptureModes captureMode() const; + void setCaptureMode(QCamera::CaptureModes mode); + bool isCaptureModeSupported(QCamera::CaptureModes mode) const; + + bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const; + +private: + QAndroidCameraSession *m_cameraSession; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERACONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp new file mode 100644 index 000000000..03bbadb93 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp @@ -0,0 +1,227 @@ +/**************************************************************************** +** +** 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 "qandroidcameraexposurecontrol.h" + +#include "qandroidcamerasession.h" +#include "jcamera.h" + +QT_BEGIN_NAMESPACE + +QAndroidCameraExposureControl::QAndroidCameraExposureControl(QAndroidCameraSession *session) + : QCameraExposureControl() + , m_session(session) + , m_minExposureCompensationIndex(0) + , m_maxExposureCompensationIndex(0) + , m_exposureCompensationStep(0.0) + , m_requestedExposureCompensation(0.0) + , m_actualExposureCompensation(0.0) + , m_requestedExposureMode(QCameraExposure::ExposureAuto) + , m_actualExposureMode(QCameraExposure::ExposureAuto) +{ + connect(m_session, SIGNAL(opened()), + this, SLOT(onCameraOpened())); +} + +bool QAndroidCameraExposureControl::isParameterSupported(ExposureParameter parameter) const +{ + switch (parameter) { + case QCameraExposureControl::ISO: + return false; + case QCameraExposureControl::Aperture: + return false; + case QCameraExposureControl::ShutterSpeed: + return false; + case QCameraExposureControl::ExposureCompensation: + return true; + case QCameraExposureControl::FlashPower: + return false; + case QCameraExposureControl::FlashCompensation: + return false; + case QCameraExposureControl::TorchPower: + return false; + case QCameraExposureControl::SpotMeteringPoint: + return false; + case QCameraExposureControl::ExposureMode: + return true; + case QCameraExposureControl::MeteringMode: + return false; + default: + return false; + } +} + +QVariantList QAndroidCameraExposureControl::supportedParameterRange(ExposureParameter parameter, bool *continuous) const +{ + if (!m_session->camera()) + return QVariantList(); + + if (continuous) + *continuous = false; + + if (parameter == QCameraExposureControl::ExposureCompensation) + return m_supportedExposureCompensations; + else if (parameter == QCameraExposureControl::ExposureMode) + return m_supportedExposureModes; + + return QVariantList(); +} + +QVariant QAndroidCameraExposureControl::requestedValue(ExposureParameter parameter) const +{ + if (parameter == QCameraExposureControl::ExposureCompensation) + return QVariant::fromValue(m_requestedExposureCompensation); + else if (parameter == QCameraExposureControl::ExposureMode) + return QVariant::fromValue(m_requestedExposureMode); + + return QVariant(); +} + +QVariant QAndroidCameraExposureControl::actualValue(ExposureParameter parameter) const +{ + if (parameter == QCameraExposureControl::ExposureCompensation) + return QVariant::fromValue(m_actualExposureCompensation); + else if (parameter == QCameraExposureControl::ExposureMode) + return QVariant::fromValue(m_actualExposureMode); + + return QVariant(); +} + +bool QAndroidCameraExposureControl::setValue(ExposureParameter parameter, const QVariant& value) +{ + if (!m_session->camera() || !value.isValid()) + return false; + + if (parameter == QCameraExposureControl::ExposureCompensation) { + m_requestedExposureCompensation = value.toReal(); + emit requestedValueChanged(QCameraExposureControl::ExposureCompensation); + + int expCompIndex = qRound(m_requestedExposureCompensation / m_exposureCompensationStep); + if (expCompIndex >= m_minExposureCompensationIndex + && expCompIndex <= m_maxExposureCompensationIndex) { + m_session->camera()->setExposureCompensation(expCompIndex); + + m_actualExposureCompensation = expCompIndex * m_exposureCompensationStep; + emit actualValueChanged(QCameraExposureControl::ExposureCompensation); + + return true; + } + + } else if (parameter == QCameraExposureControl::ExposureMode) { + m_requestedExposureMode = value.value(); + emit requestedValueChanged(QCameraExposureControl::ExposureMode); + + if (!m_supportedExposureModes.isEmpty()) { + m_actualExposureMode = m_requestedExposureMode; + + QString sceneMode; + switch (m_requestedExposureMode) { + case QCameraExposure::ExposureAuto: + sceneMode = QLatin1String("auto"); + break; + case QCameraExposure::ExposureSports: + sceneMode = QLatin1String("sports"); + break; + case QCameraExposure::ExposurePortrait: + sceneMode = QLatin1String("portrait"); + break; + case QCameraExposure::ExposureBeach: + sceneMode = QLatin1String("beach"); + break; + case QCameraExposure::ExposureSnow: + sceneMode = QLatin1String("snow"); + break; + case QCameraExposure::ExposureNight: + sceneMode = QLatin1String("night"); + break; + default: + sceneMode = QLatin1String("auto"); + m_actualExposureMode = QCameraExposure::ExposureAuto; + break; + } + + m_session->camera()->setSceneMode(sceneMode); + emit actualValueChanged(QCameraExposureControl::ExposureMode); + + return true; + } + } + + return false; +} + +void QAndroidCameraExposureControl::onCameraOpened() +{ + m_requestedExposureCompensation = m_actualExposureCompensation = 0.0; + m_requestedExposureMode = m_actualExposureMode = QCameraExposure::ExposureAuto; + emit requestedValueChanged(QCameraExposureControl::ExposureCompensation); + emit actualValueChanged(QCameraExposureControl::ExposureCompensation); + emit requestedValueChanged(QCameraExposureControl::ExposureMode); + emit actualValueChanged(QCameraExposureControl::ExposureMode); + + m_minExposureCompensationIndex = m_session->camera()->getMinExposureCompensation(); + m_maxExposureCompensationIndex = m_session->camera()->getMaxExposureCompensation(); + m_exposureCompensationStep = m_session->camera()->getExposureCompensationStep(); + for (int i = m_minExposureCompensationIndex; i <= m_maxExposureCompensationIndex; ++i) + m_supportedExposureCompensations.append(i * m_exposureCompensationStep); + emit parameterRangeChanged(QCameraExposureControl::ExposureCompensation); + + m_supportedExposureModes.clear(); + QStringList sceneModes = m_session->camera()->getSupportedSceneModes(); + for (int i = 0; i < sceneModes.size(); ++i) { + const QString &sceneMode = sceneModes.at(i); + if (sceneMode == QLatin1String("auto")) + m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureAuto); + else if (sceneMode == QLatin1String("beach")) + m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureBeach); + else if (sceneMode == QLatin1String("night")) + m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureNight); + else if (sceneMode == QLatin1String("portrait")) + m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposurePortrait); + else if (sceneMode == QLatin1String("snow")) + m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureSnow); + else if (sceneMode == QLatin1String("sports")) + m_supportedExposureModes << QVariant::fromValue(QCameraExposure::ExposureSports); + } + emit parameterRangeChanged(QCameraExposureControl::ExposureMode); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.h b/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.h new file mode 100644 index 000000000..d07fea539 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** 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 QANDROIDCAMERAEXPOSURECONTROL_H +#define QANDROIDCAMERAEXPOSURECONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidCameraExposureControl : public QCameraExposureControl +{ + Q_OBJECT +public: + explicit QAndroidCameraExposureControl(QAndroidCameraSession *session); + + bool isParameterSupported(ExposureParameter parameter) const Q_DECL_OVERRIDE; + QVariantList supportedParameterRange(ExposureParameter parameter, bool *continuous) const Q_DECL_OVERRIDE; + + QVariant requestedValue(ExposureParameter parameter) const Q_DECL_OVERRIDE; + QVariant actualValue(ExposureParameter parameter) const Q_DECL_OVERRIDE; + bool setValue(ExposureParameter parameter, const QVariant& value) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onCameraOpened(); + +private: + QAndroidCameraSession *m_session; + + QVariantList m_supportedExposureCompensations; + QVariantList m_supportedExposureModes; + + int m_minExposureCompensationIndex; + int m_maxExposureCompensationIndex; + qreal m_exposureCompensationStep; + + qreal m_requestedExposureCompensation; + qreal m_actualExposureCompensation; + QCameraExposure::ExposureMode m_requestedExposureMode; + QCameraExposure::ExposureMode m_actualExposureMode; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERAEXPOSURECONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.cpp new file mode 100644 index 000000000..253b1baa5 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** 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 "qandroidcameraflashcontrol.h" + +#include "qandroidcamerasession.h" +#include "jcamera.h" + +QT_BEGIN_NAMESPACE + +QAndroidCameraFlashControl::QAndroidCameraFlashControl(QAndroidCameraSession *session) + : QCameraFlashControl() + , m_session(session) + , m_flashMode(QCameraExposure::FlashOff) +{ + connect(m_session, SIGNAL(opened()), + this, SLOT(onCameraOpened())); +} + +QCameraExposure::FlashModes QAndroidCameraFlashControl::flashMode() const +{ + return m_flashMode; +} + +void QAndroidCameraFlashControl::setFlashMode(QCameraExposure::FlashModes mode) +{ + if (m_flashMode == mode || !m_session->camera() || !isFlashModeSupported(mode)) + return; + + // if torch was enabled, it first needs to be turned off before setting another mode + if (m_flashMode == QCameraExposure::FlashVideoLight) + m_session->camera()->setFlashMode(QLatin1String("off")); + + m_flashMode = mode; + + QString flashMode; + if (mode.testFlag(QCameraExposure::FlashAuto)) + flashMode = QLatin1String("auto"); + else if (mode.testFlag(QCameraExposure::FlashOn)) + flashMode = QLatin1String("on"); + else if (mode.testFlag(QCameraExposure::FlashRedEyeReduction)) + flashMode = QLatin1String("red-eye"); + else if (mode.testFlag(QCameraExposure::FlashVideoLight)) + flashMode = QLatin1String("torch"); + else // FlashOff + flashMode = QLatin1String("off"); + + m_session->camera()->setFlashMode(flashMode); +} + +bool QAndroidCameraFlashControl::isFlashModeSupported(QCameraExposure::FlashModes mode) const +{ + return m_supportedFlashModes.contains(mode); +} + +bool QAndroidCameraFlashControl::isFlashReady() const +{ + // Android doesn't have an API for that + return true; +} + +void QAndroidCameraFlashControl::onCameraOpened() +{ + m_supportedFlashModes.clear(); + + QStringList flashModes = m_session->camera()->getSupportedFlashModes(); + for (int i = 0; i < flashModes.size(); ++i) { + const QString &flashMode = flashModes.at(i); + if (flashMode == QLatin1String("off")) + m_supportedFlashModes << QCameraExposure::FlashOff; + else if (flashMode == QLatin1String("auto")) + m_supportedFlashModes << QCameraExposure::FlashAuto; + else if (flashMode == QLatin1String("on")) + m_supportedFlashModes << QCameraExposure::FlashOn; + else if (flashMode == QLatin1String("red-eye")) + m_supportedFlashModes << QCameraExposure::FlashRedEyeReduction; + else if (flashMode == QLatin1String("torch")) + m_supportedFlashModes << QCameraExposure::FlashVideoLight; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.h b/src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.h new file mode 100644 index 000000000..35ed71894 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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 QANDROIDCAMERAFLASHCONTROL_H +#define QANDROIDCAMERAFLASHCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidCameraFlashControl : public QCameraFlashControl +{ + Q_OBJECT +public: + explicit QAndroidCameraFlashControl(QAndroidCameraSession *session); + + QCameraExposure::FlashModes flashMode() const Q_DECL_OVERRIDE; + void setFlashMode(QCameraExposure::FlashModes mode) Q_DECL_OVERRIDE; + bool isFlashModeSupported(QCameraExposure::FlashModes mode) const Q_DECL_OVERRIDE; + bool isFlashReady() const Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onCameraOpened(); + +private: + QAndroidCameraSession *m_session; + QList m_supportedFlashModes; + QCameraExposure::FlashModes m_flashMode; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERAFLASHCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp new file mode 100644 index 000000000..cb785fe1e --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp @@ -0,0 +1,304 @@ +/**************************************************************************** +** +** 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 "qandroidcamerafocuscontrol.h" + +#include "qandroidcamerasession.h" +#include "jcamera.h" + +QT_BEGIN_NAMESPACE + +static QRect adjustedArea(const QRectF &area) +{ + // Qt maps focus points in the range (0.0, 0.0) -> (1.0, 1.0) + // Android maps focus points in the range (-1000, -1000) -> (1000, 1000) + // Converts an area in Qt coordinates to Android coordinates + return QRect(-1000 + qRound(area.x() * 2000), + -1000 + qRound(area.y() * 2000), + qRound(area.width() * 2000), + qRound(area.height() * 2000)) + .intersected(QRect(-1000, -1000, 2000, 2000)); +} + +QAndroidCameraFocusControl::QAndroidCameraFocusControl(QAndroidCameraSession *session) + : QCameraFocusControl() + , m_session(session) + , m_focusMode(QCameraFocus::AutoFocus) + , m_focusPointMode(QCameraFocus::FocusPointAuto) + , m_actualFocusPoint(0.5, 0.5) + , m_continuousPictureFocusSupported(false) + , m_continuousVideoFocusSupported(false) +{ + connect(m_session, SIGNAL(opened()), + this, SLOT(onCameraOpened())); + connect(m_session, SIGNAL(captureModeChanged(QCamera::CaptureModes)), + this, SLOT(onCameraCaptureModeChanged())); +} + +QCameraFocus::FocusModes QAndroidCameraFocusControl::focusMode() const +{ + return m_focusMode; +} + +void QAndroidCameraFocusControl::setFocusMode(QCameraFocus::FocusModes mode) +{ + if (m_focusMode == mode || !m_session->camera() || !isFocusModeSupported(mode)) + return; + + QString focusMode = QLatin1String("fixed"); + + if (mode.testFlag(QCameraFocus::HyperfocalFocus)) { + focusMode = QLatin1String("edof"); + } else if (mode.testFlag(QCameraFocus::ManualFocus)) { + focusMode = QLatin1String("fixed"); + } else if (mode.testFlag(QCameraFocus::AutoFocus)) { + focusMode = QLatin1String("auto"); + } else if (mode.testFlag(QCameraFocus::MacroFocus)) { + focusMode = QLatin1String("macro"); + } else if (mode.testFlag(QCameraFocus::ContinuousFocus)) { + if ((m_session->captureMode().testFlag(QCamera::CaptureVideo) && m_continuousVideoFocusSupported) + || !m_continuousPictureFocusSupported) { + focusMode = QLatin1String("continuous-video"); + } else { + focusMode = QLatin1String("continuous-picture"); + } + } else if (mode.testFlag(QCameraFocus::InfinityFocus)) { + focusMode = QLatin1String("infinity"); + } + + m_session->camera()->setFocusMode(focusMode); + + // reset focus position + m_session->camera()->cancelAutoFocus(); + + m_focusMode = mode; + emit focusModeChanged(m_focusMode); +} + +bool QAndroidCameraFocusControl::isFocusModeSupported(QCameraFocus::FocusModes mode) const +{ + return m_supportedFocusModes.contains(mode); +} + +QCameraFocus::FocusPointMode QAndroidCameraFocusControl::focusPointMode() const +{ + return m_focusPointMode; +} + +void QAndroidCameraFocusControl::setFocusPointMode(QCameraFocus::FocusPointMode mode) +{ + if (!m_session->camera() || m_focusPointMode == mode || !isFocusPointModeSupported(mode)) + return; + + m_focusPointMode = mode; + + if (mode == QCameraFocus::FocusPointCustom) { + m_actualFocusPoint = m_customFocusPoint; + } else { + // FocusPointAuto | FocusPointCenter + // note: there is no way to know the actual focus point in FocusPointAuto mode, + // so just report the focus point to be at the center of the frame + m_actualFocusPoint = QPointF(0.5, 0.5); + } + + updateFocusZones(); + setCameraFocusArea(); + + emit focusPointModeChanged(mode); +} + +bool QAndroidCameraFocusControl::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const +{ + return m_supportedFocusPointModes.contains(mode); +} + +QPointF QAndroidCameraFocusControl::customFocusPoint() const +{ + return m_customFocusPoint; +} + +void QAndroidCameraFocusControl::setCustomFocusPoint(const QPointF &point) +{ + if (m_customFocusPoint == point) + return; + + m_customFocusPoint = point; + emit customFocusPointChanged(m_customFocusPoint); + + if (m_focusPointMode == QCameraFocus::FocusPointCustom) { + m_actualFocusPoint = m_customFocusPoint; + updateFocusZones(); + setCameraFocusArea(); + } +} + +QCameraFocusZoneList QAndroidCameraFocusControl::focusZones() const +{ + return m_focusZones; +} + +void QAndroidCameraFocusControl::onCameraOpened() +{ + connect(m_session->camera(), SIGNAL(previewSizeChanged()), + this, SLOT(onViewportSizeChanged())); + connect(m_session->camera(), SIGNAL(autoFocusStarted()), + this, SLOT(onAutoFocusStarted())); + connect(m_session->camera(), SIGNAL(autoFocusComplete(bool)), + this, SLOT(onAutoFocusComplete(bool))); + + m_supportedFocusModes.clear(); + m_continuousPictureFocusSupported = false; + m_continuousVideoFocusSupported = false; + + m_focusPointMode = QCameraFocus::FocusPointAuto; + m_actualFocusPoint = QPointF(0.5, 0.5); + m_customFocusPoint = QPointF(); + m_supportedFocusPointModes.clear(); + m_focusZones.clear(); + + QStringList focusModes = m_session->camera()->getSupportedFocusModes(); + for (int i = 0; i < focusModes.size(); ++i) { + const QString &focusMode = focusModes.at(i); + if (focusMode == QLatin1String("auto")) { + m_supportedFocusModes << QCameraFocus::AutoFocus; + } else if (focusMode == QLatin1String("continuous-picture")) { + m_supportedFocusModes << QCameraFocus::ContinuousFocus; + m_continuousPictureFocusSupported = true; + } else if (focusMode == QLatin1String("continuous-video")) { + m_supportedFocusModes << QCameraFocus::ContinuousFocus; + m_continuousVideoFocusSupported = true; + } else if (focusMode == QLatin1String("edof")) { + m_supportedFocusModes << QCameraFocus::HyperfocalFocus; + } else if (focusMode == QLatin1String("fixed")) { + m_supportedFocusModes << QCameraFocus::ManualFocus; + } else if (focusMode == QLatin1String("infinity")) { + m_supportedFocusModes << QCameraFocus::InfinityFocus; + } else if (focusMode == QLatin1String("macro")) { + m_supportedFocusModes << QCameraFocus::MacroFocus; + } + } + + m_supportedFocusPointModes << QCameraFocus::FocusPointAuto; + if (m_session->camera()->getMaxNumFocusAreas() > 0) + m_supportedFocusPointModes << QCameraFocus::FocusPointCenter << QCameraFocus::FocusPointCustom; + + emit focusModeChanged(focusMode()); + emit focusPointModeChanged(m_focusPointMode); + emit customFocusPointChanged(m_customFocusPoint); + emit focusZonesChanged(); +} + +void QAndroidCameraFocusControl::updateFocusZones(QCameraFocusZone::FocusZoneStatus status) +{ + if (!m_session->camera()) + return; + + // create a focus zone (50x50 pixel) around the focus point + m_focusZones.clear(); + + if (m_actualFocusPoint.isNull()) + return; + + QSize viewportSize = m_session->camera()->previewSize(); + QSizeF focusSize(50.f / viewportSize.width(), 50.f / viewportSize.height()); + float x = qBound(0.f, + m_actualFocusPoint.x() - (focusSize.width() / 2), + 1.f - focusSize.width()); + float y = qBound(0.f, + m_actualFocusPoint.y() - (focusSize.height() / 2), + 1.f - focusSize.height()); + + QRectF area(QPointF(x, y), focusSize); + + m_focusZones.append(QCameraFocusZone(area, status)); + + emit focusZonesChanged(); +} + +void QAndroidCameraFocusControl::setCameraFocusArea() +{ + QList areas; + if (m_focusPointMode != QCameraFocus::FocusPointAuto) { + // in FocusPointAuto mode, leave the area list empty + // to let the driver choose the focus point. + + for (int i = 0; i < m_focusZones.size(); ++i) + areas.append(adjustedArea(m_focusZones.at(i).area())); + + } + m_session->camera()->setFocusAreas(areas); +} + +void QAndroidCameraFocusControl::onViewportSizeChanged() +{ + QCameraFocusZone::FocusZoneStatus status = QCameraFocusZone::Selected; + if (!m_focusZones.isEmpty()) + status = m_focusZones.at(0).status(); + updateFocusZones(status); +} + +void QAndroidCameraFocusControl::onCameraCaptureModeChanged() +{ + if (m_focusMode == QCameraFocus::ContinuousFocus) { + QString focusMode; + if ((m_session->captureMode().testFlag(QCamera::CaptureVideo) && m_continuousVideoFocusSupported) + || !m_continuousPictureFocusSupported) { + focusMode = QLatin1String("continuous-video"); + } else { + focusMode = QLatin1String("continuous-picture"); + } + m_session->camera()->setFocusMode(focusMode); + m_session->camera()->cancelAutoFocus(); + } +} + +void QAndroidCameraFocusControl::onAutoFocusStarted() +{ + updateFocusZones(QCameraFocusZone::Selected); +} + +void QAndroidCameraFocusControl::onAutoFocusComplete(bool success) +{ + if (success) + updateFocusZones(QCameraFocusZone::Focused); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.h b/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.h new file mode 100644 index 000000000..4311e78ba --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.h @@ -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 QANDROIDCAMERAFOCUSCONTROL_H +#define QANDROIDCAMERAFOCUSCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidCameraFocusControl : public QCameraFocusControl +{ + Q_OBJECT +public: + explicit QAndroidCameraFocusControl(QAndroidCameraSession *session); + + QCameraFocus::FocusModes focusMode() const Q_DECL_OVERRIDE; + void setFocusMode(QCameraFocus::FocusModes mode) Q_DECL_OVERRIDE; + bool isFocusModeSupported(QCameraFocus::FocusModes mode) const Q_DECL_OVERRIDE; + QCameraFocus::FocusPointMode focusPointMode() const Q_DECL_OVERRIDE; + void setFocusPointMode(QCameraFocus::FocusPointMode mode) Q_DECL_OVERRIDE; + bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const Q_DECL_OVERRIDE; + QPointF customFocusPoint() const Q_DECL_OVERRIDE; + void setCustomFocusPoint(const QPointF &point) Q_DECL_OVERRIDE; + QCameraFocusZoneList focusZones() const Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onCameraOpened(); + void onViewportSizeChanged(); + void onCameraCaptureModeChanged(); + void onAutoFocusStarted(); + void onAutoFocusComplete(bool success); + +private: + void updateFocusZones(QCameraFocusZone::FocusZoneStatus status = QCameraFocusZone::Selected); + void setCameraFocusArea(); + + QAndroidCameraSession *m_session; + + QCameraFocus::FocusModes m_focusMode; + QCameraFocus::FocusPointMode m_focusPointMode; + QPointF m_actualFocusPoint; + QPointF m_customFocusPoint; + QCameraFocusZoneList m_focusZones; + + QList m_supportedFocusModes; + bool m_continuousPictureFocusSupported; + bool m_continuousVideoFocusSupported; + + QList m_supportedFocusPointModes; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERAFOCUSCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.cpp new file mode 100644 index 000000000..3c04d292f --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** 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 "qandroidcameraimagecapturecontrol.h" + +#include "qandroidcamerasession.h" + +QT_BEGIN_NAMESPACE + +QAndroidCameraImageCaptureControl::QAndroidCameraImageCaptureControl(QAndroidCameraSession *session) + : QCameraImageCaptureControl() + , m_session(session) +{ + connect(m_session, SIGNAL(readyForCaptureChanged(bool)), this, SIGNAL(readyForCaptureChanged(bool))); + connect(m_session, SIGNAL(imageExposed(int)), this, SIGNAL(imageExposed(int))); + connect(m_session, SIGNAL(imageCaptured(int,QImage)), this, SIGNAL(imageCaptured(int,QImage))); + connect(m_session, SIGNAL(imageMetadataAvailable(int,QString,QVariant)), this, SIGNAL(imageMetadataAvailable(int,QString,QVariant))); + connect(m_session, SIGNAL(imageAvailable(int,QVideoFrame)), this, SIGNAL(imageAvailable(int,QVideoFrame))); + connect(m_session, SIGNAL(imageSaved(int,QString)), this, SIGNAL(imageSaved(int,QString))); + connect(m_session, SIGNAL(imageCaptureError(int,int,QString)), this, SIGNAL(error(int,int,QString))); +} + +bool QAndroidCameraImageCaptureControl::isReadyForCapture() const +{ + return m_session->isReadyForCapture(); +} + +QCameraImageCapture::DriveMode QAndroidCameraImageCaptureControl::driveMode() const +{ + return m_session->driveMode(); +} + +void QAndroidCameraImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode) +{ + m_session->setDriveMode(mode); +} + +int QAndroidCameraImageCaptureControl::capture(const QString &fileName) +{ + return m_session->capture(fileName); +} + +void QAndroidCameraImageCaptureControl::cancelCapture() +{ + m_session->cancelCapture(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.h b/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.h new file mode 100644 index 000000000..f69913b14 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameraimagecapturecontrol.h @@ -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 QANDROIDCAMERAIMAGECAPTURECONTROL_H +#define QANDROIDCAMERAIMAGECAPTURECONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidCameraImageCaptureControl : public QCameraImageCaptureControl +{ + Q_OBJECT +public: + explicit QAndroidCameraImageCaptureControl(QAndroidCameraSession *session); + + bool isReadyForCapture() const Q_DECL_OVERRIDE; + + QCameraImageCapture::DriveMode driveMode() const Q_DECL_OVERRIDE; + void setDriveMode(QCameraImageCapture::DriveMode mode) Q_DECL_OVERRIDE; + + int capture(const QString &fileName) Q_DECL_OVERRIDE; + void cancelCapture() Q_DECL_OVERRIDE; + +private: + QAndroidCameraSession *m_session; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERAIMAGECAPTURECONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp new file mode 100644 index 000000000..ec5a3bcbf --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** 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 "qandroidcameraimageprocessingcontrol.h" + +#include "qandroidcamerasession.h" +#include "jcamera.h" + +QT_BEGIN_NAMESPACE + +QAndroidCameraImageProcessingControl::QAndroidCameraImageProcessingControl(QAndroidCameraSession *session) + : QCameraImageProcessingControl() + , m_session(session) +{ + connect(m_session, SIGNAL(opened()), + this, SLOT(onCameraOpened())); +} + +bool QAndroidCameraImageProcessingControl::isParameterSupported(ProcessingParameter parameter) const +{ + return (parameter == QCameraImageProcessingControl::WhiteBalancePreset); +} + +bool QAndroidCameraImageProcessingControl::isParameterValueSupported(ProcessingParameter parameter, + const QVariant &value) const +{ + if (parameter != QCameraImageProcessingControl::WhiteBalancePreset) + return false; + + if (!m_session->camera()) + return false; + + return m_supportedWhiteBalanceModes.contains(value.value()); +} + +QVariant QAndroidCameraImageProcessingControl::parameter(ProcessingParameter parameter) const +{ + if (parameter != QCameraImageProcessingControl::WhiteBalancePreset) + return QVariant(); + + if (!m_session->camera()) + return QVariant(); + + QString wb = m_session->camera()->getWhiteBalance(); + QCameraImageProcessing::WhiteBalanceMode mode = m_supportedWhiteBalanceModes.key(wb, QCameraImageProcessing::WhiteBalanceAuto); + + return QVariant::fromValue(mode); +} + +void QAndroidCameraImageProcessingControl::setParameter(ProcessingParameter parameter, const QVariant &value) +{ + if (parameter != QCameraImageProcessingControl::WhiteBalancePreset) + return; + + if (!m_session->camera()) + return; + + QString wb = m_supportedWhiteBalanceModes.value(value.value(), QString()); + if (!wb.isEmpty()) + m_session->camera()->setWhiteBalance(wb); +} + +void QAndroidCameraImageProcessingControl::onCameraOpened() +{ + m_supportedWhiteBalanceModes.clear(); + QStringList whiteBalanceModes = m_session->camera()->getSupportedWhiteBalance(); + for (int i = 0; i < whiteBalanceModes.size(); ++i) { + const QString &wb = whiteBalanceModes.at(i); + if (wb == QLatin1String("auto")) { + m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceAuto, + QStringLiteral("auto")); + } else if (wb == QLatin1String("cloudy-daylight")) { + m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceCloudy, + QStringLiteral("cloudy-daylight")); + } else if (wb == QLatin1String("daylight")) { + m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceSunlight, + QStringLiteral("daylight")); + } else if (wb == QLatin1String("fluorescent")) { + m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceFluorescent, + QStringLiteral("fluorescent")); + } else if (wb == QLatin1String("incandescent")) { + m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceTungsten, + QStringLiteral("incandescent")); + } else if (wb == QLatin1String("shade")) { + m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceShade, + QStringLiteral("shade")); + } else if (wb == QLatin1String("twilight")) { + m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceSunset, + QStringLiteral("twilight")); + } else if (wb == QLatin1String("warm-fluorescent")) { + m_supportedWhiteBalanceModes.insert(QCameraImageProcessing::WhiteBalanceFlash, + QStringLiteral("warm-fluorescent")); + } + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.h b/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.h new file mode 100644 index 000000000..3ef3c3144 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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 QANDROIDCAMERAIMAGEPROCESSINGCONTROL_H +#define QANDROIDCAMERAIMAGEPROCESSINGCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidCameraImageProcessingControl : public QCameraImageProcessingControl +{ + Q_OBJECT +public: + explicit QAndroidCameraImageProcessingControl(QAndroidCameraSession *session); + + bool isParameterSupported(ProcessingParameter) const Q_DECL_OVERRIDE; + bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const Q_DECL_OVERRIDE; + QVariant parameter(ProcessingParameter parameter) const Q_DECL_OVERRIDE; + void setParameter(ProcessingParameter parameter, const QVariant &value) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onCameraOpened(); + +private: + QAndroidCameraSession *m_session; + + QHash m_supportedWhiteBalanceModes; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERAIMAGEPROCESSINGCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcameralockscontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameralockscontrol.cpp new file mode 100644 index 000000000..d9f20ec04 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameralockscontrol.cpp @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** 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 "qandroidcameralockscontrol.h" + +#include "qandroidcamerasession.h" +#include "jcamera.h" +#include + +QT_BEGIN_NAMESPACE + +QAndroidCameraLocksControl::QAndroidCameraLocksControl(QAndroidCameraSession *session) + : QCameraLocksControl() + , m_session(session) + , m_supportedLocks(QCamera::NoLock) + , m_focusLockStatus(QCamera::Unlocked) + , m_exposureLockStatus(QCamera::Unlocked) + , m_whiteBalanceLockStatus(QCamera::Unlocked) +{ + connect(m_session, SIGNAL(opened()), + this, SLOT(onCameraOpened())); + + m_recalculateTimer = new QTimer(this); + m_recalculateTimer->setInterval(1000); + m_recalculateTimer->setSingleShot(true); + connect(m_recalculateTimer, SIGNAL(timeout()), this, SLOT(onRecalculateTimeOut())); +} + +QCamera::LockTypes QAndroidCameraLocksControl::supportedLocks() const +{ + return (QCamera::LockExposure | QCamera::LockWhiteBalance | QCamera::LockFocus); +} + +QCamera::LockStatus QAndroidCameraLocksControl::lockStatus(QCamera::LockType lock) const +{ + if (!m_supportedLocks.testFlag(lock) || !m_session->camera()) + return QCamera::Locked; + + if (lock == QCamera::LockFocus) + return m_focusLockStatus; + + if (lock == QCamera::LockExposure) + return m_exposureLockStatus; + + if (lock == QCamera::LockWhiteBalance) + return m_whiteBalanceLockStatus; + + return QCamera::Locked; +} + +void QAndroidCameraLocksControl::searchAndLock(QCamera::LockTypes locks) +{ + if (!m_session->camera()) + return; + + // filter out unsupported locks + locks &= m_supportedLocks; + + if (locks.testFlag(QCamera::LockFocus)) { + QString focusMode = m_session->camera()->getFocusMode(); + if (focusMode == QLatin1String("auto") + || focusMode == QLatin1String("macro") + || focusMode == QLatin1String("continuous-picture") + || focusMode == QLatin1String("continuous-video")) { + + if (m_focusLockStatus == QCamera::Searching) + m_session->camera()->cancelAutoFocus(); + else + setFocusLockStatus(QCamera::Searching, QCamera::UserRequest); + + m_session->camera()->autoFocus(); + + } else { + setFocusLockStatus(QCamera::Locked, QCamera::LockAcquired); + } + } + + if (locks.testFlag(QCamera::LockExposure) && m_exposureLockStatus != QCamera::Searching) { + if (m_session->camera()->getAutoExposureLock()) { + // if already locked, unlock and give some time to recalculate exposure + m_session->camera()->setAutoExposureLock(false); + setExposureLockStatus(QCamera::Searching, QCamera::UserRequest); + } else { + m_session->camera()->setAutoExposureLock(true); + setExposureLockStatus(QCamera::Locked, QCamera::LockAcquired); + } + } + + if (locks.testFlag(QCamera::LockWhiteBalance) && m_whiteBalanceLockStatus != QCamera::Searching) { + if (m_session->camera()->getAutoWhiteBalanceLock()) { + // if already locked, unlock and give some time to recalculate white balance + m_session->camera()->setAutoWhiteBalanceLock(false); + setWhiteBalanceLockStatus(QCamera::Searching, QCamera::UserRequest); + } else { + m_session->camera()->setAutoWhiteBalanceLock(true); + setWhiteBalanceLockStatus(QCamera::Locked, QCamera::LockAcquired); + } + } + + if (m_exposureLockStatus == QCamera::Searching || m_whiteBalanceLockStatus == QCamera::Searching) + m_recalculateTimer->start(); +} + +void QAndroidCameraLocksControl::unlock(QCamera::LockTypes locks) +{ + if (!m_session->camera()) + return; + + if (m_recalculateTimer->isActive()) + m_recalculateTimer->stop(); + + // filter out unsupported locks + locks &= m_supportedLocks; + + if (locks.testFlag(QCamera::LockFocus)) { + m_session->camera()->cancelAutoFocus(); + setFocusLockStatus(QCamera::Unlocked, QCamera::UserRequest); + } + + if (locks.testFlag(QCamera::LockExposure)) { + m_session->camera()->setAutoExposureLock(false); + setExposureLockStatus(QCamera::Unlocked, QCamera::UserRequest); + } + + if (locks.testFlag(QCamera::LockWhiteBalance)) { + m_session->camera()->setAutoWhiteBalanceLock(false); + setWhiteBalanceLockStatus(QCamera::Unlocked, QCamera::UserRequest); + } +} + +void QAndroidCameraLocksControl::onCameraOpened() +{ + m_supportedLocks = QCamera::NoLock; + m_focusLockStatus = QCamera::Unlocked; + m_exposureLockStatus = QCamera::Unlocked; + m_whiteBalanceLockStatus = QCamera::Unlocked; + + // check if focus lock is supported + QStringList focusModes = m_session->camera()->getSupportedFocusModes(); + for (int i = 0; i < focusModes.size(); ++i) { + const QString &focusMode = focusModes.at(i); + if (focusMode == QLatin1String("auto") + || focusMode == QLatin1String("continuous-picture") + || focusMode == QLatin1String("continuous-video") + || focusMode == QLatin1String("macro")) { + + m_supportedLocks |= QCamera::LockFocus; + setFocusLockStatus(QCamera::Unlocked, QCamera::UserRequest); + + connect(m_session->camera(), SIGNAL(autoFocusComplete(bool)), + this, SLOT(onCameraAutoFocusComplete(bool))); + + break; + } + } + + if (m_session->camera()->isAutoExposureLockSupported()) { + m_supportedLocks |= QCamera::LockExposure; + setExposureLockStatus(QCamera::Unlocked, QCamera::UserRequest); + } + + if (m_session->camera()->isAutoWhiteBalanceLockSupported()) { + m_supportedLocks |= QCamera::LockWhiteBalance; + setWhiteBalanceLockStatus(QCamera::Unlocked, QCamera::UserRequest); + + connect(m_session->camera(), SIGNAL(whiteBalanceChanged()), + this, SLOT(onWhiteBalanceChanged())); + } +} + +void QAndroidCameraLocksControl::onCameraAutoFocusComplete(bool success) +{ + m_focusLockStatus = success ? QCamera::Locked : QCamera::Unlocked; + QCamera::LockChangeReason reason = success ? QCamera::LockAcquired : QCamera::LockFailed; + emit lockStatusChanged(QCamera::LockFocus, m_focusLockStatus, reason); +} + +void QAndroidCameraLocksControl::onRecalculateTimeOut() +{ + if (m_exposureLockStatus == QCamera::Searching) { + m_session->camera()->setAutoExposureLock(true); + setExposureLockStatus(QCamera::Locked, QCamera::LockAcquired); + } + + if (m_whiteBalanceLockStatus == QCamera::Searching) { + m_session->camera()->setAutoWhiteBalanceLock(true); + setWhiteBalanceLockStatus(QCamera::Locked, QCamera::LockAcquired); + } +} + +void QAndroidCameraLocksControl::onWhiteBalanceChanged() +{ + // changing the white balance mode releases the white balance lock + if (m_whiteBalanceLockStatus != QCamera::Unlocked) + setWhiteBalanceLockStatus(QCamera::Unlocked, QCamera::LockLost); +} + +void QAndroidCameraLocksControl::setFocusLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason) +{ + m_focusLockStatus = status; + emit lockStatusChanged(QCamera::LockFocus, m_focusLockStatus, reason); +} + +void QAndroidCameraLocksControl::setWhiteBalanceLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason) +{ + m_whiteBalanceLockStatus = status; + emit lockStatusChanged(QCamera::LockWhiteBalance, m_whiteBalanceLockStatus, reason); +} + +void QAndroidCameraLocksControl::setExposureLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason) +{ + m_exposureLockStatus = status; + emit lockStatusChanged(QCamera::LockExposure, m_exposureLockStatus, reason); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameralockscontrol.h b/src/plugins/android/src/mediacapture/qandroidcameralockscontrol.h new file mode 100644 index 000000000..d49821bff --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcameralockscontrol.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** 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 QANDROIDCAMERALOCKSCONTROL_H +#define QANDROIDCAMERALOCKSCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; +class QTimer; + +class QAndroidCameraLocksControl : public QCameraLocksControl +{ + Q_OBJECT +public: + explicit QAndroidCameraLocksControl(QAndroidCameraSession *session); + + QCamera::LockTypes supportedLocks() const Q_DECL_OVERRIDE; + QCamera::LockStatus lockStatus(QCamera::LockType lock) const Q_DECL_OVERRIDE; + void searchAndLock(QCamera::LockTypes locks) Q_DECL_OVERRIDE; + void unlock(QCamera::LockTypes locks) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onCameraOpened(); + void onCameraAutoFocusComplete(bool success); + void onRecalculateTimeOut(); + void onWhiteBalanceChanged(); + +private: + void setFocusLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason); + void setWhiteBalanceLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason); + void setExposureLockStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason); + + QAndroidCameraSession *m_session; + + QTimer *m_recalculateTimer; + + QCamera::LockTypes m_supportedLocks; + + QCamera::LockStatus m_focusLockStatus; + QCamera::LockStatus m_exposureLockStatus; + QCamera::LockStatus m_whiteBalanceLockStatus; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERALOCKSCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp new file mode 100644 index 000000000..761b716d1 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -0,0 +1,553 @@ +/**************************************************************************** +** +** 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 "qandroidcamerasession.h" + +#include "jcamera.h" +#include "jmultimediautils.h" +#include "qandroidvideooutput.h" +#include "qandroidmultimediautils.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +static void textureReadyCallback(void *context) +{ + if (context) + reinterpret_cast(context)->onSurfaceTextureReady(); +} + +QAndroidCameraSession::QAndroidCameraSession(QObject *parent) + : QObject(parent) + , m_selectedCamera(0) + , m_camera(0) + , m_nativeOrientation(0) + , m_videoOutput(0) + , m_captureMode(QCamera::CaptureViewfinder) + , m_state(QCamera::UnloadedState) + , m_savedState(-1) + , m_status(QCamera::UnloadedStatus) + , m_previewStarted(false) + , m_imageSettingsDirty(true) + , m_captureDestination(QCameraImageCapture::CaptureToFile) + , m_captureImageDriveMode(QCameraImageCapture::SingleImageCapture) + , m_lastImageCaptureId(0) + , m_readyForCapture(false) + , m_captureCanceled(false) + , m_currentImageCaptureId(-1) +{ + if (qApp) { + connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), + this, SLOT(onApplicationStateChanged(Qt::ApplicationState))); + } +} + +QAndroidCameraSession::~QAndroidCameraSession() +{ + close(); +} + +void QAndroidCameraSession::setCaptureMode(QCamera::CaptureModes mode) +{ + if (m_captureMode == mode || !isCaptureModeSupported(mode)) + return; + + m_captureMode = mode; + emit captureModeChanged(m_captureMode); + + if (m_previewStarted && m_captureMode.testFlag(QCamera::CaptureStillImage)) + adjustViewfinderSize(m_imageSettings.resolution()); +} + +bool QAndroidCameraSession::isCaptureModeSupported(QCamera::CaptureModes mode) const +{ + if (mode & (QCamera::CaptureStillImage & QCamera::CaptureVideo)) + return false; + + return true; +} + +void QAndroidCameraSession::setState(QCamera::State state) +{ + // If the application is inactive, the camera shouldn't be started. Save the desired state + // instead and it will be set when the application becomes active. + if (qApp->applicationState() != Qt::ApplicationActive) { + m_savedState = state; + return; + } + + if (m_state == state) + return; + + switch (state) { + case QCamera::UnloadedState: + close(); + break; + case QCamera::LoadedState: + case QCamera::ActiveState: + if (!m_camera && !open()) { + emit error(QCamera::CameraError, QStringLiteral("Failed to open camera")); + return; + } + if (state == QCamera::ActiveState) + startPreview(); + else if (state == QCamera::LoadedState) + stopPreview(); + break; + } + + m_state = state; + emit stateChanged(m_state); +} + +bool QAndroidCameraSession::open() +{ + close(); + + m_status = QCamera::LoadingStatus; + emit statusChanged(m_status); + + m_camera = JCamera::open(m_selectedCamera); + + if (m_camera) { + connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed())); + connect(m_camera, SIGNAL(pictureCaptured(QByteArray)), this, SLOT(onCameraPictureCaptured(QByteArray))); + m_nativeOrientation = m_camera->getNativeOrientation(); + m_status = QCamera::LoadedStatus; + emit opened(); + } else { + m_status = QCamera::UnavailableStatus; + } + + emit statusChanged(m_status); + + return m_camera != 0; +} + +void QAndroidCameraSession::close() +{ + if (!m_camera) + return; + + stopPreview(); + + m_status = QCamera::UnloadingStatus; + emit statusChanged(m_status); + + m_readyForCapture = false; + m_currentImageCaptureId = -1; + m_currentImageCaptureFileName.clear(); + m_imageSettingsDirty = true; + + m_camera->release(); + delete m_camera; + m_camera = 0; + + m_status = QCamera::UnloadedStatus; + emit statusChanged(m_status); +} + +void QAndroidCameraSession::setVideoPreview(QAndroidVideoOutput *videoOutput) +{ + if (m_videoOutput) + m_videoOutput->stop(); + + m_videoOutput = videoOutput; +} + +void QAndroidCameraSession::adjustViewfinderSize(const QSize &captureSize, bool restartPreview) +{ + if (!m_camera) + return; + + QSize viewfinderResolution = m_camera->previewSize(); + const qreal aspectRatio = qreal(captureSize.width()) / qreal(captureSize.height()); + if (qFuzzyCompare(aspectRatio, qreal(viewfinderResolution.width()) / qreal(viewfinderResolution.height()))) + return; + + QList previewSizes = m_camera->getSupportedPreviewSizes(); + for (int i = previewSizes.count() - 1; i >= 0; --i) { + const QSize &size = previewSizes.at(i); + // search for viewfinder resolution with the same aspect ratio + if (qFuzzyCompare(aspectRatio, (static_cast(size.width())/static_cast(size.height())))) { + viewfinderResolution = size; + break; + } + } + + if (m_camera->previewSize() != viewfinderResolution) { + if (m_videoOutput) + m_videoOutput->setVideoSize(viewfinderResolution); + + // if preview is started, we have to stop it first before changing its size + if (m_previewStarted && restartPreview) + m_camera->stopPreview(); + + m_camera->setPreviewSize(viewfinderResolution); + + // restart preview + if (m_previewStarted && restartPreview) + m_camera->startPreview(); + } +} + +void QAndroidCameraSession::startPreview() +{ + if (!m_camera || m_previewStarted) + return; + + m_status = QCamera::StartingStatus; + emit statusChanged(m_status); + + applyImageSettings(); + adjustViewfinderSize(m_imageSettings.resolution()); + + if (m_videoOutput) { + if (m_videoOutput->isTextureReady()) + m_camera->setPreviewTexture(m_videoOutput->surfaceTexture()); + else + m_videoOutput->setTextureReadyCallback(textureReadyCallback, this); + } + + JMultimediaUtils::enableOrientationListener(true); + + m_camera->startPreview(); + m_previewStarted = true; + + m_status = QCamera::ActiveStatus; + emit statusChanged(m_status); + + setReadyForCapture(true); +} + +void QAndroidCameraSession::stopPreview() +{ + if (!m_camera || !m_previewStarted) + return; + + m_status = QCamera::StoppingStatus; + emit statusChanged(m_status); + + JMultimediaUtils::enableOrientationListener(false); + + m_camera->stopPreview(); + if (m_videoOutput) + m_videoOutput->stop(); + m_previewStarted = false; + + m_status = QCamera::LoadedStatus; + emit statusChanged(m_status); + + setReadyForCapture(false); +} + +void QAndroidCameraSession::setImageSettings(const QImageEncoderSettings &settings) +{ + if (m_imageSettings == settings) + return; + + m_imageSettings = settings; + if (m_imageSettings.codec().isEmpty()) + m_imageSettings.setCodec(QLatin1String("jpeg")); + + m_imageSettingsDirty = true; + + applyImageSettings(); + + if (m_readyForCapture && m_captureMode.testFlag(QCamera::CaptureStillImage)) + adjustViewfinderSize(m_imageSettings.resolution()); +} + +int QAndroidCameraSession::currentCameraRotation() const +{ + if (!m_camera) + return 0; + + // subtract natural camera orientation and physical device orientation + int rotation = 0; + int deviceOrientation = (JMultimediaUtils::getDeviceOrientation() + 45) / 90 * 90; + if (m_camera->getFacing() == JCamera::CameraFacingFront) + rotation = (m_nativeOrientation - deviceOrientation + 360) % 360; + else // back-facing camera + rotation = (m_nativeOrientation + deviceOrientation) % 360; + + return rotation; +} + +void QAndroidCameraSession::applyImageSettings() +{ + if (!m_camera || !m_imageSettingsDirty) + return; + + const QSize requestedResolution = m_imageSettings.resolution(); + const QList supportedResolutions = m_camera->getSupportedPictureSizes(); + + if (!requestedResolution.isValid()) { + // if no resolution is set, use the highest supported one + m_imageSettings.setResolution(supportedResolutions.last()); + } else if (!supportedResolutions.contains(requestedResolution)) { + // if the requested resolution is not supported, find the closest one + int reqPixelCount = requestedResolution.width() * requestedResolution.height(); + QList supportedPixelCounts; + for (int i = 0; i < supportedResolutions.size(); ++i) { + const QSize &s = supportedResolutions.at(i); + supportedPixelCounts.append(s.width() * s.height()); + } + int closestIndex = qt_findClosestValue(supportedPixelCounts, reqPixelCount); + m_imageSettings.setResolution(supportedResolutions.at(closestIndex)); + } + + int jpegQuality = 100; + switch (m_imageSettings.quality()) { + case QMultimedia::VeryLowQuality: + jpegQuality = 20; + break; + case QMultimedia::LowQuality: + jpegQuality = 40; + break; + case QMultimedia::NormalQuality: + jpegQuality = 60; + break; + case QMultimedia::HighQuality: + jpegQuality = 80; + break; + case QMultimedia::VeryHighQuality: + jpegQuality = 100; + break; + } + + m_camera->setPictureSize(m_imageSettings.resolution()); + m_camera->setJpegQuality(jpegQuality); + + m_imageSettingsDirty = false; +} + +bool QAndroidCameraSession::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const +{ + return destination & (QCameraImageCapture::CaptureToFile | QCameraImageCapture::CaptureToBuffer); +} + +QCameraImageCapture::CaptureDestinations QAndroidCameraSession::captureDestination() const +{ + return m_captureDestination; +} + +void QAndroidCameraSession::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) +{ + if (m_captureDestination != destination) { + m_captureDestination = destination; + emit captureDestinationChanged(m_captureDestination); + } +} + +bool QAndroidCameraSession::isReadyForCapture() const +{ + return m_status == QCamera::ActiveStatus && m_readyForCapture; +} + +void QAndroidCameraSession::setReadyForCapture(bool ready) +{ + if (m_readyForCapture == ready) + return; + + m_readyForCapture = ready; + emit readyForCaptureChanged(ready); +} + +QCameraImageCapture::DriveMode QAndroidCameraSession::driveMode() const +{ + return m_captureImageDriveMode; +} + +void QAndroidCameraSession::setDriveMode(QCameraImageCapture::DriveMode mode) +{ + m_captureImageDriveMode = mode; +} + +int QAndroidCameraSession::capture(const QString &fileName) +{ + ++m_lastImageCaptureId; + + if (!isReadyForCapture()) { + emit imageCaptureError(m_lastImageCaptureId, QCameraImageCapture::NotReadyError, + tr("Camera not ready")); + return m_lastImageCaptureId; + } + + if (m_captureImageDriveMode == QCameraImageCapture::SingleImageCapture) { + setReadyForCapture(false); + + m_currentImageCaptureId = m_lastImageCaptureId; + m_currentImageCaptureFileName = fileName; + + applyImageSettings(); + adjustViewfinderSize(m_imageSettings.resolution()); + + // adjust picture rotation depending on the device orientation + m_camera->setRotation(currentCameraRotation()); + + m_camera->takePicture(); + } else { + emit imageCaptureError(m_lastImageCaptureId, QCameraImageCapture::NotSupportedFeatureError, + tr("Drive mode not supported")); + } + + return m_lastImageCaptureId; +} + +void QAndroidCameraSession::cancelCapture() +{ + if (m_readyForCapture) + return; + + m_captureCanceled = true; +} + +void QAndroidCameraSession::onCameraPictureExposed() +{ + if (m_captureCanceled) + return; + + emit imageExposed(m_currentImageCaptureId); +} + +void QAndroidCameraSession::onCameraPictureCaptured(const QByteArray &data) +{ + if (!m_captureCanceled) { + // generate a preview from the viewport + if (m_videoOutput) + emit imageCaptured(m_currentImageCaptureId, m_videoOutput->toImage()); + + // Loading and saving the captured image can be slow, do it in a separate thread + QtConcurrent::run(this, &QAndroidCameraSession::processCapturedImage, + m_currentImageCaptureId, + data, + m_captureDestination, + m_currentImageCaptureFileName); + } + + m_captureCanceled = false; + + // Preview needs to be restarted after taking a picture + m_camera->startPreview(); + + setReadyForCapture(true); +} + +void QAndroidCameraSession::processCapturedImage(int id, + const QByteArray &data, + QCameraImageCapture::CaptureDestinations dest, + const QString &fileName) +{ + + + if (dest & QCameraImageCapture::CaptureToFile) { + const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName, + QAndroidMediaStorageLocation::Camera, + QLatin1String("IMG_"), + QLatin1String("jpg")); + + QFile file(actualFileName); + if (file.open(QFile::WriteOnly)) { + if (file.write(data) == data.size()) { + // if the picture is saved into the standard picture location, register it + // with the Android media scanner so it appears immediately in apps + // such as the gallery. + QString standardLoc = JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::DCIM); + if (actualFileName.startsWith(standardLoc)) + JMultimediaUtils::registerMediaFile(actualFileName); + + emit imageSaved(id, actualFileName); + } else { + emit imageCaptureError(id, QCameraImageCapture::OutOfSpaceError, file.errorString()); + } + } else { + const QString errorMessage = tr("Could not open destination file: %1").arg(actualFileName); + emit imageCaptureError(id, QCameraImageCapture::ResourceError, errorMessage); + } + } + + if (dest & QCameraImageCapture::CaptureToBuffer) { + QImage image; + const bool ok = image.loadFromData(data, "JPG"); + + if (ok) { + QVideoFrame frame(image); + emit imageAvailable(id, frame); + } else { + emit imageCaptureError(id, QCameraImageCapture::FormatError, + tr("Could not load JPEG data from captured image")); + } + } +} + +void QAndroidCameraSession::onSurfaceTextureReady() +{ + if (m_camera && m_videoOutput) + m_camera->setPreviewTexture(m_videoOutput->surfaceTexture()); +} + +void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state) +{ + switch (state) { + case Qt::ApplicationInactive: + if (m_state != QCamera::UnloadedState) { + m_savedState = m_state; + close(); + m_state = QCamera::UnloadedState; + emit stateChanged(m_state); + } + break; + case Qt::ApplicationActive: + if (m_savedState != -1) { + setState(QCamera::State(m_savedState)); + m_savedState = -1; + } + break; + default: + break; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h new file mode 100644 index 000000000..f1cf44eec --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.h @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** 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 QANDROIDCAMERASESSION_H +#define QANDROIDCAMERASESSION_H + +#include +#include +#include +#include "qandroidmediastoragelocation.h" + +QT_BEGIN_NAMESPACE + +class JCamera; +class QAndroidVideoOutput; + +class QAndroidCameraSession : public QObject +{ + Q_OBJECT +public: + explicit QAndroidCameraSession(QObject *parent = 0); + ~QAndroidCameraSession(); + + void setSelectedCamera(int cameraId) { m_selectedCamera = cameraId; } + JCamera *camera() const { return m_camera; } + + QCamera::State state() const { return m_state; } + void setState(QCamera::State state); + + QCamera::Status status() const { return m_status; } + + QCamera::CaptureModes captureMode() const { return m_captureMode; } + void setCaptureMode(QCamera::CaptureModes mode); + bool isCaptureModeSupported(QCamera::CaptureModes mode) const; + + void setVideoPreview(QAndroidVideoOutput *videoOutput); + void adjustViewfinderSize(const QSize &captureSize, bool restartPreview = true); + + QImageEncoderSettings imageSettings() const { return m_imageSettings; } + void setImageSettings(const QImageEncoderSettings &settings); + + bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const; + QCameraImageCapture::CaptureDestinations captureDestination() const; + void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination); + + bool isReadyForCapture() const; + void setReadyForCapture(bool ready); + QCameraImageCapture::DriveMode driveMode() const; + void setDriveMode(QCameraImageCapture::DriveMode mode); + int capture(const QString &fileName); + void cancelCapture(); + + void onSurfaceTextureReady(); + + int currentCameraRotation() const; + +Q_SIGNALS: + void statusChanged(QCamera::Status status); + void stateChanged(QCamera::State); + void error(int error, const QString &errorString); + void captureModeChanged(QCamera::CaptureModes); + void opened(); + + void captureDestinationChanged(QCameraImageCapture::CaptureDestinations destination); + + void readyForCaptureChanged(bool); + void imageExposed(int id); + void imageCaptured(int id, const QImage &preview); + void imageMetadataAvailable(int id, const QString &key, const QVariant &value); + void imageAvailable(int id, const QVideoFrame &buffer); + void imageSaved(int id, const QString &fileName); + void imageCaptureError(int id, int error, const QString &errorString); + +private Q_SLOTS: + void onApplicationStateChanged(Qt::ApplicationState state); + + void onCameraPictureExposed(); + void onCameraPictureCaptured(const QByteArray &data); + +private: + bool open(); + void close(); + + void startPreview(); + void stopPreview(); + + void applyImageSettings(); + void processPreviewImage(int id); + void processCapturedImage(int id, + const QByteArray &data, + QCameraImageCapture::CaptureDestinations dest, + const QString &fileName); + + int m_selectedCamera; + JCamera *m_camera; + int m_nativeOrientation; + QAndroidVideoOutput *m_videoOutput; + + QCamera::CaptureModes m_captureMode; + QCamera::State m_state; + int m_savedState; + QCamera::Status m_status; + bool m_previewStarted; + + QImageEncoderSettings m_imageSettings; + bool m_imageSettingsDirty; + QCameraImageCapture::CaptureDestinations m_captureDestination; + QCameraImageCapture::DriveMode m_captureImageDriveMode; + int m_lastImageCaptureId; + bool m_readyForCapture; + bool m_captureCanceled; + int m_currentImageCaptureId; + QString m_currentImageCaptureFileName; + + QAndroidMediaStorageLocation m_mediaStorageLocation; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERASESSION_H diff --git a/src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.cpp new file mode 100644 index 000000000..b7030e56b --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** 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 "qandroidcamerazoomcontrol.h" + +#include "qandroidcamerasession.h" +#include "jcamera.h" +#include "qandroidmultimediautils.h" +#include + +QT_BEGIN_NAMESPACE + +QAndroidCameraZoomControl::QAndroidCameraZoomControl(QAndroidCameraSession *session) + : QCameraZoomControl() + , m_cameraSession(session) + , m_maximumZoom(1.0) + , m_requestedZoom(1.0) + , m_currentZoom(1.0) +{ + connect(m_cameraSession, SIGNAL(opened()), + this, SLOT(onCameraOpened())); +} + +qreal QAndroidCameraZoomControl::maximumOpticalZoom() const +{ + // Optical zoom not supported + return 1.0; +} + +qreal QAndroidCameraZoomControl::maximumDigitalZoom() const +{ + return m_maximumZoom; +} + +qreal QAndroidCameraZoomControl::requestedOpticalZoom() const +{ + // Optical zoom not supported + return 1.0; +} + +qreal QAndroidCameraZoomControl::requestedDigitalZoom() const +{ + return m_requestedZoom; +} + +qreal QAndroidCameraZoomControl::currentOpticalZoom() const +{ + // Optical zoom not supported + return 1.0; +} + +qreal QAndroidCameraZoomControl::currentDigitalZoom() const +{ + return m_currentZoom; +} + +void QAndroidCameraZoomControl::zoomTo(qreal optical, qreal digital) +{ + Q_UNUSED(optical); + + if (!m_cameraSession->camera() || + qFuzzyCompare(m_requestedZoom, digital) || + qFuzzyCompare(m_maximumZoom, qreal(1))) { + return; + } + + m_requestedZoom = digital; + emit requestedDigitalZoomChanged(m_requestedZoom); + + digital = qBound(qreal(1), digital, m_maximumZoom); + int validZoomIndex = qt_findClosestValue(m_zoomRatios, qRound(digital * 100)); + qreal newZoom = m_zoomRatios.at(validZoomIndex) / qreal(100); + if (!qFuzzyCompare(m_currentZoom, newZoom)) { + m_cameraSession->camera()->setZoom(validZoomIndex); + m_currentZoom = newZoom; + emit currentDigitalZoomChanged(m_currentZoom); + } +} + +void QAndroidCameraZoomControl::onCameraOpened() +{ + m_requestedZoom = 1.0; + m_currentZoom = 1.0; + emit requestedDigitalZoomChanged(m_requestedZoom); + emit currentDigitalZoomChanged(m_currentZoom); + + if (m_cameraSession->camera()->isZoomSupported()) { + m_zoomRatios = m_cameraSession->camera()->getZoomRatios(); + qreal maxZoom = m_zoomRatios.last() / qreal(100); + if (m_maximumZoom != maxZoom) { + m_maximumZoom = maxZoom; + emit maximumDigitalZoomChanged(m_maximumZoom); + } + } else { + m_zoomRatios.clear(); + if (!qFuzzyCompare(m_maximumZoom, qreal(1))) { + m_maximumZoom = 1.0; + emit maximumDigitalZoomChanged(m_maximumZoom); + } + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.h b/src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.h new file mode 100644 index 000000000..b102c5dda --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.h @@ -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 QANDROIDCAMERAZOOMCONTROL_H +#define QANDROIDCAMERAZOOMCONTROL_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidCameraZoomControl : public QCameraZoomControl +{ + Q_OBJECT +public: + explicit QAndroidCameraZoomControl(QAndroidCameraSession *session); + + qreal maximumOpticalZoom() const Q_DECL_OVERRIDE; + qreal maximumDigitalZoom() const Q_DECL_OVERRIDE; + qreal requestedOpticalZoom() const Q_DECL_OVERRIDE; + qreal requestedDigitalZoom() const Q_DECL_OVERRIDE; + qreal currentOpticalZoom() const Q_DECL_OVERRIDE; + qreal currentDigitalZoom() const Q_DECL_OVERRIDE; + void zoomTo(qreal optical, qreal digital) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onCameraOpened(); + +private: + QAndroidCameraSession *m_cameraSession; + + qreal m_maximumZoom; + QList m_zoomRatios; + qreal m_requestedZoom; + qreal m_currentZoom; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAMERAZOOMCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidcaptureservice.cpp b/src/plugins/android/src/mediacapture/qandroidcaptureservice.cpp new file mode 100644 index 000000000..3468c64e5 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcaptureservice.cpp @@ -0,0 +1,216 @@ +/**************************************************************************** +** +** 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 "qandroidcaptureservice.h" + +#include "qandroidmediarecordercontrol.h" +#include "qandroidcapturesession.h" +#include "qandroidcameracontrol.h" +#include "qandroidvideodeviceselectorcontrol.h" +#include "qandroidaudioinputselectorcontrol.h" +#include "qandroidcamerasession.h" +#include "qandroidvideorendercontrol.h" +#include "qandroidcamerazoomcontrol.h" +#include "qandroidcameraexposurecontrol.h" +#include "qandroidcameraflashcontrol.h" +#include "qandroidcamerafocuscontrol.h" +#include "qandroidcameralockscontrol.h" +#include "qandroidcameraimageprocessingcontrol.h" +#include "qandroidimageencodercontrol.h" +#include "qandroidcameraimagecapturecontrol.h" +#include "qandroidcameracapturedestinationcontrol.h" +#include "qandroidcameracapturebufferformatcontrol.h" +#include "qandroidaudioencodersettingscontrol.h" +#include "qandroidvideoencodersettingscontrol.h" +#include "qandroidmediacontainercontrol.h" + +#include + +QT_BEGIN_NAMESPACE + +QAndroidCaptureService::QAndroidCaptureService(const QString &service, QObject *parent) + : QMediaService(parent) + , m_service(service) + , m_videoRendererControl(0) +{ + if (m_service == QLatin1String(Q_MEDIASERVICE_CAMERA)) { + m_cameraSession = new QAndroidCameraSession; + m_cameraControl = new QAndroidCameraControl(m_cameraSession); + m_videoInputControl = new QAndroidVideoDeviceSelectorControl(m_cameraSession); + m_cameraZoomControl = new QAndroidCameraZoomControl(m_cameraSession); + m_cameraExposureControl = new QAndroidCameraExposureControl(m_cameraSession); + m_cameraFlashControl = new QAndroidCameraFlashControl(m_cameraSession); + m_cameraFocusControl = new QAndroidCameraFocusControl(m_cameraSession); + m_cameraLocksControl = new QAndroidCameraLocksControl(m_cameraSession); + m_cameraImageProcessingControl = new QAndroidCameraImageProcessingControl(m_cameraSession); + m_imageEncoderControl = new QAndroidImageEncoderControl(m_cameraSession); + m_imageCaptureControl = new QAndroidCameraImageCaptureControl(m_cameraSession); + m_captureDestinationControl = new QAndroidCameraCaptureDestinationControl(m_cameraSession); + m_captureBufferFormatControl = new QAndroidCameraCaptureBufferFormatControl; + m_audioInputControl = 0; + } else { + m_cameraSession = 0; + m_cameraControl = 0; + m_videoInputControl = 0; + m_cameraZoomControl = 0; + m_cameraExposureControl = 0; + m_cameraFlashControl = 0; + m_cameraFocusControl = 0; + m_cameraLocksControl = 0; + m_cameraImageProcessingControl = 0; + m_imageEncoderControl = 0; + m_imageCaptureControl = 0; + m_captureDestinationControl = 0; + m_captureBufferFormatControl = 0; + m_videoEncoderSettingsControl = 0; + } + + m_captureSession = new QAndroidCaptureSession(m_cameraSession); + m_recorderControl = new QAndroidMediaRecorderControl(m_captureSession); + m_audioEncoderSettingsControl = new QAndroidAudioEncoderSettingsControl(m_captureSession); + m_mediaContainerControl = new QAndroidMediaContainerControl(m_captureSession); + + if (m_service == QLatin1String(Q_MEDIASERVICE_CAMERA)) { + m_videoEncoderSettingsControl = new QAndroidVideoEncoderSettingsControl(m_captureSession); + } else { + m_audioInputControl = new QAndroidAudioInputSelectorControl(m_captureSession); + m_captureSession->setAudioInput(m_audioInputControl->defaultInput()); + } +} + +QAndroidCaptureService::~QAndroidCaptureService() +{ + delete m_audioEncoderSettingsControl; + delete m_videoEncoderSettingsControl; + delete m_mediaContainerControl; + delete m_recorderControl; + delete m_captureSession; + delete m_cameraControl; + delete m_audioInputControl; + delete m_videoInputControl; + delete m_videoRendererControl; + delete m_cameraZoomControl; + delete m_cameraExposureControl; + delete m_cameraFlashControl; + delete m_cameraFocusControl; + delete m_cameraLocksControl; + delete m_cameraImageProcessingControl; + delete m_imageEncoderControl; + delete m_imageCaptureControl; + delete m_captureDestinationControl; + delete m_captureBufferFormatControl; + delete m_cameraSession; +} + +QMediaControl *QAndroidCaptureService::requestControl(const char *name) +{ + if (qstrcmp(name, QMediaRecorderControl_iid) == 0) + return m_recorderControl; + + if (qstrcmp(name, QMediaContainerControl_iid) == 0) + return m_mediaContainerControl; + + if (qstrcmp(name, QAudioEncoderSettingsControl_iid) == 0) + return m_audioEncoderSettingsControl; + + if (qstrcmp(name, QVideoEncoderSettingsControl_iid) == 0) + return m_videoEncoderSettingsControl; + + if (qstrcmp(name, QCameraControl_iid) == 0) + return m_cameraControl; + + if (qstrcmp(name, QAudioInputSelectorControl_iid) == 0) + return m_audioInputControl; + + if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0) + return m_videoInputControl; + + if (qstrcmp(name, QCameraZoomControl_iid) == 0) + return m_cameraZoomControl; + + if (qstrcmp(name, QCameraExposureControl_iid) == 0) + return m_cameraExposureControl; + + if (qstrcmp(name, QCameraFlashControl_iid) == 0) + return m_cameraFlashControl; + + if (qstrcmp(name, QCameraFocusControl_iid) == 0) + return m_cameraFocusControl; + + if (qstrcmp(name, QCameraLocksControl_iid) == 0) + return m_cameraLocksControl; + + if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0) + return m_cameraImageProcessingControl; + + if (qstrcmp(name, QImageEncoderControl_iid) == 0) + return m_imageEncoderControl; + + if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) + return m_imageCaptureControl; + + if (qstrcmp(name, QCameraCaptureDestinationControl_iid) == 0) + return m_captureDestinationControl; + + if (qstrcmp(name, QCameraCaptureBufferFormatControl_iid) == 0) + return m_captureBufferFormatControl; + + if (qstrcmp(name, QVideoRendererControl_iid) == 0 + && m_service == QLatin1String(Q_MEDIASERVICE_CAMERA) + && !m_videoRendererControl) { + m_videoRendererControl = new QAndroidVideoRendererControl; + m_cameraSession->setVideoPreview(m_videoRendererControl); + return m_videoRendererControl; + } + + return 0; +} + +void QAndroidCaptureService::releaseControl(QMediaControl *control) +{ + if (control && control == m_videoRendererControl) { + m_cameraSession->setVideoPreview(0); + delete m_videoRendererControl; + m_videoRendererControl = 0; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcaptureservice.h b/src/plugins/android/src/mediacapture/qandroidcaptureservice.h new file mode 100644 index 000000000..71aaf2d64 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcaptureservice.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** 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 QANDROIDCAPTURESERVICE_H +#define QANDROIDCAPTURESERVICE_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QAndroidMediaRecorderControl; +class QAndroidCaptureSession; +class QAndroidCameraControl; +class QAndroidVideoDeviceSelectorControl; +class QAndroidAudioInputSelectorControl; +class QAndroidCameraSession; +class QAndroidVideoRendererControl; +class QAndroidCameraZoomControl; +class QAndroidCameraExposureControl; +class QAndroidCameraFlashControl; +class QAndroidCameraFocusControl; +class QAndroidCameraLocksControl; +class QAndroidCameraImageProcessingControl; +class QAndroidImageEncoderControl; +class QAndroidCameraImageCaptureControl; +class QAndroidCameraCaptureDestinationControl; +class QAndroidCameraCaptureBufferFormatControl; +class QAndroidAudioEncoderSettingsControl; +class QAndroidVideoEncoderSettingsControl; +class QAndroidMediaContainerControl; + +class QAndroidCaptureService : public QMediaService +{ + Q_OBJECT + +public: + explicit QAndroidCaptureService(const QString &service, QObject *parent = 0); + virtual ~QAndroidCaptureService(); + + QMediaControl *requestControl(const char *name); + void releaseControl(QMediaControl *); + +private: + QString m_service; + + QAndroidMediaRecorderControl *m_recorderControl; + QAndroidCaptureSession *m_captureSession; + QAndroidCameraControl *m_cameraControl; + QAndroidVideoDeviceSelectorControl *m_videoInputControl; + QAndroidAudioInputSelectorControl *m_audioInputControl; + QAndroidCameraSession *m_cameraSession; + QAndroidVideoRendererControl *m_videoRendererControl; + QAndroidCameraZoomControl *m_cameraZoomControl; + QAndroidCameraExposureControl *m_cameraExposureControl; + QAndroidCameraFlashControl *m_cameraFlashControl; + QAndroidCameraFocusControl *m_cameraFocusControl; + QAndroidCameraLocksControl *m_cameraLocksControl; + QAndroidCameraImageProcessingControl *m_cameraImageProcessingControl; + QAndroidImageEncoderControl *m_imageEncoderControl; + QAndroidCameraImageCaptureControl *m_imageCaptureControl; + QAndroidCameraCaptureDestinationControl *m_captureDestinationControl; + QAndroidCameraCaptureBufferFormatControl *m_captureBufferFormatControl; + QAndroidAudioEncoderSettingsControl *m_audioEncoderSettingsControl; + QAndroidVideoEncoderSettingsControl *m_videoEncoderSettingsControl; + QAndroidMediaContainerControl *m_mediaContainerControl; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAPTURESERVICE_H diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp new file mode 100644 index 000000000..1927aeb8e --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp @@ -0,0 +1,547 @@ +/**************************************************************************** +** +** 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 "qandroidcapturesession.h" + +#include "jcamera.h" +#include "qandroidcamerasession.h" +#include "jmultimediautils.h" +#include "qandroidmultimediautils.h" +#include + +QT_BEGIN_NAMESPACE + +QAndroidCaptureSession::QAndroidCaptureSession(QAndroidCameraSession *cameraSession) + : QObject() + , m_mediaRecorder(0) + , m_cameraSession(cameraSession) + , m_audioSource(JMediaRecorder::DefaultAudioSource) + , m_duration(0) + , m_state(QMediaRecorder::StoppedState) + , m_status(QMediaRecorder::UnloadedStatus) + , m_resolutionDirty(false) + , m_containerFormatDirty(true) + , m_videoSettingsDirty(true) + , m_audioSettingsDirty(true) + , m_outputFormat(JMediaRecorder::DefaultOutputFormat) + , m_audioEncoder(JMediaRecorder::DefaultAudioEncoder) + , m_videoEncoder(JMediaRecorder::DefaultVideoEncoder) +{ + if (cameraSession) { + connect(cameraSession, SIGNAL(opened()), this, SLOT(onCameraOpened())); + connect(cameraSession, SIGNAL(statusChanged(QCamera::Status)), + this, SLOT(onCameraStatusChanged(QCamera::Status))); + connect(cameraSession, SIGNAL(captureModeChanged(QCamera::CaptureModes)), + this, SLOT(onCameraCaptureModeChanged(QCamera::CaptureModes))); + } + + m_notifyTimer.setInterval(1000); + connect(&m_notifyTimer, SIGNAL(timeout()), this, SLOT(updateDuration())); +} + +QAndroidCaptureSession::~QAndroidCaptureSession() +{ + stop(); + delete m_mediaRecorder; +} + +void QAndroidCaptureSession::setAudioInput(const QString &input) +{ + if (m_audioInput == input) + return; + + m_audioInput = input; + + if (m_audioInput == QLatin1String("default")) + m_audioSource = JMediaRecorder::DefaultAudioSource; + else if (m_audioInput == QLatin1String("mic")) + m_audioSource = JMediaRecorder::Mic; + else if (m_audioInput == QLatin1String("voice_uplink")) + m_audioSource = JMediaRecorder::VoiceUplink; + else if (m_audioInput == QLatin1String("voice_downlink")) + m_audioSource = JMediaRecorder::VoiceDownlink; + else if (m_audioInput == QLatin1String("voice_call")) + m_audioSource = JMediaRecorder::VoiceCall; + else if (m_audioInput == QLatin1String("voice_recognition")) + m_audioSource = JMediaRecorder::VoiceRecognition; + else + m_audioSource = JMediaRecorder::DefaultAudioSource; + + emit audioInputChanged(m_audioInput); +} + +QUrl QAndroidCaptureSession::outputLocation() const +{ + return m_outputLocation; +} + +bool QAndroidCaptureSession::setOutputLocation(const QUrl &location) +{ + if (m_outputLocation == location) + return false; + + m_outputLocation = location; + + if (m_outputLocation.isEmpty()) + return true; + + if (m_outputLocation.isValid() && (m_outputLocation.isLocalFile() || m_outputLocation.isRelative())) { + emit actualLocationChanged(m_outputLocation); + return true; + } + + m_outputLocation = QUrl(); + return false; +} + +QMediaRecorder::State QAndroidCaptureSession::state() const +{ + return m_state; +} + +void QAndroidCaptureSession::setState(QMediaRecorder::State state) +{ + if (m_state == state) + return; + + switch (state) { + case QMediaRecorder::StoppedState: + stop(); + break; + case QMediaRecorder::RecordingState: + if (!start()) + return; + break; + case QMediaRecorder::PausedState: + // Not supported by Android API + qWarning("QMediaRecorder::PausedState is not supported on Android"); + return; + } + + m_state = state; + emit stateChanged(m_state); +} + +bool QAndroidCaptureSession::start() +{ + if (m_state == QMediaRecorder::RecordingState) + return false; + + setStatus(QMediaRecorder::LoadingStatus); + + if (m_mediaRecorder) { + m_mediaRecorder->release(); + delete m_mediaRecorder; + } + m_mediaRecorder = new JMediaRecorder; + connect(m_mediaRecorder, SIGNAL(error(int,int)), this, SLOT(onError(int,int))); + connect(m_mediaRecorder, SIGNAL(info(int,int)), this, SLOT(onInfo(int,int))); + + // Set audio/video sources + if (m_cameraSession) { + if (m_cameraSession->status() != QCamera::ActiveStatus) { + emit error(QMediaRecorder::ResourceError, QLatin1String("Camera must be active to record it.")); + setStatus(QMediaRecorder::UnloadedStatus); + return false; + } else { + updateViewfinder(); + m_cameraSession->camera()->unlock(); + m_mediaRecorder->setCamera(m_cameraSession->camera()); + m_mediaRecorder->setAudioSource(JMediaRecorder::Camcorder); + m_mediaRecorder->setVideoSource(JMediaRecorder::Camera); + } + } else { + m_mediaRecorder->setAudioSource(m_audioSource); + } + + // Set output format + m_mediaRecorder->setOutputFormat(m_outputFormat); + + // Set audio encoder settings + m_mediaRecorder->setAudioChannels(m_audioSettings.channelCount()); + m_mediaRecorder->setAudioEncodingBitRate(m_audioSettings.bitRate()); + m_mediaRecorder->setAudioSamplingRate(m_audioSettings.sampleRate()); + m_mediaRecorder->setAudioEncoder(m_audioEncoder); + + // Set video encoder settings + if (m_cameraSession) { + m_mediaRecorder->setVideoSize(m_videoSettings.resolution()); + m_mediaRecorder->setVideoFrameRate(qRound(m_videoSettings.frameRate())); + m_mediaRecorder->setVideoEncodingBitRate(m_videoSettings.bitRate()); + m_mediaRecorder->setVideoEncoder(m_videoEncoder); + + m_mediaRecorder->setOrientationHint(m_cameraSession->currentCameraRotation()); + } + + + // Set output file + QString filePath = m_mediaStorageLocation.generateFileName(m_outputLocation.isLocalFile() ? m_outputLocation.toLocalFile() + : m_outputLocation.toString(), + m_cameraSession ? QAndroidMediaStorageLocation::Camera + : QAndroidMediaStorageLocation::Audio, + m_cameraSession ? QLatin1String("VID_") + : QLatin1String("REC_"), + m_containerFormat); + m_outputLocation = QUrl::fromLocalFile(filePath); + emit actualLocationChanged(m_outputLocation); + + m_mediaRecorder->setOutputFile(filePath); + + if (!m_mediaRecorder->prepare()) { + emit error(QMediaRecorder::FormatError, QLatin1String("Unable to prepare the media recorder.")); + setStatus(QMediaRecorder::UnloadedStatus); + return false; + } + + setStatus(QMediaRecorder::LoadedStatus); + setStatus(QMediaRecorder::StartingStatus); + + if (!m_mediaRecorder->start()) { + emit error(QMediaRecorder::FormatError, QLatin1String("Unable to start the media recorder.")); + setStatus(QMediaRecorder::UnloadedStatus); + return false; + } + + setStatus(QMediaRecorder::RecordingStatus); + + m_elapsedTime.start(); + m_notifyTimer.start(); + updateDuration(); + + if (m_cameraSession) + m_cameraSession->setReadyForCapture(false); + + return true; +} + +void QAndroidCaptureSession::stop(bool error) +{ + if (m_state == QMediaRecorder::StoppedState) + return; + + setStatus(QMediaRecorder::FinalizingStatus); + + m_mediaRecorder->stop(); + + m_notifyTimer.stop(); + updateDuration(); + m_elapsedTime.invalidate(); + + if (m_cameraSession) { + m_cameraSession->camera()->reconnect(); + // Viewport needs to be restarted + m_cameraSession->camera()->startPreview(); + m_cameraSession->setReadyForCapture(true); + } + + m_mediaRecorder->release(); + delete m_mediaRecorder; + m_mediaRecorder = 0; + + if (!error) { + // if the media is saved into the standard media location, register it + // with the Android media scanner so it appears immediately in apps + // such as the gallery. + QString mediaPath = m_outputLocation.toLocalFile(); + QString standardLoc = m_cameraSession ? JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::DCIM) + : JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::Sounds); + if (mediaPath.startsWith(standardLoc)) + JMultimediaUtils::registerMediaFile(mediaPath); + } + + setStatus(QMediaRecorder::UnloadedStatus); +} + +void QAndroidCaptureSession::setStatus(QMediaRecorder::Status status) +{ + if (m_status == status) + return; + + m_status = status; + emit statusChanged(m_status); +} + +QMediaRecorder::Status QAndroidCaptureSession::status() const +{ + return m_status; +} + +qint64 QAndroidCaptureSession::duration() const +{ + return m_duration; +} + +void QAndroidCaptureSession::setContainerFormat(const QString &format) +{ + if (m_containerFormat == format) + return; + + m_containerFormat = format; + m_containerFormatDirty = true; +} + +void QAndroidCaptureSession::setAudioSettings(const QAudioEncoderSettings &settings) +{ + if (m_audioSettings == settings) + return; + + m_audioSettings = settings; + m_audioSettingsDirty = true; +} + +void QAndroidCaptureSession::setVideoSettings(const QVideoEncoderSettings &settings) +{ + if (!m_cameraSession || m_videoSettings == settings) + return; + + if (m_videoSettings.resolution() != settings.resolution()) + m_resolutionDirty = true; + + m_videoSettings = settings; + m_videoSettingsDirty = true; +} + +void QAndroidCaptureSession::applySettings() +{ + // container settings + if (m_containerFormatDirty) { + if (m_containerFormat.isEmpty()) { + m_containerFormat = m_defaultSettings.outputFileExtension; + m_outputFormat = m_defaultSettings.outputFormat; + } else if (m_containerFormat == QLatin1String("3gp")) { + m_outputFormat = JMediaRecorder::THREE_GPP; + } else if (!m_cameraSession && m_containerFormat == QLatin1String("amr")) { + m_outputFormat = JMediaRecorder::AMR_NB_Format; + } else if (!m_cameraSession && m_containerFormat == QLatin1String("awb")) { + m_outputFormat = JMediaRecorder::AMR_WB_Format; + } else { + m_containerFormat = QStringLiteral("mp4"); + m_outputFormat = JMediaRecorder::MPEG_4; + } + + m_containerFormatDirty = false; + } + + // audio settings + if (m_audioSettingsDirty) { + if (m_audioSettings.channelCount() <= 0) + m_audioSettings.setChannelCount(m_defaultSettings.audioChannels); + if (m_audioSettings.bitRate() <= 0) + m_audioSettings.setBitRate(m_defaultSettings.audioBitRate); + if (m_audioSettings.sampleRate() <= 0) + m_audioSettings.setSampleRate(m_defaultSettings.audioSampleRate); + + if (m_audioSettings.codec().isEmpty()) + m_audioEncoder = m_defaultSettings.audioEncoder; + else if (m_audioSettings.codec() == QLatin1String("aac")) + m_audioEncoder = JMediaRecorder::AAC; + else if (m_audioSettings.codec() == QLatin1String("amr-nb")) + m_audioEncoder = JMediaRecorder::AMR_NB_Encoder; + else if (m_audioSettings.codec() == QLatin1String("amr-wb")) + m_audioEncoder = JMediaRecorder::AMR_WB_Encoder; + else + m_audioEncoder = m_defaultSettings.audioEncoder; + + m_audioSettingsDirty = false; + } + + // video settings + if (m_cameraSession && m_videoSettingsDirty) { + if (m_videoSettings.resolution().isEmpty()) { + m_videoSettings.setResolution(m_defaultSettings.videoResolution); + m_resolutionDirty = true; + } else if (!m_supportedResolutions.contains(m_videoSettings.resolution())) { + // if the requested resolution is not supported, find the closest one + QSize reqSize = m_videoSettings.resolution(); + int reqPixelCount = reqSize.width() * reqSize.height(); + QList supportedPixelCounts; + for (int i = 0; i < m_supportedResolutions.size(); ++i) { + const QSize &s = m_supportedResolutions.at(i); + supportedPixelCounts.append(s.width() * s.height()); + } + int closestIndex = qt_findClosestValue(supportedPixelCounts, reqPixelCount); + m_videoSettings.setResolution(m_supportedResolutions.at(closestIndex)); + m_resolutionDirty = true; + } + + if (m_videoSettings.frameRate() <= 0) + m_videoSettings.setFrameRate(m_defaultSettings.videoFrameRate); + if (m_videoSettings.bitRate() <= 0) + m_videoSettings.setBitRate(m_defaultSettings.videoBitRate); + + if (m_videoSettings.codec().isEmpty()) + m_videoEncoder = m_defaultSettings.videoEncoder; + else if (m_videoSettings.codec() == QLatin1String("h263")) + m_videoEncoder = JMediaRecorder::H263; + else if (m_videoSettings.codec() == QLatin1String("h264")) + m_videoEncoder = JMediaRecorder::H264; + else if (m_videoSettings.codec() == QLatin1String("mpeg4_sp")) + m_videoEncoder = JMediaRecorder::MPEG_4_SP; + else + m_videoEncoder = m_defaultSettings.videoEncoder; + + m_videoSettingsDirty = false; + } +} + +void QAndroidCaptureSession::updateViewfinder() +{ + if (!m_resolutionDirty) + return; + + m_cameraSession->camera()->stopPreview(); + m_cameraSession->adjustViewfinderSize(m_videoSettings.resolution(), false); + m_resolutionDirty = false; +} + +void QAndroidCaptureSession::updateDuration() +{ + if (m_elapsedTime.isValid()) + m_duration = m_elapsedTime.elapsed(); + + emit durationChanged(m_duration); +} + +void QAndroidCaptureSession::onCameraOpened() +{ + m_supportedResolutions.clear(); + m_supportedFramerates.clear(); + + // get supported resolutions from predefined profiles + for (int i = 0; i < 8; ++i) { + CaptureProfile profile = getProfile(i); + if (!profile.isNull) { + if (i == 1) // QUALITY_HIGH + m_defaultSettings = profile; + + if (!m_supportedResolutions.contains(profile.videoResolution)) + m_supportedResolutions.append(profile.videoResolution); + if (!m_supportedFramerates.contains(profile.videoFrameRate)) + m_supportedFramerates.append(profile.videoFrameRate); + } + } + + qSort(m_supportedResolutions.begin(), m_supportedResolutions.end(), qt_sizeLessThan); + qSort(m_supportedFramerates.begin(), m_supportedFramerates.end()); +} + +QAndroidCaptureSession::CaptureProfile QAndroidCaptureSession::getProfile(int id) +{ + CaptureProfile profile; + bool hasProfile = QJNIObject::callStaticMethod("android/media/CamcorderProfile", + "hasProfile", + "(II)Z", + m_cameraSession->camera()->cameraId(), + id); + + if (hasProfile) { + QJNILocalRef ref = QJNIObject::callStaticObjectMethod("android/media/CamcorderProfile", + "get", + "(II)Landroid/media/CamcorderProfile;", + m_cameraSession->camera()->cameraId(), + id); + + + QJNIObject obj(ref.object()); + + profile.outputFormat = JMediaRecorder::OutputFormat(obj.getField("fileFormat")); + profile.audioEncoder = JMediaRecorder::AudioEncoder(obj.getField("audioCodec")); + profile.audioBitRate = obj.getField("audioBitRate"); + profile.audioChannels = obj.getField("audioChannels"); + profile.audioSampleRate = obj.getField("audioSampleRate"); + profile.videoEncoder = JMediaRecorder::VideoEncoder(obj.getField("videoCodec")); + profile.videoBitRate = obj.getField("videoBitRate"); + profile.videoFrameRate = obj.getField("videoFrameRate"); + profile.videoResolution = QSize(obj.getField("videoFrameWidth"), + obj.getField("videoFrameHeight")); + + if (profile.outputFormat == JMediaRecorder::MPEG_4) + profile.outputFileExtension = QStringLiteral("mp4"); + else if (profile.outputFormat == JMediaRecorder::THREE_GPP) + profile.outputFileExtension = QStringLiteral("3gp"); + else if (profile.outputFormat == JMediaRecorder::AMR_NB_Format) + profile.outputFileExtension = QStringLiteral("amr"); + else if (profile.outputFormat == JMediaRecorder::AMR_WB_Format) + profile.outputFileExtension = QStringLiteral("awb"); + + profile.isNull = false; + } + + return profile; +} + +void QAndroidCaptureSession::onCameraStatusChanged(QCamera::Status status) +{ + if (status == QCamera::StoppingStatus) + setState(QMediaRecorder::StoppedState); +} + +void QAndroidCaptureSession::onCameraCaptureModeChanged(QCamera::CaptureModes mode) +{ + if (!mode.testFlag(QCamera::CaptureVideo)) + setState(QMediaRecorder::StoppedState); +} + +void QAndroidCaptureSession::onError(int what, int extra) +{ + Q_UNUSED(what) + Q_UNUSED(extra) + stop(true); + m_state = QMediaRecorder::StoppedState; + emit stateChanged(m_state); + emit error(QMediaRecorder::ResourceError, QLatin1String("Unknown error.")); +} + +void QAndroidCaptureSession::onInfo(int what, int extra) +{ + Q_UNUSED(extra) + if (what == 800) { + // MEDIA_RECORDER_INFO_MAX_DURATION_REACHED + setState(QMediaRecorder::StoppedState); + emit error(QMediaRecorder::OutOfSpaceError, QLatin1String("Maximum duration reached.")); + } else if (what == 801) { + // MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED + setState(QMediaRecorder::StoppedState); + emit error(QMediaRecorder::OutOfSpaceError, QLatin1String("Maximum file size reached.")); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.h b/src/plugins/android/src/mediacapture/qandroidcapturesession.h new file mode 100644 index 000000000..6d3645c13 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.h @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** 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 QANDROIDCAPTURESESSION_H +#define QANDROIDCAPTURESESSION_H + +#include +#include +#include +#include +#include +#include "qandroidmediastoragelocation.h" +#include "jmediarecorder.h" + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidCaptureSession : public QObject +{ + Q_OBJECT +public: + explicit QAndroidCaptureSession(QAndroidCameraSession *cameraSession = 0); + ~QAndroidCaptureSession(); + + QList supportedResolutions() const { return m_supportedResolutions; } + QList supportedFrameRates() const { return m_supportedFramerates; } + + QString audioInput() const { return m_audioInput; } + void setAudioInput(const QString &input); + + QUrl outputLocation() const; + bool setOutputLocation(const QUrl &location); + + QMediaRecorder::State state() const; + void setState(QMediaRecorder::State state); + + QMediaRecorder::Status status() const; + + qint64 duration() const; + + QString containerFormat() const { return m_containerFormat; } + void setContainerFormat(const QString &format); + + QAudioEncoderSettings audioSettings() const { return m_audioSettings; } + void setAudioSettings(const QAudioEncoderSettings &settings); + + QVideoEncoderSettings videoSettings() const { return m_videoSettings; } + void setVideoSettings(const QVideoEncoderSettings &settings); + + void applySettings(); + +Q_SIGNALS: + void audioInputChanged(const QString& name); + void stateChanged(QMediaRecorder::State state); + void statusChanged(QMediaRecorder::Status status); + void durationChanged(qint64 position); + void actualLocationChanged(const QUrl &location); + void error(int error, const QString &errorString); + +private Q_SLOTS: + void updateDuration(); + void onCameraOpened(); + void onCameraStatusChanged(QCamera::Status); + void onCameraCaptureModeChanged(QCamera::CaptureModes mode); + + void onError(int what, int extra); + void onInfo(int what, int extra); + +private: + struct CaptureProfile { + JMediaRecorder::OutputFormat outputFormat; + QString outputFileExtension; + + JMediaRecorder::AudioEncoder audioEncoder; + int audioBitRate; + int audioChannels; + int audioSampleRate; + + JMediaRecorder::VideoEncoder videoEncoder; + int videoBitRate; + int videoFrameRate; + QSize videoResolution; + + bool isNull; + + CaptureProfile() + : outputFormat(JMediaRecorder::MPEG_4) + , outputFileExtension(QLatin1String("mp4")) + , audioEncoder(JMediaRecorder::DefaultAudioEncoder) + , audioBitRate(128000) + , audioChannels(2) + , audioSampleRate(44100) + , videoEncoder(JMediaRecorder::DefaultVideoEncoder) + , videoBitRate(1) + , videoFrameRate(-1) + , videoResolution(320, 240) + , isNull(true) + { } + }; + + CaptureProfile getProfile(int id); + + bool start(); + void stop(bool error = false); + + void setStatus(QMediaRecorder::Status status); + + void updateViewfinder(); + + JMediaRecorder *m_mediaRecorder; + QAndroidCameraSession *m_cameraSession; + + QString m_audioInput; + JMediaRecorder::AudioSource m_audioSource; + + QAndroidMediaStorageLocation m_mediaStorageLocation; + + QElapsedTimer m_elapsedTime; + QTimer m_notifyTimer; + qint64 m_duration; + + QMediaRecorder::State m_state; + QMediaRecorder::Status m_status; + QUrl m_outputLocation; + + CaptureProfile m_defaultSettings; + + QString m_containerFormat; + QAudioEncoderSettings m_audioSettings; + QVideoEncoderSettings m_videoSettings; + bool m_resolutionDirty; + bool m_containerFormatDirty; + bool m_videoSettingsDirty; + bool m_audioSettingsDirty; + JMediaRecorder::OutputFormat m_outputFormat; + JMediaRecorder::AudioEncoder m_audioEncoder; + JMediaRecorder::VideoEncoder m_videoEncoder; + + QList m_supportedResolutions; + QList m_supportedFramerates; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDCAPTURESESSION_H diff --git a/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp b/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp new file mode 100644 index 000000000..79e0651a3 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp @@ -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$ +** +****************************************************************************/ + +#include "qandroidimageencodercontrol.h" + +#include "qandroidcamerasession.h" +#include "jcamera.h" + +QT_BEGIN_NAMESPACE + +QAndroidImageEncoderControl::QAndroidImageEncoderControl(QAndroidCameraSession *session) + : QImageEncoderControl() + , m_session(session) +{ + connect(m_session, SIGNAL(opened()), + this, SLOT(onCameraOpened())); +} + +QStringList QAndroidImageEncoderControl::supportedImageCodecs() const +{ + return QStringList() << QLatin1String("jpeg"); +} + +QString QAndroidImageEncoderControl::imageCodecDescription(const QString &codecName) const +{ + if (codecName == QLatin1String("jpeg")) + return tr("JPEG image"); + + return QString(); +} + +QList QAndroidImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const +{ + Q_UNUSED(settings); + + if (continuous) + *continuous = false; + + return m_supportedResolutions; +} + +QImageEncoderSettings QAndroidImageEncoderControl::imageSettings() const +{ + return m_session->imageSettings(); +} + +void QAndroidImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings) +{ + m_session->setImageSettings(settings); +} + +void QAndroidImageEncoderControl::onCameraOpened() +{ + m_supportedResolutions = m_session->camera()->getSupportedPictureSizes(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h b/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h new file mode 100644 index 000000000..23e397d4d --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h @@ -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 QANDROIDIMAGEENCODERCONTROL_H +#define QANDROIDIMAGEENCODERCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidImageEncoderControl : public QImageEncoderControl +{ + Q_OBJECT +public: + explicit QAndroidImageEncoderControl(QAndroidCameraSession *session); + + QStringList supportedImageCodecs() const Q_DECL_OVERRIDE; + QString imageCodecDescription(const QString &codecName) const Q_DECL_OVERRIDE; + QList supportedResolutions(const QImageEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE; + QImageEncoderSettings imageSettings() const Q_DECL_OVERRIDE; + void setImageSettings(const QImageEncoderSettings &settings) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void onCameraOpened(); + +private: + QAndroidCameraSession *m_session; + + QList m_supportedResolutions; +}; + +#endif // QANDROIDIMAGEENCODERCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.cpp b/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.cpp new file mode 100644 index 000000000..33f7f2351 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** 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 "qandroidmediacontainercontrol.h" + +#include "qandroidcapturesession.h" + +QT_BEGIN_NAMESPACE + +QAndroidMediaContainerControl::QAndroidMediaContainerControl(QAndroidCaptureSession *session) + : QMediaContainerControl() + , m_session(session) +{ +} + +QStringList QAndroidMediaContainerControl::supportedContainers() const +{ + return QStringList() << QLatin1String("mp4") + << QLatin1String("3gp") + << QLatin1String("amr") + << QLatin1String("awb"); +} + +QString QAndroidMediaContainerControl::containerFormat() const +{ + return m_session->containerFormat(); +} + +void QAndroidMediaContainerControl::setContainerFormat(const QString &format) +{ + m_session->setContainerFormat(format); +} + +QString QAndroidMediaContainerControl::containerDescription(const QString &formatMimeType) const +{ + if (formatMimeType == QLatin1String("mp4")) + return tr("MPEG4 media file format"); + else if (formatMimeType == QLatin1String("3gp")) + return tr("3GPP media file format"); + else if (formatMimeType == QLatin1String("amr")) + return tr("AMR NB file format"); + else if (formatMimeType == QLatin1String("awb")) + return tr("AMR WB file format"); + + return QString(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.h b/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.h new file mode 100644 index 000000000..d52e8365f --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidmediacontainercontrol.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** 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 QANDROIDMEDIACONTAINERCONTROL_H +#define QANDROIDMEDIACONTAINERCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCaptureSession; + +class QAndroidMediaContainerControl : public QMediaContainerControl +{ + Q_OBJECT +public: + QAndroidMediaContainerControl(QAndroidCaptureSession *session); + + QStringList supportedContainers() const Q_DECL_OVERRIDE; + QString containerFormat() const Q_DECL_OVERRIDE; + void setContainerFormat(const QString &format) Q_DECL_OVERRIDE; + QString containerDescription(const QString &formatMimeType) const Q_DECL_OVERRIDE; + +private: + QAndroidCaptureSession *m_session; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDMEDIACONTAINERCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.cpp b/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.cpp new file mode 100644 index 000000000..dab9f3e30 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** 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 "qandroidmediarecordercontrol.h" + +#include "qandroidcapturesession.h" + +QT_BEGIN_NAMESPACE + +QAndroidMediaRecorderControl::QAndroidMediaRecorderControl(QAndroidCaptureSession *session) + : QMediaRecorderControl() + , m_session(session) +{ + connect(m_session, SIGNAL(stateChanged(QMediaRecorder::State)), this, SIGNAL(stateChanged(QMediaRecorder::State))); + connect(m_session, SIGNAL(statusChanged(QMediaRecorder::Status)), this, SIGNAL(statusChanged(QMediaRecorder::Status))); + connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64))); + connect(m_session, SIGNAL(actualLocationChanged(QUrl)), this, SIGNAL(actualLocationChanged(QUrl))); + connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString))); +} + +QUrl QAndroidMediaRecorderControl::outputLocation() const +{ + return m_session->outputLocation(); +} + +bool QAndroidMediaRecorderControl::setOutputLocation(const QUrl &location) +{ + return m_session->setOutputLocation(location); +} + +QMediaRecorder::State QAndroidMediaRecorderControl::state() const +{ + return m_session->state(); +} + +QMediaRecorder::Status QAndroidMediaRecorderControl::status() const +{ + return m_session->status(); +} + +qint64 QAndroidMediaRecorderControl::duration() const +{ + return m_session->duration(); +} + +bool QAndroidMediaRecorderControl::isMuted() const +{ + // No API for this in Android + return false; +} + +qreal QAndroidMediaRecorderControl::volume() const +{ + // No API for this in Android + return 1.0; +} + +void QAndroidMediaRecorderControl::applySettings() +{ + m_session->applySettings(); +} + +void QAndroidMediaRecorderControl::setState(QMediaRecorder::State state) +{ + m_session->setState(state); +} + +void QAndroidMediaRecorderControl::setMuted(bool muted) +{ + // No API for this in Android + Q_UNUSED(muted) + qWarning("QMediaRecorder::setMuted() is not supported on Android."); +} + +void QAndroidMediaRecorderControl::setVolume(qreal volume) +{ + // No API for this in Android + Q_UNUSED(volume) + qWarning("QMediaRecorder::setVolume() is not supported on Android."); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.h b/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.h new file mode 100644 index 000000000..c518f7f70 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidmediarecordercontrol.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** 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 QANDROIDMEDIARECORDERCONTROL_H +#define QANDROIDMEDIARECORDERCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCaptureSession; + +class QAndroidMediaRecorderControl : public QMediaRecorderControl +{ + Q_OBJECT +public: + explicit QAndroidMediaRecorderControl(QAndroidCaptureSession *session); + + QUrl outputLocation() const Q_DECL_OVERRIDE; + bool setOutputLocation(const QUrl &location) Q_DECL_OVERRIDE; + QMediaRecorder::State state() const Q_DECL_OVERRIDE; + QMediaRecorder::Status status() const Q_DECL_OVERRIDE; + qint64 duration() const Q_DECL_OVERRIDE; + bool isMuted() const Q_DECL_OVERRIDE; + qreal volume() const Q_DECL_OVERRIDE; + void applySettings() Q_DECL_OVERRIDE; + +public Q_SLOTS: + void setState(QMediaRecorder::State state) Q_DECL_OVERRIDE; + void setMuted(bool muted) Q_DECL_OVERRIDE; + void setVolume(qreal volume) Q_DECL_OVERRIDE; + +private: + QAndroidCaptureSession *m_session; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDMEDIARECORDERCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidmediastoragelocation.cpp b/src/plugins/android/src/mediacapture/qandroidmediastoragelocation.cpp new file mode 100644 index 000000000..ee6734158 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidmediastoragelocation.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** 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 "qandroidmediastoragelocation.h" + +#include "jmultimediautils.h" + +QT_BEGIN_NAMESPACE + +QAndroidMediaStorageLocation::QAndroidMediaStorageLocation() +{ +} + +QDir QAndroidMediaStorageLocation::defaultDir(CaptureSource source) const +{ + QStringList dirCandidates; + + if (source == Camera) + dirCandidates << JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::DCIM); + else + dirCandidates << JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::Sounds); + dirCandidates << QDir::homePath(); + dirCandidates << QDir::currentPath(); + dirCandidates << QDir::tempPath(); + + Q_FOREACH (const QString &path, dirCandidates) { + if (QFileInfo(path).isWritable()) + return QDir(path); + } + + return QDir(); +} + +QString QAndroidMediaStorageLocation::generateFileName(const QString &requestedName, + CaptureSource source, + const QString &prefix, + const QString &extension) const +{ + if (requestedName.isEmpty()) + return generateFileName(prefix, defaultDir(source), extension); + + QString path = requestedName; + + if (QFileInfo(path).isRelative()) + path = defaultDir(source).absoluteFilePath(path); + + if (QFileInfo(path).isDir()) + return generateFileName(prefix, QDir(path), extension); + + if (!path.endsWith(extension)) + path.append(QString(".%1").arg(extension)); + + return path; +} + +QString QAndroidMediaStorageLocation::generateFileName(const QString &prefix, + const QDir &dir, + const QString &extension) const +{ + QMutexLocker lock(&m_mutex); + + const QString lastMediaKey = dir.absolutePath() + QLatin1Char(' ') + prefix + QLatin1Char(' ') + extension; + qint64 lastMediaIndex = m_lastUsedIndex.value(lastMediaKey, 0); + + if (lastMediaIndex == 0) { + // first run, find the maximum media number during the fist capture + Q_FOREACH (const QString &fileName, dir.entryList(QStringList() << QString("%1*.%2").arg(prefix).arg(extension))) { + const qint64 mediaIndex = fileName.mid(prefix.length(), fileName.size() - prefix.length() - extension.length() - 1).toInt(); + lastMediaIndex = qMax(lastMediaIndex, mediaIndex); + } + } + + // don't just rely on cached lastMediaIndex value, + // someone else may create a file after camera started + while (true) { + const QString name = QString("%1%2.%3").arg(prefix) + .arg(lastMediaIndex + 1, 8, 10, QLatin1Char('0')) + .arg(extension); + + const QString path = dir.absoluteFilePath(name); + if (!QFileInfo(path).exists()) { + m_lastUsedIndex[lastMediaKey] = lastMediaIndex + 1; + return path; + } + + lastMediaIndex++; + } + + return QString(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidmediastoragelocation.h b/src/plugins/android/src/mediacapture/qandroidmediastoragelocation.h new file mode 100644 index 000000000..2e63f3df5 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidmediastoragelocation.h @@ -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 QANDROIDMEDIASTORAGELOCATION_H +#define QANDROIDMEDIASTORAGELOCATION_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QAndroidMediaStorageLocation +{ +public: + enum CaptureSource { + Camera, + Audio + }; + + QAndroidMediaStorageLocation(); + + QDir defaultDir(CaptureSource source) const; + + QString generateFileName(const QString &requestedName, CaptureSource source, const QString &prefix, const QString &extension) const; + QString generateFileName(const QString &prefix, const QDir &dir, const QString &extension) const; + +private: + mutable QHash m_lastUsedIndex; + + mutable QMutex m_mutex; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDMEDIASTORAGELOCATION_H diff --git a/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp new file mode 100644 index 000000000..26dce565e --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** 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 "qandroidvideodeviceselectorcontrol.h" + +#include "qandroidcamerasession.h" +#include "jcamera.h" +#include + +QT_BEGIN_NAMESPACE + +QList QAndroidVideoDeviceSelectorControl::m_names; +QStringList QAndroidVideoDeviceSelectorControl::m_descriptions; + +QAndroidVideoDeviceSelectorControl::QAndroidVideoDeviceSelectorControl(QAndroidCameraSession *session) + : QVideoDeviceSelectorControl(0) + , m_selectedDevice(0) + , m_cameraSession(session) +{ + if (m_names.isEmpty()) + update(); +} + +QAndroidVideoDeviceSelectorControl::~QAndroidVideoDeviceSelectorControl() +{ +} + +int QAndroidVideoDeviceSelectorControl::deviceCount() const +{ + return m_names.size(); +} + +QString QAndroidVideoDeviceSelectorControl::deviceName(int index) const +{ + return m_names.at(index); +} + +QString QAndroidVideoDeviceSelectorControl::deviceDescription(int index) const +{ + return m_descriptions.at(index); +} + +int QAndroidVideoDeviceSelectorControl::defaultDevice() const +{ + return 0; +} + +int QAndroidVideoDeviceSelectorControl::selectedDevice() const +{ + return m_selectedDevice; +} + +void QAndroidVideoDeviceSelectorControl::setSelectedDevice(int index) +{ + if (index != m_selectedDevice) { + m_selectedDevice = index; + m_cameraSession->setSelectedCamera(m_selectedDevice); + emit selectedDeviceChanged(index); + emit selectedDeviceChanged(deviceName(index)); + } +} + +void QAndroidVideoDeviceSelectorControl::update() +{ + m_names.clear(); + m_descriptions.clear(); + + QJNIObject cameraInfo("android/hardware/Camera$CameraInfo"); + int numCameras = QJNIObject::callStaticMethod("android/hardware/Camera", + "getNumberOfCameras"); + + for (int i = 0; i < numCameras; ++i) { + QJNIObject::callStaticMethod("android/hardware/Camera", + "getCameraInfo", + "(ILandroid/hardware/Camera$CameraInfo;)V", + i, cameraInfo.object()); + + JCamera::CameraFacing facing = JCamera::CameraFacing(cameraInfo.getField("facing")); + + switch (facing) { + case JCamera::CameraFacingBack: + m_names.append("back"); + m_descriptions.append(QStringLiteral("Rear-facing camera")); + break; + case JCamera::CameraFacingFront: + m_names.append("front"); + m_descriptions.append(QStringLiteral("Front-facing camera")); + break; + default: + break; + } + } +} + +QList QAndroidVideoDeviceSelectorControl::availableDevices() +{ + if (m_names.isEmpty()) + update(); + + return m_names; +} + +QString QAndroidVideoDeviceSelectorControl::availableDeviceDescription(const QByteArray &device) +{ + int i = m_names.indexOf(device); + if (i != -1) + return m_descriptions.at(i); + + return QString(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.h b/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.h new file mode 100644 index 000000000..3ebf83ab2 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** 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 QANDROIDVIDEODEVICESELECTORCONTROL_H +#define QANDROIDVIDEODEVICESELECTORCONTROL_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCameraSession; + +class QAndroidVideoDeviceSelectorControl : public QVideoDeviceSelectorControl +{ + Q_OBJECT +public: + explicit QAndroidVideoDeviceSelectorControl(QAndroidCameraSession *session); + ~QAndroidVideoDeviceSelectorControl(); + + int deviceCount() const; + + QString deviceName(int index) const; + QString deviceDescription(int index) const; + + int defaultDevice() const; + int selectedDevice() const; + + void setSelectedDevice(int index); + + static QList availableDevices(); + static QString availableDeviceDescription(const QByteArray &device); + +private: + static void update(); + + int m_selectedDevice; + static QList m_names; + static QStringList m_descriptions; + + QAndroidCameraSession *m_cameraSession; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDVIDEODEVICESELECTORCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.cpp b/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.cpp new file mode 100644 index 000000000..20318c8bb --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** 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 "qandroidvideoencodersettingscontrol.h" + +#include "qandroidcapturesession.h" + +QT_BEGIN_NAMESPACE + +QAndroidVideoEncoderSettingsControl::QAndroidVideoEncoderSettingsControl(QAndroidCaptureSession *session) + : QVideoEncoderSettingsControl() + , m_session(session) +{ +} + +QList QAndroidVideoEncoderSettingsControl::supportedResolutions(const QVideoEncoderSettings &, bool *continuous) const +{ + if (continuous) + *continuous = false; + + return m_session->supportedResolutions(); +} + +QList QAndroidVideoEncoderSettingsControl::supportedFrameRates(const QVideoEncoderSettings &, bool *continuous) const +{ + if (continuous) + *continuous = false; + + return m_session->supportedFrameRates(); +} + +QStringList QAndroidVideoEncoderSettingsControl::supportedVideoCodecs() const +{ + return QStringList() << QLatin1String("h263") + << QLatin1String("h264") + << QLatin1String("mpeg4_sp"); +} + +QString QAndroidVideoEncoderSettingsControl::videoCodecDescription(const QString &codecName) const +{ + if (codecName == QLatin1String("h263")) + return tr("H.263 compression"); + else if (codecName == QLatin1String("h264")) + return tr("H.264 compression"); + else if (codecName == QLatin1String("mpeg4_sp")) + return tr("MPEG-4 SP compression"); + + return QString(); +} + +QVideoEncoderSettings QAndroidVideoEncoderSettingsControl::videoSettings() const +{ + return m_session->videoSettings(); +} + +void QAndroidVideoEncoderSettingsControl::setVideoSettings(const QVideoEncoderSettings &settings) +{ + m_session->setVideoSettings(settings); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.h b/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.h new file mode 100644 index 000000000..1427924c0 --- /dev/null +++ b/src/plugins/android/src/mediacapture/qandroidvideoencodersettingscontrol.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** 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 QANDROIDVIDEOENCODERSETTINGSCONTROL_H +#define QANDROIDVIDEOENCODERSETTINGSCONTROL_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidCaptureSession; + +class QAndroidVideoEncoderSettingsControl : public QVideoEncoderSettingsControl +{ + Q_OBJECT +public: + explicit QAndroidVideoEncoderSettingsControl(QAndroidCaptureSession *session); + + QList supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE; + QList supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous = 0) const Q_DECL_OVERRIDE; + QStringList supportedVideoCodecs() const Q_DECL_OVERRIDE; + QString videoCodecDescription(const QString &codecName) const Q_DECL_OVERRIDE; + QVideoEncoderSettings videoSettings() const Q_DECL_OVERRIDE; + void setVideoSettings(const QVideoEncoderSettings &settings) Q_DECL_OVERRIDE; + +private: + QAndroidCaptureSession *m_session; +}; + +QT_END_NAMESPACE + +#endif // QANDROIDVIDEOENCODERSETTINGSCONTROL_H diff --git a/src/plugins/android/src/mediaplayer/mediaplayer.pri b/src/plugins/android/src/mediaplayer/mediaplayer.pri new file mode 100644 index 000000000..c386d996b --- /dev/null +++ b/src/plugins/android/src/mediaplayer/mediaplayer.pri @@ -0,0 +1,11 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/qandroidmediaplayercontrol.h \ + $$PWD/qandroidmediaservice.h \ + $$PWD/qandroidmetadatareadercontrol.h + +SOURCES += \ + $$PWD/qandroidmediaplayercontrol.cpp \ + $$PWD/qandroidmediaservice.cpp \ + $$PWD/qandroidmetadatareadercontrol.cpp diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp new file mode 100644 index 000000000..753c60662 --- /dev/null +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp @@ -0,0 +1,535 @@ +/**************************************************************************** +** +** 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 + +static void textureReadyCallback(void *context) +{ + if (context) + reinterpret_cast(context)->onSurfaceTextureReady(); +} + +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), + mPendingSetMedia(false) +{ + 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() +{ + mMediaPlayer->stop(); + mMediaPlayer->release(); + 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 + || !mMediaPlayerReady) ? 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; + + if (mVideoOutput && !mMediaPlayer->display()) { + // if a video output is set but the video texture is not ready, delay loading the media + // since it can cause problems on some hardware + mPendingSetMedia = true; + return; + } + + 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; + + if (mVideoOutput && !mMediaPlayer->display()) { + if (mVideoOutput->isTextureReady()) + mMediaPlayer->setDisplay(mVideoOutput->surfaceHolder()); + else + mVideoOutput->setTextureReadyCallback(textureReadyCallback, this); + } +} + +void QAndroidMediaPlayerControl::play() +{ + if (!mMediaPlayerReady) { + mPendingState = QMediaPlayer::PlayingState; + if (mCurrentState == QMediaPlayer::StoppedState + && !mMediaContent.isNull() + && mCurrentMediaStatus != QMediaPlayer::LoadingMedia + && !mPendingSetMedia) { + 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: + setMediaStatus(QMediaPlayer::LoadedMedia); + if (mBuffering) { + setMediaStatus(mBufferPercent == 100 ? QMediaPlayer::BufferedMedia + : QMediaPlayer::BufferingMedia); + } else { + onBufferChanged(100); + } + 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 = percent != 100; + mBufferPercent = percent; + Q_EMIT bufferStatusChanged(mBufferPercent); + + updateAvailablePlaybackRanges(); + + if (mBufferPercent == 100) + setMediaStatus(QMediaPlayer::BufferedMedia); +} + +void QAndroidMediaPlayerControl::onVideoSizeChanged(qint32 width, qint32 height) +{ + QSize newSize(width, height); + + if (width == 0 || height == 0 || newSize == mVideoSize) + return; + + setVideoAvailable(true); + mVideoSize = newSize; + + if (mVideoOutput) + mVideoOutput->setVideoSize(mVideoSize); +} + +void QAndroidMediaPlayerControl::onSurfaceTextureReady() +{ + if (!mMediaPlayer->display() && mVideoOutput) { + mMediaPlayer->setDisplay(mVideoOutput->surfaceHolder()); + flushPendingStates(); + } +} + +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; + + if (!available) + mVideoSize = QSize(); + + mVideoAvailable = available; + Q_EMIT videoAvailableChanged(mVideoAvailable); +} + +void QAndroidMediaPlayerControl::resetBufferingProgress() +{ + mBuffering = false; + mBufferPercent = 0; + mAvailablePlaybackRange = QMediaTimeRange(); + Q_EMIT bufferStatusChanged(mBufferPercent); +} + +void QAndroidMediaPlayerControl::flushPendingStates() +{ + if (mPendingSetMedia) { + setMedia(mMediaContent, 0); + mPendingSetMedia = false; + return; + } + + 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 diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h new file mode 100644 index 000000000..93eced853 --- /dev/null +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** 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 +#include +#include + +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); + void onSurfaceTextureReady(); + +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; + QSize mVideoSize; + bool mBuffering; + QMediaTimeRange mAvailablePlaybackRange; + bool mMediaPlayerReady; + QMediaPlayer::State mPendingState; + qint64 mPendingPosition; + bool mPendingSetMedia; + + 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 diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp new file mode 100644 index 000000000..175958676 --- /dev/null +++ b/src/plugins/android/src/mediaplayer/qandroidmediaservice.cpp @@ -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 diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaservice.h b/src/plugins/android/src/mediaplayer/qandroidmediaservice.h new file mode 100644 index 000000000..4d310e8e0 --- /dev/null +++ b/src/plugins/android/src/mediaplayer/qandroidmediaservice.h @@ -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 + +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 diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp new file mode 100644 index 000000000..e52c46387 --- /dev/null +++ b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp @@ -0,0 +1,222 @@ +/**************************************************************************** +** +** 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 +#include +#include + +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 diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h new file mode 100644 index 000000000..7ea736ffd --- /dev/null +++ b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h @@ -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 +#include + +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 diff --git a/src/plugins/android/src/qandroidmediaserviceplugin.cpp b/src/plugins/android/src/qandroidmediaserviceplugin.cpp new file mode 100644 index 000000000..d7a2cd29f --- /dev/null +++ b/src/plugins/android/src/qandroidmediaserviceplugin.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** 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 "qandroidcaptureservice.h" +#include "qandroidvideodeviceselectorcontrol.h" +#include "qandroidaudioinputselectorcontrol.h" +#include "jmediaplayer.h" +#include "jsurfacetexture.h" +#include "jsurfacetextureholder.h" +#include "jcamera.h" +#include "jmultimediautils.h" +#include "jmediarecorder.h" +#include + +QT_BEGIN_NAMESPACE + +QAndroidMediaServicePlugin::QAndroidMediaServicePlugin() +{ +} + +QAndroidMediaServicePlugin::~QAndroidMediaServicePlugin() +{ +} + +QMediaService *QAndroidMediaServicePlugin::create(const QString &key) +{ + if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) + return new QAndroidMediaService; + + if (key == QLatin1String(Q_MEDIASERVICE_CAMERA) + || key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)) { + return new QAndroidCaptureService(key); + } + + 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; + + if (service == Q_MEDIASERVICE_CAMERA) + return QMediaServiceProviderHint::VideoSurface | QMediaServiceProviderHint::RecordingSupport; + + if (service == Q_MEDIASERVICE_AUDIOSOURCE) + return QMediaServiceProviderHint::RecordingSupport; + + return QMediaServiceProviderHint::Features(); +} + +QList QAndroidMediaServicePlugin::devices(const QByteArray &service) const +{ + if (service == Q_MEDIASERVICE_CAMERA) + return QAndroidVideoDeviceSelectorControl::availableDevices(); + + if (service == Q_MEDIASERVICE_AUDIOSOURCE) + return QAndroidAudioInputSelectorControl::availableDevices(); + + return QList(); +} + +QString QAndroidMediaServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) +{ + if (service == Q_MEDIASERVICE_CAMERA) + return QAndroidVideoDeviceSelectorControl::availableDeviceDescription(device); + + if (service == Q_MEDIASERVICE_AUDIOSOURCE) + return QAndroidAudioInputSelectorControl::availableDeviceDescription(device); + + return QString(); +} + + +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) || + !JCamera::initJNI(jniEnv) || + !JMultimediaUtils::initJNI(jniEnv) || + !JMediaRecorder::initJNI(jniEnv)) { + return JNI_ERR; + } + + return JNI_VERSION_1_4; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/qandroidmediaserviceplugin.h b/src/plugins/android/src/qandroidmediaserviceplugin.h new file mode 100644 index 000000000..18b1def21 --- /dev/null +++ b/src/plugins/android/src/qandroidmediaserviceplugin.h @@ -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 QANDROIDMEDIASERVICEPLUGIN_H +#define QANDROIDMEDIASERVICEPLUGIN_H + +#include + +QT_BEGIN_NAMESPACE + +class QAndroidMediaServicePlugin + : public QMediaServiceProviderPlugin + , public QMediaServiceSupportedDevicesInterface + , public QMediaServiceFeaturesInterface +{ + Q_OBJECT + Q_INTERFACES(QMediaServiceSupportedDevicesInterface) + Q_INTERFACES(QMediaServiceFeaturesInterface) + Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" + FILE "android_mediaservice.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; + + QList devices(const QByteArray &service) const; + QString deviceDescription(const QByteArray &service, const QByteArray &device); +}; + +QT_END_NAMESPACE + +#endif // QANDROIDMEDIASERVICEPLUGIN_H diff --git a/src/plugins/android/src/src.pro b/src/plugins/android/src/src.pro new file mode 100644 index 000000000..e99fd30f5 --- /dev/null +++ b/src/plugins/android/src/src.pro @@ -0,0 +1,19 @@ +TARGET = qtmedia_android +QT += multimedia-private gui-private platformsupport-private network + +PLUGIN_TYPE = mediaservice +PLUGIN_CLASS_NAME = QAndroidMediaServicePlugin +load(qt_plugin) + +HEADERS += \ + qandroidmediaserviceplugin.h + +SOURCES += \ + qandroidmediaserviceplugin.cpp + +include (wrappers/wrappers.pri) +include (common/common.pri) +include (mediaplayer/mediaplayer.pri) +include (mediacapture/mediacapture.pri) + +OTHER_FILES += android_mediaservice.json diff --git a/src/plugins/android/src/wrappers/jcamera.cpp b/src/plugins/android/src/wrappers/jcamera.cpp new file mode 100644 index 000000000..9005ac6e0 --- /dev/null +++ b/src/plugins/android/src/wrappers/jcamera.cpp @@ -0,0 +1,712 @@ +/**************************************************************************** +** +** 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 "jcamera.h" + +#include +#include +#include +#include "qandroidmultimediautils.h" + +QT_BEGIN_NAMESPACE + +static jclass g_qtCameraClass = 0; +static QMap g_objectMap; + +static QRect areaToRect(jobject areaObj) +{ + QJNIObject area(areaObj); + QJNILocalRef rectRef = area.getObjectField("rect", "android/graphics/Rect"); + QJNIObject rect(rectRef.object()); + + return QRect(rect.getField("left"), + rect.getField("top"), + rect.callMethod("width"), + rect.callMethod("height")); +} + +static QJNILocalRef rectToArea(const QRect &rect) +{ + QJNIObject jrect("android/graphics/Rect", + "(IIII)V", + rect.left(), rect.top(), rect.right(), rect.bottom()); + + QJNIObject area("android/hardware/Camera$Area", + "(Landroid/graphics/Rect;I)V", + jrect.object(), 500); + + return QJNILocalRef(QAttachedJNIEnv()->NewLocalRef(area.object())); +} + +// native method for QtCamera.java +static void notifyAutoFocusComplete(JNIEnv* , jobject, int id, jboolean success) +{ + JCamera *obj = g_objectMap.value(id, 0); + if (obj) + Q_EMIT obj->autoFocusComplete(success); +} + +static void notifyPictureExposed(JNIEnv* , jobject, int id) +{ + JCamera *obj = g_objectMap.value(id, 0); + if (obj) + Q_EMIT obj->pictureExposed(); +} + +static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data) +{ + JCamera *obj = g_objectMap.value(id, 0); + if (obj) { + QByteArray bytes; + int arrayLength = env->GetArrayLength(data); + bytes.resize(arrayLength); + env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); + Q_EMIT obj->pictureCaptured(bytes); + } +} + +JCamera::JCamera(int cameraId, jobject cam) + : QObject() + , QJNIObject(cam) + , m_cameraId(cameraId) + , m_info(0) + , m_parameters(0) + , m_hasAPI14(false) +{ + if (isValid()) { + g_objectMap.insert(cameraId, this); + + m_info = new QJNIObject("android/hardware/Camera$CameraInfo"); + callStaticMethod("android/hardware/Camera", + "getCameraInfo", + "(ILandroid/hardware/Camera$CameraInfo;)V", + cameraId, m_info->object()); + + QJNILocalRef params = callObjectMethod("getParameters", + "()Landroid/hardware/Camera$Parameters;"); + m_parameters = new QJNIObject(params.object()); + + // Check if API 14 is available + QAttachedJNIEnv env; + jclass clazz = env->FindClass("android/hardware/Camera"); + if (env->ExceptionCheck()) { + clazz = 0; + env->ExceptionClear(); + } + if (clazz) { + // startFaceDetection() was added in API 14 + jmethodID id = env->GetMethodID(clazz, "startFaceDetection", "()V"); + if (env->ExceptionCheck()) { + id = 0; + env->ExceptionClear(); + } + m_hasAPI14 = bool(id); + } + } +} + +JCamera::~JCamera() +{ + if (isValid()) + g_objectMap.remove(m_cameraId); + delete m_parameters; + delete m_info; +} + +JCamera *JCamera::open(int cameraId) +{ + QAttachedJNIEnv env; + + QJNILocalRef camera = callStaticObjectMethod(g_qtCameraClass, + "open", + "(I)Lorg/qtproject/qt5/android/multimedia/QtCamera;", + cameraId); + + if (camera.isNull()) + return 0; + else + return new JCamera(cameraId, camera.object()); +} + +void JCamera::lock() +{ + callMethod("lock"); +} + +void JCamera::unlock() +{ + callMethod("unlock"); +} + +void JCamera::reconnect() +{ + callMethod("reconnect"); +} + +void JCamera::release() +{ + m_previewSize = QSize(); + delete m_parameters; + m_parameters = 0; + callMethod("release"); +} + +JCamera::CameraFacing JCamera::getFacing() +{ + return CameraFacing(m_info->getField("facing")); +} + +int JCamera::getNativeOrientation() +{ + return m_info->getField("orientation"); +} + +QSize JCamera::getPreferredPreviewSizeForVideo() +{ + if (!m_parameters || !m_parameters->isValid()) + return QSize(); + + QJNILocalRef sizeRef = m_parameters->callObjectMethod("getPreferredPreviewSizeForVideo", + "()Landroid/hardware/Camera$Size;"); + + QJNIObject size(sizeRef.object()); + return QSize(size.getField("width"), size.getField("height")); +} + +QList JCamera::getSupportedPreviewSizes() +{ + QList list; + + if (m_parameters && m_parameters->isValid()) { + QJNILocalRef sizeListRef = m_parameters->callObjectMethod("getSupportedPreviewSizes", + "()Ljava/util/List;"); + QJNIObject sizeList(sizeListRef.object()); + int count = sizeList.callMethod("size"); + for (int i = 0; i < count; ++i) { + QJNILocalRef sizeRef = sizeList.callObjectMethod("get", + "(I)Ljava/lang/Object;", + i); + QJNIObject size(sizeRef.object()); + list.append(QSize(size.getField("width"), size.getField("height"))); + } + + qSort(list.begin(), list.end(), qt_sizeLessThan); + } + + return list; +} + +void JCamera::setPreviewSize(const QSize &size) +{ + if (!m_parameters || !m_parameters->isValid()) + return; + + m_previewSize = size; + + m_parameters->callMethod("setPreviewSize", "(II)V", size.width(), size.height()); + applyParameters(); + + emit previewSizeChanged(); +} + +void JCamera::setPreviewTexture(jobject surfaceTexture) +{ + callMethod("setPreviewTexture", "(Landroid/graphics/SurfaceTexture;)V", surfaceTexture); +} + +bool JCamera::isZoomSupported() +{ + if (!m_parameters || !m_parameters->isValid()) + return false; + + return m_parameters->callMethod("isZoomSupported"); +} + +int JCamera::getMaxZoom() +{ + if (!m_parameters || !m_parameters->isValid()) + return 0; + + return m_parameters->callMethod("getMaxZoom"); +} + +QList JCamera::getZoomRatios() +{ + QList ratios; + + if (m_parameters && m_parameters->isValid()) { + QJNILocalRef ratioListRef = m_parameters->callObjectMethod("getZoomRatios", + "()Ljava/util/List;"); + QJNIObject ratioList(ratioListRef.object()); + int count = ratioList.callMethod("size"); + for (int i = 0; i < count; ++i) { + QJNILocalRef zoomRatioRef = ratioList.callObjectMethod("get", + "(I)Ljava/lang/Object;", + i); + + QJNIObject zoomRatio(zoomRatioRef.object()); + ratios.append(zoomRatio.callMethod("intValue")); + } + } + + return ratios; +} + +int JCamera::getZoom() +{ + if (!m_parameters || !m_parameters->isValid()) + return 0; + + return m_parameters->callMethod("getZoom"); +} + +void JCamera::setZoom(int value) +{ + if (!m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setZoom", "(I)V", value); + applyParameters(); +} + +QStringList JCamera::getSupportedFlashModes() +{ + return callStringListMethod("getSupportedFlashModes"); +} + +QString JCamera::getFlashMode() +{ + QString value; + + if (m_parameters && m_parameters->isValid()) { + QJNILocalRef flashMode = m_parameters->callObjectMethod("getFlashMode", + "()Ljava/lang/String;"); + if (!flashMode.isNull()) + value = qt_convertJString(flashMode.object()); + } + + return value; +} + +void JCamera::setFlashMode(const QString &value) +{ + if (!m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setFlashMode", + "(Ljava/lang/String;)V", + qt_toJString(value).object()); + applyParameters(); +} + +QStringList JCamera::getSupportedFocusModes() +{ + return callStringListMethod("getSupportedFocusModes"); +} + +QString JCamera::getFocusMode() +{ + QString value; + + if (m_parameters && m_parameters->isValid()) { + QJNILocalRef focusMode = m_parameters->callObjectMethod("getFocusMode", + "()Ljava/lang/String;"); + if (!focusMode.isNull()) + value = qt_convertJString(focusMode.object()); + } + + return value; +} + +void JCamera::setFocusMode(const QString &value) +{ + if (!m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setFocusMode", + "(Ljava/lang/String;)V", + qt_toJString(value).object()); + applyParameters(); +} + +int JCamera::getMaxNumFocusAreas() +{ + if (!m_hasAPI14 || !m_parameters || !m_parameters->isValid()) + return 0; + + return m_parameters->callMethod("getMaxNumFocusAreas"); +} + +QList JCamera::getFocusAreas() +{ + QList areas; + + if (m_hasAPI14 && m_parameters && m_parameters->isValid()) { + QJNILocalRef listRef = m_parameters->callObjectMethod("getFocusAreas", + "()Ljava/util/List;"); + + if (!listRef.isNull()) { + QJNIObject list(listRef.object()); + int count = list.callMethod("size"); + for (int i = 0; i < count; ++i) { + QJNILocalRef areaRef = list.callObjectMethod("get", + "(I)Ljava/lang/Object;", + i); + + areas.append(areaToRect(areaRef.object())); + } + } + } + + return areas; +} + +void JCamera::setFocusAreas(const QList &areas) +{ + if (!m_hasAPI14 || !m_parameters || !m_parameters->isValid()) + return; + + QJNILocalRef list(0); + + if (!areas.isEmpty()) { + QAttachedJNIEnv env; + QJNIObject arrayList("java/util/ArrayList", "(I)V", areas.size()); + for (int i = 0; i < areas.size(); ++i) { + arrayList.callMethod("add", + "(Ljava/lang/Object;)Z", + rectToArea(areas.at(i)).object()); + if (env->ExceptionCheck()) + env->ExceptionClear(); + } + list = env->NewLocalRef(arrayList.object()); + } + + m_parameters->callMethod("setFocusAreas", "(Ljava/util/List;)V", list.object()); + + applyParameters(); +} + +void JCamera::autoFocus() +{ + callMethod("autoFocus"); + emit autoFocusStarted(); +} + +void JCamera::cancelAutoFocus() +{ + callMethod("cancelAutoFocus"); +} + +bool JCamera::isAutoExposureLockSupported() +{ + if (!m_hasAPI14 || !m_parameters || !m_parameters->isValid()) + return false; + + return m_parameters->callMethod("isAutoExposureLockSupported"); +} + +bool JCamera::getAutoExposureLock() +{ + if (!m_hasAPI14 || !m_parameters || !m_parameters->isValid()) + return false; + + return m_parameters->callMethod("getAutoExposureLock"); +} + +void JCamera::setAutoExposureLock(bool toggle) +{ + if (!m_hasAPI14 || !m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setAutoExposureLock", "(Z)V", toggle); + applyParameters(); +} + +bool JCamera::isAutoWhiteBalanceLockSupported() +{ + if (!m_hasAPI14 || !m_parameters || !m_parameters->isValid()) + return false; + + return m_parameters->callMethod("isAutoWhiteBalanceLockSupported"); +} + +bool JCamera::getAutoWhiteBalanceLock() +{ + if (!m_hasAPI14 || !m_parameters || !m_parameters->isValid()) + return false; + + return m_parameters->callMethod("getAutoWhiteBalanceLock"); +} + +void JCamera::setAutoWhiteBalanceLock(bool toggle) +{ + if (!m_hasAPI14 || !m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setAutoWhiteBalanceLock", "(Z)V", toggle); + applyParameters(); +} + +int JCamera::getExposureCompensation() +{ + if (!m_parameters || !m_parameters->isValid()) + return 0; + + return m_parameters->callMethod("getExposureCompensation"); +} + +void JCamera::setExposureCompensation(int value) +{ + if (!m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setExposureCompensation", "(I)V", value); + applyParameters(); +} + +float JCamera::getExposureCompensationStep() +{ + if (!m_parameters || !m_parameters->isValid()) + return 0; + + return m_parameters->callMethod("getExposureCompensationStep"); +} + +int JCamera::getMinExposureCompensation() +{ + if (!m_parameters || !m_parameters->isValid()) + return 0; + + return m_parameters->callMethod("getMinExposureCompensation"); +} + +int JCamera::getMaxExposureCompensation() +{ + if (!m_parameters || !m_parameters->isValid()) + return 0; + + return m_parameters->callMethod("getMaxExposureCompensation"); +} + +QStringList JCamera::getSupportedSceneModes() +{ + return callStringListMethod("getSupportedSceneModes"); +} + +QString JCamera::getSceneMode() +{ + QString value; + + if (m_parameters && m_parameters->isValid()) { + QJNILocalRef sceneMode = m_parameters->callObjectMethod("getSceneMode", + "()Ljava/lang/String;"); + if (!sceneMode.isNull()) + value = qt_convertJString(sceneMode.object()); + } + + return value; +} + +void JCamera::setSceneMode(const QString &value) +{ + if (!m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setSceneMode", + "(Ljava/lang/String;)V", + qt_toJString(value).object()); + applyParameters(); +} + +QStringList JCamera::getSupportedWhiteBalance() +{ + return callStringListMethod("getSupportedWhiteBalance"); +} + +QString JCamera::getWhiteBalance() +{ + QString value; + + if (m_parameters && m_parameters->isValid()) { + QJNILocalRef wb = m_parameters->callObjectMethod("getWhiteBalance", + "()Ljava/lang/String;"); + if (!wb.isNull()) + value = qt_convertJString(wb.object()); + } + + return value; +} + +void JCamera::setWhiteBalance(const QString &value) +{ + if (!m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setWhiteBalance", + "(Ljava/lang/String;)V", + qt_toJString(value).object()); + applyParameters(); + + emit whiteBalanceChanged(); +} + +void JCamera::setRotation(int rotation) +{ + if (!m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setRotation", "(I)V", rotation); + applyParameters(); +} + +QList JCamera::getSupportedPictureSizes() +{ + QList list; + + if (m_parameters && m_parameters->isValid()) { + QJNILocalRef sizeListRef = m_parameters->callObjectMethod("getSupportedPictureSizes", + "()Ljava/util/List;"); + QJNIObject sizeList(sizeListRef.object()); + int count = sizeList.callMethod("size"); + for (int i = 0; i < count; ++i) { + QJNILocalRef sizeRef = sizeList.callObjectMethod("get", + "(I)Ljava/lang/Object;", + i); + QJNIObject size(sizeRef.object()); + list.append(QSize(size.getField("width"), size.getField("height"))); + } + + qSort(list.begin(), list.end(), qt_sizeLessThan); + } + + return list; +} + +void JCamera::setPictureSize(const QSize &size) +{ + if (!m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setPictureSize", "(II)V", size.width(), size.height()); + applyParameters(); +} + +void JCamera::setJpegQuality(int quality) +{ + if (!m_parameters || !m_parameters->isValid()) + return; + + m_parameters->callMethod("setJpegQuality", "(I)V", quality); + applyParameters(); +} + +void JCamera::takePicture() +{ + callMethod("takePicture"); +} + +void JCamera::startPreview() +{ + callMethod("startPreview"); +} + +void JCamera::stopPreview() +{ + callMethod("stopPreview"); +} + +void JCamera::applyParameters() +{ + callMethod("setParameters", + "(Landroid/hardware/Camera$Parameters;)V", + m_parameters->object()); +} + +QStringList JCamera::callStringListMethod(const char *methodName) +{ + QStringList stringList; + + if (m_parameters && m_parameters->isValid()) { + QJNILocalRef listRef = m_parameters->callObjectMethod(methodName, + "()Ljava/util/List;"); + + if (!listRef.isNull()) { + QJNIObject list(listRef.object()); + int count = list.callMethod("size"); + for (int i = 0; i < count; ++i) { + QJNILocalRef stringRef = list.callObjectMethod("get", + "(I)Ljava/lang/Object;", + i); + + QJNIObject string(stringRef.object()); + stringList.append(qt_convertJString(string.callObjectMethod("toString").object())); + } + } + } + + return stringList; +} + +static JNINativeMethod methods[] = { + {"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete}, + {"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed}, + {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured} +}; + +bool JCamera::initJNI(JNIEnv *env) +{ + jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtCamera"); + if (env->ExceptionCheck()) + env->ExceptionClear(); + + if (clazz) { + g_qtCameraClass = static_cast(env->NewGlobalRef(clazz)); + if (env->RegisterNatives(g_qtCameraClass, + methods, + sizeof(methods) / sizeof(methods[0])) < 0) { + return false; + } + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jcamera.h b/src/plugins/android/src/wrappers/jcamera.h new file mode 100644 index 000000000..100628721 --- /dev/null +++ b/src/plugins/android/src/wrappers/jcamera.h @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** 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 JCAMERA_H +#define JCAMERA_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class JCamera : public QObject, public QJNIObject +{ + Q_OBJECT +public: + enum CameraFacing { + CameraFacingBack = 0, + CameraFacingFront = 1 + }; + + ~JCamera(); + + static JCamera *open(int cameraId); + + int cameraId() const { return m_cameraId; } + + void lock(); + void unlock(); + void reconnect(); + void release(); + + CameraFacing getFacing(); + int getNativeOrientation(); + + QSize getPreferredPreviewSizeForVideo(); + QList getSupportedPreviewSizes(); + + QSize previewSize() const { return m_previewSize; } + void setPreviewSize(const QSize &size); + void setPreviewTexture(jobject surfaceTexture); + + bool isZoomSupported(); + int getMaxZoom(); + QList getZoomRatios(); + int getZoom(); + void setZoom(int value); + + QStringList getSupportedFlashModes(); + QString getFlashMode(); + void setFlashMode(const QString &value); + + QStringList getSupportedFocusModes(); + QString getFocusMode(); + void setFocusMode(const QString &value); + + int getMaxNumFocusAreas(); + QList getFocusAreas(); + void setFocusAreas(const QList &areas); + + void autoFocus(); + void cancelAutoFocus(); + + bool isAutoExposureLockSupported(); + bool getAutoExposureLock(); + void setAutoExposureLock(bool toggle); + + bool isAutoWhiteBalanceLockSupported(); + bool getAutoWhiteBalanceLock(); + void setAutoWhiteBalanceLock(bool toggle); + + int getExposureCompensation(); + void setExposureCompensation(int value); + float getExposureCompensationStep(); + int getMinExposureCompensation(); + int getMaxExposureCompensation(); + + QStringList getSupportedSceneModes(); + QString getSceneMode(); + void setSceneMode(const QString &value); + + QStringList getSupportedWhiteBalance(); + QString getWhiteBalance(); + void setWhiteBalance(const QString &value); + + void setRotation(int rotation); + + QList getSupportedPictureSizes(); + void setPictureSize(const QSize &size); + void setJpegQuality(int quality); + + void startPreview(); + void stopPreview(); + + void takePicture(); + + static bool initJNI(JNIEnv *env); + +Q_SIGNALS: + void previewSizeChanged(); + + void autoFocusStarted(); + void autoFocusComplete(bool success); + + void whiteBalanceChanged(); + + void pictureExposed(); + void pictureCaptured(const QByteArray &data); + +private: + JCamera(int cameraId, jobject cam); + void applyParameters(); + + QStringList callStringListMethod(const char *methodName); + + int m_cameraId; + QJNIObject *m_info; + QJNIObject *m_parameters; + + QSize m_previewSize; + + bool m_hasAPI14; +}; + +QT_END_NAMESPACE + +#endif // JCAMERA_H diff --git a/src/plugins/android/src/wrappers/jmediametadataretriever.cpp b/src/plugins/android/src/wrappers/jmediametadataretriever.cpp new file mode 100644 index 000000000..ae5abcf43 --- /dev/null +++ b/src/plugins/android/src/wrappers/jmediametadataretriever.cpp @@ -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 +#include +#include + +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(nativeInterface->nativeResourceForIntegration("QtActivity")); + } +} + +JMediaMetadataRetriever::~JMediaMetadataRetriever() +{ +} + +QString JMediaMetadataRetriever::extractMetadata(MetadataKey key) +{ + QString value; + + QJNILocalRef metadata = callObjectMethod("extractMetadata", + "(I)Ljava/lang/String;", + jint(key)); + if (!metadata.isNull()) + value = qt_convertJString(metadata.object()); + + return value; +} + +void JMediaMetadataRetriever::release() +{ + callMethod("release"); +} + +bool JMediaMetadataRetriever::setDataSource(const QUrl &url) +{ + QAttachedJNIEnv env; + + bool loaded = false; + + QJNILocalRef string = qt_toJString(url.toString()); + + QJNILocalRef uri = callStaticObjectMethod("android/net/Uri", + "parse", + "(Ljava/lang/String;)Landroid/net/Uri;", + string.object()); + if (env->ExceptionCheck()) { + env->ExceptionClear(); + } else { + callMethod("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("setDataSource", "(Ljava/lang/String;)V", qt_toJString(path).object()); + if (env->ExceptionCheck()) + env->ExceptionClear(); + else + loaded = true; + + return loaded; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jmediametadataretriever.h b/src/plugins/android/src/wrappers/jmediametadataretriever.h new file mode 100644 index 000000000..dd63e0d87 --- /dev/null +++ b/src/plugins/android/src/wrappers/jmediametadataretriever.h @@ -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 +#include + +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 diff --git a/src/plugins/android/src/wrappers/jmediaplayer.cpp b/src/plugins/android/src/wrappers/jmediaplayer.cpp new file mode 100644 index 000000000..f6e03ee22 --- /dev/null +++ b/src/plugins/android/src/wrappers/jmediaplayer.cpp @@ -0,0 +1,270 @@ +/**************************************************************************** +** +** 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 +#include +#include +#include + +namespace { + +jclass mediaPlayerClass = 0; + +QMap mplayers; + +} + +QT_BEGIN_NAMESPACE + +bool JMediaPlayer::mActivitySet = false; + +JMediaPlayer::JMediaPlayer() + : QObject() + , QJNIObject(mediaPlayerClass, "(J)V", reinterpret_cast(this)) + , mId(reinterpret_cast(this)) + , mDisplay(0) +{ + mplayers.insert(mId, this); + + if (!mActivitySet) { + QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); + jobject activity = static_cast(nativeInterface->nativeResourceForIntegration("QtActivity")); + QJNIObject::callStaticMethod(mediaPlayerClass, + "setActivity", + "(Landroid/app/Activity;)V", + activity); + mActivitySet = true; + } +} + +JMediaPlayer::~JMediaPlayer() +{ + mplayers.remove(mId); +} + +void JMediaPlayer::release() +{ + callMethod("release"); +} + +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("getCurrentPosition"); +} + +int JMediaPlayer::getDuration() +{ + return callMethod("getDuration"); +} + +bool JMediaPlayer::isPlaying() +{ + return callMethod("isPlaying"); +} + +int JMediaPlayer::volume() +{ + return callMethod("getVolume"); +} + +bool JMediaPlayer::isMuted() +{ + return callMethod("isMuted"); +} + +void JMediaPlayer::play() +{ + callMethod("start"); +} + +void JMediaPlayer::pause() +{ + callMethod("pause"); +} + +void JMediaPlayer::stop() +{ + callMethod("stop"); +} + +void JMediaPlayer::seekTo(qint32 msec) +{ + callMethod("seekTo", "(I)V", jint(msec)); +} + +void JMediaPlayer::setMuted(bool mute) +{ + callMethod("mute", "(Z)V", jboolean(mute)); +} + +void JMediaPlayer::setDataSource(const QString &path) +{ + QJNILocalRef string = qt_toJString(path); + callMethod("setMediaPath", "(Ljava/lang/String;)V", string.object()); +} + +void JMediaPlayer::setVolume(int volume) +{ + callMethod("setVolume", "(I)V", jint(volume)); +} + +void JMediaPlayer::setDisplay(jobject surfaceHolder) +{ + mDisplay = surfaceHolder; + callMethod("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(env->NewGlobalRef(jClass)); + + JNINativeMethod methods[] = { + {"onErrorNative", "(IIJ)V", reinterpret_cast(onErrorNative)}, + {"onBufferingUpdateNative", "(IJ)V", reinterpret_cast(onBufferingUpdateNative)}, + {"onInfoNative", "(IIJ)V", reinterpret_cast(onInfoNative)}, + {"onMediaPlayerInfoNative", "(IIJ)V", reinterpret_cast(onMediaPlayerInfoNative)}, + {"onVideoSizeChangedNative", "(IIJ)V", reinterpret_cast(onVideoSizeChangedNative)} + }; + + if (env->RegisterNatives(mediaPlayerClass, + methods, + sizeof(methods) / sizeof(methods[0])) < 0) { + return false; + } + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jmediaplayer.h b/src/plugins/android/src/wrappers/jmediaplayer.h new file mode 100644 index 000000000..710246b9a --- /dev/null +++ b/src/plugins/android/src/wrappers/jmediaplayer.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** 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 +#include + +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 + }; + + void release(); + + 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 diff --git a/src/plugins/android/src/wrappers/jmediarecorder.cpp b/src/plugins/android/src/wrappers/jmediarecorder.cpp new file mode 100644 index 000000000..b7cbe5724 --- /dev/null +++ b/src/plugins/android/src/wrappers/jmediarecorder.cpp @@ -0,0 +1,242 @@ +/**************************************************************************** +** +** 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 "jmediarecorder.h" + +#include "jcamera.h" +#include +#include + +QT_BEGIN_NAMESPACE + +static jclass g_qtMediaRecorderClass = 0; +static QMap g_objectMap; + +static void notifyError(JNIEnv* , jobject, jlong id, jint what, jint extra) +{ + JMediaRecorder *obj = g_objectMap.value(id, 0); + if (obj) + emit obj->error(what, extra); +} + +static void notifyInfo(JNIEnv* , jobject, jlong id, jint what, jint extra) +{ + JMediaRecorder *obj = g_objectMap.value(id, 0); + if (obj) + emit obj->info(what, extra); +} + +JMediaRecorder::JMediaRecorder() + : QObject() + , QJNIObject(g_qtMediaRecorderClass, "(J)V", reinterpret_cast(this)) + , m_id(reinterpret_cast(this)) +{ + if (isValid()) + g_objectMap.insert(m_id, this); +} + +JMediaRecorder::~JMediaRecorder() +{ + g_objectMap.remove(m_id); +} + +void JMediaRecorder::release() +{ + callMethod("release"); +} + +bool JMediaRecorder::prepare() +{ + QAttachedJNIEnv env; + callMethod("prepare"); + if (env->ExceptionCheck()) { + env->ExceptionClear(); + return false; + } + return true; +} + +void JMediaRecorder::reset() +{ + callMethod("reset"); +} + +bool JMediaRecorder::start() +{ + QAttachedJNIEnv env; + callMethod("start"); + if (env->ExceptionCheck()) { + env->ExceptionClear(); + return false; + } + return true; +} + +void JMediaRecorder::stop() +{ + QAttachedJNIEnv env; + callMethod("stop"); + if (env->ExceptionCheck()) + env->ExceptionClear(); +} + +void JMediaRecorder::setAudioChannels(int numChannels) +{ + callMethod("setAudioChannels", "(I)V", numChannels); +} + +void JMediaRecorder::setAudioEncoder(AudioEncoder encoder) +{ + QAttachedJNIEnv env; + callMethod("setAudioEncoder", "(I)V", int(encoder)); + if (env->ExceptionCheck()) + env->ExceptionClear(); +} + +void JMediaRecorder::setAudioEncodingBitRate(int bitRate) +{ + callMethod("setAudioEncodingBitRate", "(I)V", bitRate); +} + +void JMediaRecorder::setAudioSamplingRate(int samplingRate) +{ + callMethod("setAudioSamplingRate", "(I)V", samplingRate); +} + +void JMediaRecorder::setAudioSource(AudioSource source) +{ + QAttachedJNIEnv env; + callMethod("setAudioSource", "(I)V", int(source)); + if (env->ExceptionCheck()) + env->ExceptionClear(); +} + +void JMediaRecorder::setCamera(JCamera *camera) +{ + QJNILocalRef cam = camera->getObjectField("m_camera", "Landroid/hardware/Camera;"); + callMethod("setCamera", "(Landroid/hardware/Camera;)V", cam.object()); +} + +void JMediaRecorder::setVideoEncoder(VideoEncoder encoder) +{ + QAttachedJNIEnv env; + callMethod("setVideoEncoder", "(I)V", int(encoder)); + if (env->ExceptionCheck()) + env->ExceptionClear(); +} + +void JMediaRecorder::setVideoEncodingBitRate(int bitRate) +{ + callMethod("setVideoEncodingBitRate", "(I)V", bitRate); +} + +void JMediaRecorder::setVideoFrameRate(int rate) +{ + QAttachedJNIEnv env; + callMethod("setVideoFrameRate", "(I)V", rate); + if (env->ExceptionCheck()) + env->ExceptionClear(); +} + +void JMediaRecorder::setVideoSize(const QSize &size) +{ + QAttachedJNIEnv env; + callMethod("setVideoSize", "(II)V", size.width(), size.height()); + if (env->ExceptionCheck()) + env->ExceptionClear(); +} + +void JMediaRecorder::setVideoSource(VideoSource source) +{ + QAttachedJNIEnv env; + callMethod("setVideoSource", "(I)V", int(source)); + if (env->ExceptionCheck()) + env->ExceptionClear(); +} + +void JMediaRecorder::setOrientationHint(int degrees) +{ + QAttachedJNIEnv env; + callMethod("setOrientationHint", "(I)V", degrees); + if (env->ExceptionCheck()) + env->ExceptionClear(); +} + +void JMediaRecorder::setOutputFormat(OutputFormat format) +{ + QAttachedJNIEnv env; + callMethod("setOutputFormat", "(I)V", int(format)); + if (env->ExceptionCheck()) + env->ExceptionClear(); +} + +void JMediaRecorder::setOutputFile(const QString &path) +{ + QAttachedJNIEnv env; + callMethod("setOutputFile", "(Ljava/lang/String;)V", qt_toJString(path).object()); + if (env->ExceptionCheck()) + env->ExceptionClear(); +} + +static JNINativeMethod methods[] = { + {"notifyError", "(JII)V", (void *)notifyError}, + {"notifyInfo", "(JII)V", (void *)notifyInfo} +}; + +bool JMediaRecorder::initJNI(JNIEnv *env) +{ + jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtMediaRecorder"); + if (env->ExceptionCheck()) + env->ExceptionClear(); + + if (clazz) { + g_qtMediaRecorderClass = static_cast(env->NewGlobalRef(clazz)); + if (env->RegisterNatives(g_qtMediaRecorderClass, + methods, + sizeof(methods) / sizeof(methods[0])) < 0) { + return false; + } + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jmediarecorder.h b/src/plugins/android/src/wrappers/jmediarecorder.h new file mode 100644 index 000000000..ef26b8a72 --- /dev/null +++ b/src/plugins/android/src/wrappers/jmediarecorder.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** 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 JMEDIARECORDER_H +#define JMEDIARECORDER_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class JCamera; + +class JMediaRecorder : public QObject, public QJNIObject +{ + Q_OBJECT +public: + enum AudioEncoder { + DefaultAudioEncoder = 0, + AMR_NB_Encoder = 1, + AMR_WB_Encoder = 2, + AAC = 3 + }; + + enum AudioSource { + DefaultAudioSource = 0, + Mic = 1, + VoiceUplink = 2, + VoiceDownlink = 3, + VoiceCall = 4, + Camcorder = 5, + VoiceRecognition = 6 + }; + + enum VideoEncoder { + DefaultVideoEncoder = 0, + H263 = 1, + H264 = 2, + MPEG_4_SP = 3 + }; + + enum VideoSource { + DefaultVideoSource = 0, + Camera = 1 + }; + + enum OutputFormat { + DefaultOutputFormat = 0, + THREE_GPP = 1, + MPEG_4 = 2, + AMR_NB_Format = 3, + AMR_WB_Format = 4 + }; + + JMediaRecorder(); + ~JMediaRecorder(); + + void release(); + bool prepare(); + void reset(); + + bool start(); + void stop(); + + void setAudioChannels(int numChannels); + void setAudioEncoder(AudioEncoder encoder); + void setAudioEncodingBitRate(int bitRate); + void setAudioSamplingRate(int samplingRate); + void setAudioSource(AudioSource source); + + void setCamera(JCamera *camera); + void setVideoEncoder(VideoEncoder encoder); + void setVideoEncodingBitRate(int bitRate); + void setVideoFrameRate(int rate); + void setVideoSize(const QSize &size); + void setVideoSource(VideoSource source); + + void setOrientationHint(int degrees); + + void setOutputFormat(OutputFormat format); + void setOutputFile(const QString &path); + + static bool initJNI(JNIEnv *env); + +Q_SIGNALS: + void error(int what, int extra); + void info(int what, int extra); + +private: + jlong m_id; +}; + +QT_END_NAMESPACE + +#endif // JMEDIARECORDER_H diff --git a/src/plugins/android/src/wrappers/jmultimediautils.cpp b/src/plugins/android/src/wrappers/jmultimediautils.cpp new file mode 100644 index 000000000..6832e6b6e --- /dev/null +++ b/src/plugins/android/src/wrappers/jmultimediautils.cpp @@ -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$ +** +****************************************************************************/ + +#include "jmultimediautils.h" + +#include + +QT_BEGIN_NAMESPACE + +static jclass g_qtMultimediaUtilsClass = 0; + +JMultimediaUtils::JMultimediaUtils() + : QObject() + , QJNIObject(g_qtMultimediaUtilsClass) +{ +} + +void JMultimediaUtils::enableOrientationListener(bool enable) +{ + callStaticMethod(g_qtMultimediaUtilsClass, "enableOrientationListener", "(Z)V", enable); +} + +int JMultimediaUtils::getDeviceOrientation() +{ + return callStaticMethod(g_qtMultimediaUtilsClass, "getDeviceOrientation"); +} + +QString JMultimediaUtils::getDefaultMediaDirectory(MediaType type) +{ + QJNILocalRef path = callStaticObjectMethod(g_qtMultimediaUtilsClass, + "getDefaultMediaDirectory", + "(I)Ljava/lang/String;", + jint(type)); + return qt_convertJString(path.object()); +} + +void JMultimediaUtils::registerMediaFile(const QString &file) +{ + callStaticMethod(g_qtMultimediaUtilsClass, + "registerMediaFile", + "(Ljava/lang/String;)V", + qt_toJString(file).object()); +} + +bool JMultimediaUtils::initJNI(JNIEnv *env) +{ + jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtMultimediaUtils"); + if (env->ExceptionCheck()) + env->ExceptionClear(); + + if (clazz) + g_qtMultimediaUtilsClass = static_cast(env->NewGlobalRef(clazz)); + + return true; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jmultimediautils.h b/src/plugins/android/src/wrappers/jmultimediautils.h new file mode 100644 index 000000000..909f5c155 --- /dev/null +++ b/src/plugins/android/src/wrappers/jmultimediautils.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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 JMULTIMEDIAUTILS_H +#define JMULTIMEDIAUTILS_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class JMultimediaUtils : public QObject, public QJNIObject +{ + Q_OBJECT +public: + enum MediaType { + Music = 0, + Movies = 1, + DCIM = 2, + Sounds = 3 + }; + + JMultimediaUtils(); + + static void enableOrientationListener(bool enable); + static int getDeviceOrientation(); + static QString getDefaultMediaDirectory(MediaType type); + static void registerMediaFile(const QString &file); + + static bool initJNI(JNIEnv *env); +}; + +QT_END_NAMESPACE + +#endif // JMULTIMEDIAUTILS_H diff --git a/src/plugins/android/src/wrappers/jsurfacetexture.cpp b/src/plugins/android/src/wrappers/jsurfacetexture.cpp new file mode 100644 index 000000000..60c85cdf0 --- /dev/null +++ b/src/plugins/android/src/wrappers/jsurfacetexture.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** 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 + +QT_BEGIN_NAMESPACE + +static jclass g_qtSurfaceTextureClass = 0; +static QMap 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 (isValid()) + g_objectMap.insert(int(texName), this); +} + +JSurfaceTexture::~JSurfaceTexture() +{ + if (isValid()) + g_objectMap.remove(m_texID); +} + +QMatrix4x4 JSurfaceTexture::getTransformMatrix() +{ + QAttachedJNIEnv env; + + QMatrix4x4 matrix; + jfloatArray array = env->NewFloatArray(16); + callMethod("getTransformMatrix", "([F)V", array); + env->GetFloatArrayRegion(array, 0, 16, matrix.data()); + env->DeleteLocalRef(array); + + return matrix; +} + +void JSurfaceTexture::updateTexImage() +{ + callMethod("updateTexImage"); +} + +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(env->NewGlobalRef(clazz)); + if (env->RegisterNatives(g_qtSurfaceTextureClass, + methods, + sizeof(methods) / sizeof(methods[0])) < 0) { + return false; + } + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jsurfacetexture.h b/src/plugins/android/src/wrappers/jsurfacetexture.h new file mode 100644 index 000000000..2a2f27ae3 --- /dev/null +++ b/src/plugins/android/src/wrappers/jsurfacetexture.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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 +#include + +#include + +QT_BEGIN_NAMESPACE + +class JSurfaceTexture : public QObject, public QJNIObject +{ + Q_OBJECT +public: + explicit JSurfaceTexture(unsigned int texName); + ~JSurfaceTexture(); + + QMatrix4x4 getTransformMatrix(); + void updateTexImage(); + + static bool initJNI(JNIEnv *env); + +Q_SIGNALS: + void frameAvailable(); + +private: + int m_texID; +}; + +QT_END_NAMESPACE + +#endif // JSURFACETEXTURE_H diff --git a/src/plugins/android/src/wrappers/jsurfacetextureholder.cpp b/src/plugins/android/src/wrappers/jsurfacetextureholder.cpp new file mode 100644 index 000000000..4ec8935c2 --- /dev/null +++ b/src/plugins/android/src/wrappers/jsurfacetextureholder.cpp @@ -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(env->NewGlobalRef(clazz)); + + return true; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jsurfacetextureholder.h b/src/plugins/android/src/wrappers/jsurfacetextureholder.h new file mode 100644 index 000000000..5b567de3a --- /dev/null +++ b/src/plugins/android/src/wrappers/jsurfacetextureholder.h @@ -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 + +QT_BEGIN_NAMESPACE + +class JSurfaceTextureHolder : public QJNIObject +{ +public: + JSurfaceTextureHolder(jobject surface); + + static bool initJNI(JNIEnv *env); +}; + +QT_END_NAMESPACE + +#endif // JSURFACETEXTUREHOLDER_H diff --git a/src/plugins/android/src/wrappers/wrappers.pri b/src/plugins/android/src/wrappers/wrappers.pri new file mode 100644 index 000000000..b2faa5b79 --- /dev/null +++ b/src/plugins/android/src/wrappers/wrappers.pri @@ -0,0 +1,21 @@ +QT += platformsupport-private + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/jmediaplayer.h \ + $$PWD/jsurfacetexture.h \ + $$PWD/jsurfacetextureholder.h \ + $$PWD/jmediametadataretriever.h \ + $$PWD/jcamera.h \ + $$PWD/jmultimediautils.h \ + $$PWD/jmediarecorder.h + +SOURCES += \ + $$PWD/jmediaplayer.cpp \ + $$PWD/jsurfacetexture.cpp \ + $$PWD/jsurfacetextureholder.cpp \ + $$PWD/jmediametadataretriever.cpp \ + $$PWD/jcamera.cpp \ + $$PWD/jmultimediautils.cpp \ + $$PWD/jmediarecorder.cpp diff --git a/src/plugins/android/wrappers/jmediametadataretriever.cpp b/src/plugins/android/wrappers/jmediametadataretriever.cpp deleted file mode 100644 index ae5abcf43..000000000 --- a/src/plugins/android/wrappers/jmediametadataretriever.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** 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 -#include -#include - -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(nativeInterface->nativeResourceForIntegration("QtActivity")); - } -} - -JMediaMetadataRetriever::~JMediaMetadataRetriever() -{ -} - -QString JMediaMetadataRetriever::extractMetadata(MetadataKey key) -{ - QString value; - - QJNILocalRef metadata = callObjectMethod("extractMetadata", - "(I)Ljava/lang/String;", - jint(key)); - if (!metadata.isNull()) - value = qt_convertJString(metadata.object()); - - return value; -} - -void JMediaMetadataRetriever::release() -{ - callMethod("release"); -} - -bool JMediaMetadataRetriever::setDataSource(const QUrl &url) -{ - QAttachedJNIEnv env; - - bool loaded = false; - - QJNILocalRef string = qt_toJString(url.toString()); - - QJNILocalRef uri = callStaticObjectMethod("android/net/Uri", - "parse", - "(Ljava/lang/String;)Landroid/net/Uri;", - string.object()); - if (env->ExceptionCheck()) { - env->ExceptionClear(); - } else { - callMethod("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("setDataSource", "(Ljava/lang/String;)V", qt_toJString(path).object()); - if (env->ExceptionCheck()) - env->ExceptionClear(); - else - loaded = true; - - return loaded; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/wrappers/jmediametadataretriever.h b/src/plugins/android/wrappers/jmediametadataretriever.h deleted file mode 100644 index dd63e0d87..000000000 --- a/src/plugins/android/wrappers/jmediametadataretriever.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** 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 -#include - -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 diff --git a/src/plugins/android/wrappers/jmediaplayer.cpp b/src/plugins/android/wrappers/jmediaplayer.cpp deleted file mode 100644 index f6e03ee22..000000000 --- a/src/plugins/android/wrappers/jmediaplayer.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/**************************************************************************** -** -** 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 -#include -#include -#include - -namespace { - -jclass mediaPlayerClass = 0; - -QMap mplayers; - -} - -QT_BEGIN_NAMESPACE - -bool JMediaPlayer::mActivitySet = false; - -JMediaPlayer::JMediaPlayer() - : QObject() - , QJNIObject(mediaPlayerClass, "(J)V", reinterpret_cast(this)) - , mId(reinterpret_cast(this)) - , mDisplay(0) -{ - mplayers.insert(mId, this); - - if (!mActivitySet) { - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - jobject activity = static_cast(nativeInterface->nativeResourceForIntegration("QtActivity")); - QJNIObject::callStaticMethod(mediaPlayerClass, - "setActivity", - "(Landroid/app/Activity;)V", - activity); - mActivitySet = true; - } -} - -JMediaPlayer::~JMediaPlayer() -{ - mplayers.remove(mId); -} - -void JMediaPlayer::release() -{ - callMethod("release"); -} - -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("getCurrentPosition"); -} - -int JMediaPlayer::getDuration() -{ - return callMethod("getDuration"); -} - -bool JMediaPlayer::isPlaying() -{ - return callMethod("isPlaying"); -} - -int JMediaPlayer::volume() -{ - return callMethod("getVolume"); -} - -bool JMediaPlayer::isMuted() -{ - return callMethod("isMuted"); -} - -void JMediaPlayer::play() -{ - callMethod("start"); -} - -void JMediaPlayer::pause() -{ - callMethod("pause"); -} - -void JMediaPlayer::stop() -{ - callMethod("stop"); -} - -void JMediaPlayer::seekTo(qint32 msec) -{ - callMethod("seekTo", "(I)V", jint(msec)); -} - -void JMediaPlayer::setMuted(bool mute) -{ - callMethod("mute", "(Z)V", jboolean(mute)); -} - -void JMediaPlayer::setDataSource(const QString &path) -{ - QJNILocalRef string = qt_toJString(path); - callMethod("setMediaPath", "(Ljava/lang/String;)V", string.object()); -} - -void JMediaPlayer::setVolume(int volume) -{ - callMethod("setVolume", "(I)V", jint(volume)); -} - -void JMediaPlayer::setDisplay(jobject surfaceHolder) -{ - mDisplay = surfaceHolder; - callMethod("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(env->NewGlobalRef(jClass)); - - JNINativeMethod methods[] = { - {"onErrorNative", "(IIJ)V", reinterpret_cast(onErrorNative)}, - {"onBufferingUpdateNative", "(IJ)V", reinterpret_cast(onBufferingUpdateNative)}, - {"onInfoNative", "(IIJ)V", reinterpret_cast(onInfoNative)}, - {"onMediaPlayerInfoNative", "(IIJ)V", reinterpret_cast(onMediaPlayerInfoNative)}, - {"onVideoSizeChangedNative", "(IIJ)V", reinterpret_cast(onVideoSizeChangedNative)} - }; - - if (env->RegisterNatives(mediaPlayerClass, - methods, - sizeof(methods) / sizeof(methods[0])) < 0) { - return false; - } - } - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/wrappers/jmediaplayer.h b/src/plugins/android/wrappers/jmediaplayer.h deleted file mode 100644 index 710246b9a..000000000 --- a/src/plugins/android/wrappers/jmediaplayer.h +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** 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 -#include - -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 - }; - - void release(); - - 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 diff --git a/src/plugins/android/wrappers/jsurfacetexture.cpp b/src/plugins/android/wrappers/jsurfacetexture.cpp deleted file mode 100644 index 34edf1b66..000000000 --- a/src/plugins/android/wrappers/jsurfacetexture.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** 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 - -QT_BEGIN_NAMESPACE - -static jclass g_qtSurfaceTextureClass = 0; -static QHash 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 (isValid()) - g_objectMap.insert(int(texName), this); -} - -JSurfaceTexture::~JSurfaceTexture() -{ - if (isValid()) - g_objectMap.remove(m_texID); -} - -QMatrix4x4 JSurfaceTexture::getTransformMatrix() -{ - QAttachedJNIEnv env; - - QMatrix4x4 matrix; - jfloatArray array = env->NewFloatArray(16); - callMethod("getTransformMatrix", "([F)V", array); - env->GetFloatArrayRegion(array, 0, 16, matrix.data()); - env->DeleteLocalRef(array); - - return matrix; -} - -void JSurfaceTexture::updateTexImage() -{ - callMethod("updateTexImage"); -} - -QJNILocalRef JSurfaceTexture::surfaceTexture() -{ - return getObjectField("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(env->NewGlobalRef(clazz)); - if (env->RegisterNatives(g_qtSurfaceTextureClass, - methods, - sizeof(methods) / sizeof(methods[0])) < 0) { - return false; - } - } - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/wrappers/jsurfacetexture.h b/src/plugins/android/wrappers/jsurfacetexture.h deleted file mode 100644 index 49e007666..000000000 --- a/src/plugins/android/wrappers/jsurfacetexture.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** 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 -#include - -#include - -QT_BEGIN_NAMESPACE - -class JSurfaceTexture : public QObject, public QJNIObject -{ - Q_OBJECT -public: - explicit JSurfaceTexture(unsigned int texName); - ~JSurfaceTexture(); - - QMatrix4x4 getTransformMatrix(); - void updateTexImage(); - - QJNILocalRef surfaceTexture(); - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void frameAvailable(); - -private: - int m_texID; -}; - -QT_END_NAMESPACE - -#endif // JSURFACETEXTURE_H diff --git a/src/plugins/android/wrappers/jsurfacetextureholder.cpp b/src/plugins/android/wrappers/jsurfacetextureholder.cpp deleted file mode 100644 index 4ec8935c2..000000000 --- a/src/plugins/android/wrappers/jsurfacetextureholder.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** 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(env->NewGlobalRef(clazz)); - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/wrappers/jsurfacetextureholder.h b/src/plugins/android/wrappers/jsurfacetextureholder.h deleted file mode 100644 index 5b567de3a..000000000 --- a/src/plugins/android/wrappers/jsurfacetextureholder.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** 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 - -QT_BEGIN_NAMESPACE - -class JSurfaceTextureHolder : public QJNIObject -{ -public: - JSurfaceTextureHolder(jobject surface); - - static bool initJNI(JNIEnv *env); -}; - -QT_END_NAMESPACE - -#endif // JSURFACETEXTUREHOLDER_H diff --git a/src/plugins/android/wrappers/wrappers.pri b/src/plugins/android/wrappers/wrappers.pri deleted file mode 100644 index 5b47ef531..000000000 --- a/src/plugins/android/wrappers/wrappers.pri +++ /dev/null @@ -1,15 +0,0 @@ -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 diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index b0356636a..742a4f7f0 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -29,7 +29,7 @@ win32 { config_wmf: SUBDIRS += wmf } -unix:!mac { +unix:!mac:!android { config_gstreamer { SUBDIRS += gstreamer } else { -- cgit v1.2.3