From b33e6d46726ee275eaa00be8800339f1fce4585e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Mon, 7 Apr 2014 14:04:49 +0200 Subject: Android: Release the surface texture when not in use With some Android versions the preview texture is released when the application is suspended. If we don't release the texture in our code, the preview will be empty when the application resumes. Task-number: QTBUG-38165 Change-Id: I72244727081d8f94ee5f6cb0ab660ca59f4bb2de Reviewed-by: Yoann Lopes --- src/plugins/android/src/mediacapture/qandroidcamerasession.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index b1b3f848e..6051cf964 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -286,8 +286,10 @@ void QAndroidCameraSession::close() void QAndroidCameraSession::setVideoPreview(QObject *videoOutput) { - if (m_videoOutput) + if (m_videoOutput) { m_videoOutput->stop(); + m_videoOutput->reset(); + } if (videoOutput) { connect(videoOutput, SIGNAL(readyChanged(bool)), this, SLOT(onVideoOutputReady(bool))); @@ -368,8 +370,12 @@ void QAndroidCameraSession::stopPreview() m_camera->stopPreview(); m_camera->setPreviewSize(QSize()); - if (m_videoOutput) + m_camera->setPreviewTexture(0); + + if (m_videoOutput) { m_videoOutput->stop(); + m_videoOutput->reset(); + } m_previewStarted = false; } -- cgit v1.2.3 From af73d55efffa1dca928038cd4f392eb7def7c7e1 Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Wed, 9 Apr 2014 17:02:25 +0200 Subject: Doc: Improved example documentation -added instructions on how to run the example (using \include to insert a section from qtbase/doc/global/) -updated copyright year -removed links to Qt 4 API -rearranged some of the sections -created links from the example pages to Qt Multimedia -fixed QDoc warnings related to the example pages Task-number: QTBUG-33597 Change-Id: Id45ce5cbd40dbfa384abd7260a316f6f6837c186 Reviewed-by: Yoann Lopes Reviewed-by: Sze Howe Koh --- .../audiodevices/doc/src/audiodevices.qdoc | 9 +++--- .../audioengine/doc/src/audioengine.qdoc | 10 +++--- .../multimedia/audioinput/doc/src/audioinput.qdoc | 9 +++--- .../audiooutput/doc/src/audiooutput.qdoc | 9 +++--- .../audiorecorder/doc/src/audiorecorder.qdoc | 12 ++++--- .../doc/src/declarative-camera.qdoc | 37 +++++++--------------- .../doc/src/declarative-radio.qdoc | 10 +++--- examples/multimedia/spectrum/doc/src/spectrum.qdoc | 6 ++-- examples/multimedia/video/doc/src/qmlvideo.qdoc | 11 +++---- examples/multimedia/video/doc/src/qmlvideofx.qdoc | 11 ++++--- .../multimediawidgets/camera/doc/src/camera.qdoc | 8 ++--- .../multimediawidgets/player/doc/src/player.qdoc | 5 +-- .../doc/src/videographicsitem.qdoc | 6 ++-- .../videowidget/doc/src/videowidget.qdoc | 6 ++-- 14 files changed, 73 insertions(+), 76 deletions(-) diff --git a/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc b/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc index d75584485..bdf1590fe 100644 --- a/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc +++ b/examples/multimedia/audiodevices/doc/src/audiodevices.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -29,8 +29,8 @@ \example audiodevices \title Audio Devices Example \ingroup multimedia_examples - \brief The Audio Devices example shows the application of the audio devices APIs - + \brief The Audio Devices example shows the application of the audio devices + APIs. This example shows how to create a simple application to list and test the configuration for the various audio devices available on the device @@ -38,6 +38,5 @@ \image audiodevices.png + \include examples-run.qdocinc */ - - diff --git a/examples/multimedia/audioengine/doc/src/audioengine.qdoc b/examples/multimedia/audioengine/doc/src/audioengine.qdoc index c83247df1..52a377130 100644 --- a/examples/multimedia/audioengine/doc/src/audioengine.qdoc +++ b/examples/multimedia/audioengine/doc/src/audioengine.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -30,10 +30,10 @@ \title AudioEngine Example \ingroup multimedia_examples \brief The Audio Engine example demonstrates 3D sound control using - the QtAudioEngine API. + the Qt Audio Engine API. - \image audioengine.png + The Audio Engine example demonstrates 3D sound control using the + \l{Qt Audio Engine QML Types}{Qt Audio Engine} API. + \include examples-run.qdocinc */ - - diff --git a/examples/multimedia/audioinput/doc/src/audioinput.qdoc b/examples/multimedia/audioinput/doc/src/audioinput.qdoc index 39ef26156..11a513a99 100644 --- a/examples/multimedia/audioinput/doc/src/audioinput.qdoc +++ b/examples/multimedia/audioinput/doc/src/audioinput.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -37,7 +37,8 @@ Qt provides the QAudioInput class to enable audio functionality within a standard application user interface. - This example calculates the maximum linear value of the input audio from the microphone and displays the output. -*/ - + This example calculates the maximum linear value of the input audio from the + microphone and displays the output. + \include examples-run.qdocinc +*/ diff --git a/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc b/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc index bc79e6a5d..60c9d00d4 100644 --- a/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc +++ b/examples/multimedia/audiooutput/doc/src/audiooutput.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -31,13 +31,14 @@ \ingroup multimedia_examples \brief The Audio Output Example show the use of the QAudioOutput API. - The example demonstrates the basic use cases of the QAudioOutput class. + The example demonstrates the basic use cases of the QAudioOutput class from + \l{Qt Multimedia}. \image audiooutput-example.png This example provides a tone generator to supply continuous audio playback. The first button allows pause and resume of the playback, and the second button allows toggling between push and pull modes of operation. -*/ - + \include examples-run.qdocinc +*/ diff --git a/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc b/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc index 8453ea34e..35f6c0511 100644 --- a/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc +++ b/examples/multimedia/audiorecorder/doc/src/audiorecorder.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -34,6 +34,12 @@ It demonstrates the discovery of the supported devices and codecs and the use of recording functions in the QAudioRecorder class. + \image audiorecorder.png + + \include examples-run.qdocinc + + \section1 Displaying the Window and Audio Settings + We display a window for the user to select the appropriate audio input, codec, container, and sample rate. Allow a setting of either quality or bitrate. Finally, the output file can be selected and recording can be @@ -49,7 +55,7 @@ \l{QMultimedia::NormalQuality}, while the bitrates are hardcoded into the list. - \image audiorecorder.png + \section1 Recording Audio To record audio we simply create a QAudioRecorder object. @@ -96,5 +102,3 @@ ui->statusbar->showMessage(tr("Recorded %1 sec").arg(duration / 1000)); \endcode */ - - diff --git a/examples/multimedia/declarative-camera/doc/src/declarative-camera.qdoc b/examples/multimedia/declarative-camera/doc/src/declarative-camera.qdoc index 02e77854c..8c87b1d46 100644 --- a/examples/multimedia/declarative-camera/doc/src/declarative-camera.qdoc +++ b/examples/multimedia/declarative-camera/doc/src/declarative-camera.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -34,35 +34,22 @@ or video. \image qml-camera.png -This example demonstrates how to use the Qt Multimedia QML API to access -camera functions. It shows how to change settings and to capture images. +This example demonstrates how to use the +\l{Qt Multimedia QML Types}{Qt Multimedia QML API} to access camera functions. +It shows how to change settings and to capture images. + +\include examples-run.qdocinc + +\section1 Application Structure Most of the QML code supports the user interface for this application with the camera types being mostly found in \e {declarative-camera.qml} and \e {CaptureControls.qml}. -In \e {declarative-camera.qml} the \l Camera is initialized with an id -of \e {camera}, a photo preview is setup, states are implemented for image -preview or capture and \l CaptureControls is initialized. The initial -\e state is \e PhotoCapture. \l CameraCapture includes a handler, \e onImageCaptured, -for the \l {imageCaptured} signal. The handler sets up the application to process -the preview including a change in the user interface state. The \l PhotoPreview -becomes visible with any key press being picked up by the handler -in PhotoPreview and returning the state to \e PhotoCapture. - -\e CaptureControls, which is implemented in \e {CaptureControls.qml}, +CaptureControls, which is implemented in \e {CaptureControls.qml}, generates a column on the right hand side of the screen which includes control -buttons for \e focus (not initially visible), \e {capture}, \e {flash modes}, -\e {white balance}, \e {exposure compensation}, and if a preview is -available a \e {preview} button. The last button exits from the application. - -When the Capture button is pressed the \e onClicked handler calls -\l {Camera::captureImage()}{captureImage()} - - - - - - +buttons for focus (not initially visible), capture, flash modes, +white balance, exposure compensation, and if a preview is +available, a preview button. The last button exits from the application. */ diff --git a/examples/multimedia/declarative-radio/doc/src/declarative-radio.qdoc b/examples/multimedia/declarative-radio/doc/src/declarative-radio.qdoc index 99c41114a..bb1a5d89f 100644 --- a/examples/multimedia/declarative-radio/doc/src/declarative-radio.qdoc +++ b/examples/multimedia/declarative-radio/doc/src/declarative-radio.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -31,8 +31,8 @@ \brief Demonstrates the radio functionality \ingroup multimedia_examples - This examples uses the Qt Multimedia Radio QML type to list the available - channels on the FM frequency. -*/ - + This examples uses the \l{Qt Multimedia} \l Radio QML type to list the + available channels on the FM frequency. + \include examples-run.qdocinc +*/ diff --git a/examples/multimedia/spectrum/doc/src/spectrum.qdoc b/examples/multimedia/spectrum/doc/src/spectrum.qdoc index 280838956..3c846afdc 100644 --- a/examples/multimedia/spectrum/doc/src/spectrum.qdoc +++ b/examples/multimedia/spectrum/doc/src/spectrum.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -59,6 +59,6 @@ (FFT) of a segment of audio data. An open-source library, \l{http://ldesoras.free.fr/prod.html}{FFTReal}, against which the application is dynamically linked, is used to compute the transform. -*/ - + \include examples-run.qdocinc +*/ diff --git a/examples/multimedia/video/doc/src/qmlvideo.qdoc b/examples/multimedia/video/doc/src/qmlvideo.qdoc index 6d6833497..1e80cd176 100644 --- a/examples/multimedia/video/doc/src/qmlvideo.qdoc +++ b/examples/multimedia/video/doc/src/qmlvideo.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -34,8 +34,6 @@ resize; rotate; change aspect ratio) which can be applied to QML \l{VideoOutput} items. -\section1 Overview - This example demonstrates the various manipulations (move; resize; rotate; change aspect ratio) which can be applied to QML \l{VideoOutput} items. @@ -50,7 +48,9 @@ which moves across the \l{VideoOutput} item. \image qmlvideo-overlay.png -\section1 Application structure +\include examples-run.qdocinc + +\section1 Application Structure The \l{video/qmlvideo/qml/qmlvideo/main.qml} file creates a UI which includes the following items: @@ -127,7 +127,7 @@ instance, the embedded \l{video/qmlvideo/qml/qmlvideo/Content.qml}{Content} item creates either a \l{MediaPlayer} or a \l{Camera} item. -\section1 Calculating and displaying QML painting rate +\section1 Calculating and Displaying QML Painting Rate \input multimedia/doc/src/examples/video-qml-paint-rate.qdocinc @@ -145,4 +145,3 @@ object to a JavaScript function, which will eventually call frequencyItem.notify \printuntil SLOT(qmlFramePainted())); */ - diff --git a/examples/multimedia/video/doc/src/qmlvideofx.qdoc b/examples/multimedia/video/doc/src/qmlvideofx.qdoc index b7bd78ac7..80f087e7f 100644 --- a/examples/multimedia/video/doc/src/qmlvideofx.qdoc +++ b/examples/multimedia/video/doc/src/qmlvideofx.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -34,9 +34,11 @@ can be used to apply postprocessing effects, expressed in \c GLSL, to video and camera viewfinder content. +\include examples-run.qdocinc + \section1 Overview -This example shows how a \l {ShaderEffectItem} can be used to apply +This example shows how a \l {ShaderEffect} can be used to apply postprocessing effects, expressed in GLSL, to QML \l {VideoOutput} items. It also shows how native code can be combined with QML to implement more @@ -73,7 +75,7 @@ for Effect*.qml files in the list above to see the full range. \section1 Application structure Shader effects can be applied to video or viewfinder content using -\l{ShaderEffectItem}, as shown in the following example, which applies +\l{ShaderEffect}, as shown in the following example, which applies a wiggly effect to the content: \code @@ -171,7 +173,7 @@ is based on the \l{ShaderEffect}: \skipto import \printuntil /^\}/ -The interface of the \l Effect allows for derived effects to specify the +The interface of Effect allows for derived effects to specify the number of parameters which they support (and therefore the number of sliders which should be displayed), and whether a vertical dividing line should be drawn between transformed and untransformed image regions. As an example, here is the @@ -219,4 +221,3 @@ object to a JavaScript function, which will eventually call frequencyItem.notify \printuntil SLOT(qmlFramePainted())); */ - diff --git a/examples/multimediawidgets/camera/doc/src/camera.qdoc b/examples/multimediawidgets/camera/doc/src/camera.qdoc index d1a855d4e..5f6683484 100644 --- a/examples/multimediawidgets/camera/doc/src/camera.qdoc +++ b/examples/multimediawidgets/camera/doc/src/camera.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -35,10 +35,12 @@ \brief The Camera Example shows how to use the API to capture a still image or video. -The Camera Example demonstrates how you can use Qt Multimedia to implement +The Camera Example demonstrates how you can use \l{Qt Multimedia} to implement some basic Camera functionality to take still images and record video clips with audio. +\include examples-run.qdocinc + A Camera class is created that will act as our Camera. It has a user interface, control functions, setting values and a means of defining the location where the image or video clip is to be saved. It will also store the image and video @@ -74,5 +76,3 @@ is started with a call to \l {QMediaRecorder::record()}. \image camera-example.png */ - - diff --git a/examples/multimediawidgets/player/doc/src/player.qdoc b/examples/multimediawidgets/player/doc/src/player.qdoc index 2dfb7c3d0..29121dce4 100644 --- a/examples/multimediawidgets/player/doc/src/player.qdoc +++ b/examples/multimediawidgets/player/doc/src/player.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -34,6 +34,8 @@ This example creates a simple multimedia player. We can play audio and or video files using various codecs. + \include examples-run.qdocinc + The example uses a QMediaPlayer object passed into a QVideoWidget to control the video output. To give the application playlist capability we also use a QPlayList object. @@ -93,4 +95,3 @@ \endcode */ - diff --git a/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc b/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc index 3ccdba5f5..1e392ce8c 100644 --- a/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc +++ b/examples/multimediawidgets/videographicsitem/doc/src/videographicsitem.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -32,9 +32,11 @@ \brief This example demonstrates how to stream video on a graphics scene. The Video Graphics Item example shows how to implement a QGraphicsItem that displays video on a - graphics scene using Qt Multimedia's QAbstractVideoSurface. + graphics scene using \l{Qt Multimedia}'s QAbstractVideoSurface. \image video-videographicsitem.png \sa {Video Widget Example} + + \include examples-run.qdocinc */ diff --git a/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc b/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc index 805a830bc..6b93a3c19 100644 --- a/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc +++ b/examples/multimediawidgets/videowidget/doc/src/videowidget.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -32,7 +32,9 @@ \brief This example is a simple video player The Video Widget example denonstrates how to implement a video widget using - Qt Multimedia's QAbstractVideoSurface. + \l{Qt Multimedia}'s QAbstractVideoSurface. \image video-videowidget.png + + \include examples-run.qdocinc */ -- cgit v1.2.3 From 60a911096f04b5159b99ad444bc9ad9aedf42eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Thu, 3 Apr 2014 17:26:05 +0200 Subject: Android: Use QMutexLock in camera callbacks. We should not release the locks before the native callbacks returns. Change-Id: Ia2691f6c5be66a3dcf371e48e3bac7498b401833 Reviewed-by: Yoann Lopes --- src/plugins/android/src/wrappers/jcamera.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/plugins/android/src/wrappers/jcamera.cpp b/src/plugins/android/src/wrappers/jcamera.cpp index b0e9f89f3..f43e2308c 100644 --- a/src/plugins/android/src/wrappers/jcamera.cpp +++ b/src/plugins/android/src/wrappers/jcamera.cpp @@ -82,27 +82,24 @@ static QJNIObjectPrivate rectToArea(const QRect &rect) // native method for QtCamera.java static void notifyAutoFocusComplete(JNIEnv* , jobject, int id, jboolean success) { - g_objectMapMutex.lock(); + QMutexLocker locker(&g_objectMapMutex); JCamera *obj = g_objectMap.value(id, 0); - g_objectMapMutex.unlock(); if (obj) Q_EMIT obj->autoFocusComplete(success); } static void notifyPictureExposed(JNIEnv* , jobject, int id) { - g_objectMapMutex.lock(); + QMutexLocker locker(&g_objectMapMutex); JCamera *obj = g_objectMap.value(id, 0); - g_objectMapMutex.unlock(); if (obj) Q_EMIT obj->pictureExposed(); } static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data) { - g_objectMapMutex.lock(); + QMutexLocker locker(&g_objectMapMutex); JCamera *obj = g_objectMap.value(id, 0); - g_objectMapMutex.unlock(); if (obj) { QByteArray bytes; int arrayLength = env->GetArrayLength(data); @@ -114,9 +111,8 @@ static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data) static void notifyFrameFetched(JNIEnv *env, jobject, int id, jbyteArray data) { - g_objectMapMutex.lock(); + QMutexLocker locker(&g_objectMapMutex); JCamera *obj = g_objectMap.value(id, 0); - g_objectMapMutex.unlock(); if (obj) { QByteArray bytes; int arrayLength = env->GetArrayLength(data); -- cgit v1.2.3 From b088962950dbc4c6f0219de30b0d9a8cf47a3376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Thu, 3 Apr 2014 18:09:48 +0200 Subject: Android: Camera code clean-up Change-Id: Ib400afde12067764c3dcc0f44e40ddc1abb3012f Reviewed-by: Yoann Lopes --- src/plugins/android/jar/jar.pri | 2 +- .../qtproject/qt5/android/multimedia/QtCamera.java | 266 ------------ .../qt5/android/multimedia/QtCameraListener.java | 148 +++++++ src/plugins/android/src/wrappers/jcamera.cpp | 470 ++++++++++++--------- src/plugins/android/src/wrappers/jcamera.h | 8 +- 5 files changed, 432 insertions(+), 462 deletions(-) delete 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/QtCameraListener.java diff --git a/src/plugins/android/jar/jar.pri b/src/plugins/android/jar/jar.pri index d8bc59a72..d31839c61 100644 --- a/src/plugins/android/jar/jar.pri +++ b/src/plugins/android/jar/jar.pri @@ -6,7 +6,7 @@ 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/QtCameraListener.java \ $$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener.java \ $$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java \ $$PWD/src/org/qtproject/qt5/android/multimedia/QtMultimediaUtils.java \ 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 deleted file mode 100644 index f03053f17..000000000 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCamera.java +++ /dev/null @@ -1,266 +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 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.ImageFormat; -import android.graphics.SurfaceTexture; -import android.util.Log; -import java.lang.Math; -import java.util.concurrent.locks.ReentrantLock; - -public class QtCamera implements Camera.ShutterCallback, - Camera.PictureCallback, - Camera.AutoFocusCallback, - Camera.PreviewCallback -{ - private int m_cameraId = -1; - private Camera m_camera = null; - private byte[] m_cameraPreviewFirstBuffer = null; - private byte[] m_cameraPreviewSecondBuffer = null; - private int m_actualPreviewBuffer = 0; - private final ReentrantLock m_buffersLock = new ReentrantLock(); - private boolean m_isReleased = false; - private boolean m_fetchEachFrame = false; - - 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_isReleased = true; - 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 fetchEachFrame(boolean fetch) - { - m_fetchEachFrame = fetch; - } - - public void startPreview() - { - Camera.Size previewSize = m_camera.getParameters().getPreviewSize(); - double bytesPerPixel = ImageFormat.getBitsPerPixel(m_camera.getParameters().getPreviewFormat()) / 8.0; - int bufferSizeNeeded = (int)Math.ceil(bytesPerPixel*previewSize.width*previewSize.height); - - //We need to clear preview buffers queue here, but there is no method to do it - //Though just resetting preview callback do the trick - m_camera.setPreviewCallback(null); - m_buffersLock.lock(); - if (m_cameraPreviewFirstBuffer == null || m_cameraPreviewFirstBuffer.length < bufferSizeNeeded) - m_cameraPreviewFirstBuffer = new byte[bufferSizeNeeded]; - if (m_cameraPreviewSecondBuffer == null || m_cameraPreviewSecondBuffer.length < bufferSizeNeeded) - m_cameraPreviewSecondBuffer = new byte[bufferSizeNeeded]; - addCallbackBuffer(); - m_buffersLock.unlock(); - m_camera.setPreviewCallbackWithBuffer(this); - - 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()); - } - } - - public byte[] lockAndFetchPreviewBuffer() - { - //This method should always be followed by unlockPreviewBuffer() - //This method is not just a getter. It also marks last preview as already seen one. - //We should reset actualBuffer flag here to make sure we will not use old preview with future captures - byte[] result = null; - m_buffersLock.lock(); - if (m_actualPreviewBuffer == 1) - result = m_cameraPreviewFirstBuffer; - else if (m_actualPreviewBuffer == 2) - result = m_cameraPreviewSecondBuffer; - m_actualPreviewBuffer = 0; - return result; - } - - public void unlockPreviewBuffer() - { - if (m_buffersLock.isHeldByCurrentThread()) - m_buffersLock.unlock(); - } - - private void addCallbackBuffer() - { - if (m_isReleased) - return; - - m_camera.addCallbackBuffer((m_actualPreviewBuffer == 1) - ? m_cameraPreviewSecondBuffer - : m_cameraPreviewFirstBuffer); - } - - @Override - public void onShutter() - { - notifyPictureExposed(m_cameraId); - } - - @Override - public void onPictureTaken(byte[] data, Camera camera) - { - notifyPictureCaptured(m_cameraId, data); - } - - @Override - public void onPreviewFrame(byte[] data, Camera camera) - { - m_buffersLock.lock(); - - if (data != null && m_fetchEachFrame) - notifyFrameFetched(m_cameraId, data); - - if (data == m_cameraPreviewFirstBuffer) - m_actualPreviewBuffer = 1; - else if (data == m_cameraPreviewSecondBuffer) - m_actualPreviewBuffer = 2; - else - m_actualPreviewBuffer = 0; - addCallbackBuffer(); - m_buffersLock.unlock(); - } - - @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); - private static native void notifyFrameFetched(int id, byte[] data); -} diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java new file mode 100644 index 000000000..27002fd29 --- /dev/null +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtCameraListener.java @@ -0,0 +1,148 @@ +/**************************************************************************** + ** + ** 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.ImageFormat; +import android.graphics.SurfaceTexture; +import android.util.Log; +import java.lang.Math; +import java.util.concurrent.locks.ReentrantLock; + +public class QtCameraListener implements Camera.ShutterCallback, + Camera.PictureCallback, + Camera.AutoFocusCallback, + Camera.PreviewCallback +{ + private int m_cameraId = -1; + private byte[][] m_cameraPreviewBuffer = null; + private volatile int m_actualPreviewBuffer = 0; + private final ReentrantLock m_buffersLock = new ReentrantLock(); + private boolean m_fetchEachFrame = false; + + private static final String TAG = "Qt Camera"; + + private QtCameraListener(int id) + { + m_cameraId = id; + } + + public void preparePreviewBuffer(Camera camera) + { + Camera.Size previewSize = camera.getParameters().getPreviewSize(); + double bytesPerPixel = ImageFormat.getBitsPerPixel(camera.getParameters().getPreviewFormat()) / 8.0; + int bufferSizeNeeded = (int)Math.ceil(bytesPerPixel*previewSize.width*previewSize.height); + m_buffersLock.lock(); + if (m_cameraPreviewBuffer == null || m_cameraPreviewBuffer[0].length < bufferSizeNeeded) + m_cameraPreviewBuffer = new byte[2][bufferSizeNeeded]; + m_buffersLock.unlock(); + } + + public void fetchEachFrame(boolean fetch) + { + m_fetchEachFrame = fetch; + } + + public byte[] lockAndFetchPreviewBuffer() + { + //This method should always be followed by unlockPreviewBuffer() + //This method is not just a getter. It also marks last preview as already seen one. + //We should reset actualBuffer flag here to make sure we will not use old preview with future captures + byte[] result = null; + m_buffersLock.lock(); + result = m_cameraPreviewBuffer[(m_actualPreviewBuffer == 1) ? 0 : 1]; + m_actualPreviewBuffer = 0; + return result; + } + + public void unlockPreviewBuffer() + { + if (m_buffersLock.isHeldByCurrentThread()) + m_buffersLock.unlock(); + } + + public byte[] callbackBuffer() + { + return m_cameraPreviewBuffer[(m_actualPreviewBuffer == 1) ? 1 : 0]; + } + + @Override + public void onShutter() + { + notifyPictureExposed(m_cameraId); + } + + @Override + public void onPictureTaken(byte[] data, Camera camera) + { + notifyPictureCaptured(m_cameraId, data); + } + + @Override + public void onPreviewFrame(byte[] data, Camera camera) + { + m_buffersLock.lock(); + + if (data != null && m_fetchEachFrame) + notifyFrameFetched(m_cameraId, data); + + if (data == m_cameraPreviewBuffer[0]) + m_actualPreviewBuffer = 1; + else if (data == m_cameraPreviewBuffer[1]) + m_actualPreviewBuffer = 2; + else + m_actualPreviewBuffer = 0; + camera.addCallbackBuffer(m_cameraPreviewBuffer[(m_actualPreviewBuffer == 1) ? 1 : 0]); + m_buffersLock.unlock(); + } + + @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); + private static native void notifyFrameFetched(int id, byte[] data); +} diff --git a/src/plugins/android/src/wrappers/jcamera.cpp b/src/plugins/android/src/wrappers/jcamera.cpp index f43e2308c..5401e6d1f 100644 --- a/src/plugins/android/src/wrappers/jcamera.cpp +++ b/src/plugins/android/src/wrappers/jcamera.cpp @@ -41,19 +41,19 @@ #include "jcamera.h" -#include #include #include #include "qandroidmultimediautils.h" -#include #include #include +#include QT_BEGIN_NAMESPACE -static jclass g_qtCameraClass = 0; -static QMap g_objectMap; -static QMutex g_objectMapMutex; +static jclass g_qtCameraListenerClass = 0; +static QMutex g_cameraMapMutex; +typedef QMap CameraMap; +Q_GLOBAL_STATIC(CameraMap, g_cameraMap) static QRect areaToRect(jobject areaObj) { @@ -79,31 +79,30 @@ static QJNIObjectPrivate rectToArea(const QRect &rect) return area; } -// native method for QtCamera.java +// native method for QtCameraLisener.java static void notifyAutoFocusComplete(JNIEnv* , jobject, int id, jboolean success) { - QMutexLocker locker(&g_objectMapMutex); - JCamera *obj = g_objectMap.value(id, 0); + QMutexLocker locker(&g_cameraMapMutex); + JCamera *obj = g_cameraMap->value(id, 0); if (obj) Q_EMIT obj->autoFocusComplete(success); } static void notifyPictureExposed(JNIEnv* , jobject, int id) { - QMutexLocker locker(&g_objectMapMutex); - JCamera *obj = g_objectMap.value(id, 0); + QMutexLocker locker(&g_cameraMapMutex); + JCamera *obj = g_cameraMap->value(id, 0); if (obj) Q_EMIT obj->pictureExposed(); } static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data) { - QMutexLocker locker(&g_objectMapMutex); - JCamera *obj = g_objectMap.value(id, 0); + QMutexLocker locker(&g_cameraMapMutex); + JCamera *obj = g_cameraMap->value(id, 0); if (obj) { - QByteArray bytes; - int arrayLength = env->GetArrayLength(data); - bytes.resize(arrayLength); + const int arrayLength = env->GetArrayLength(data); + QByteArray bytes(arrayLength, Qt::Uninitialized); env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); Q_EMIT obj->pictureCaptured(bytes); } @@ -111,46 +110,30 @@ static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data) static void notifyFrameFetched(JNIEnv *env, jobject, int id, jbyteArray data) { - QMutexLocker locker(&g_objectMapMutex); - JCamera *obj = g_objectMap.value(id, 0); + QMutexLocker locker(&g_cameraMapMutex); + JCamera *obj = g_cameraMap->value(id, 0); if (obj) { - QByteArray bytes; - int arrayLength = env->GetArrayLength(data); - bytes.resize(arrayLength); + const int arrayLength = env->GetArrayLength(data); + QByteArray bytes(arrayLength, Qt::Uninitialized); env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); Q_EMIT obj->frameFetched(bytes); } } -class JCameraInstantiator : public QObject +class JCameraPrivate : public QObject { Q_OBJECT public: - JCameraInstantiator() : QObject(0) {} - QJNIObjectPrivate result() {return lastCamera;} -public slots: - void openCamera(int cameraId) - { - QJNIEnvironmentPrivate env; - lastCamera = QJNIObjectPrivate::callStaticObjectMethod(g_qtCameraClass, - "open", - "(I)Lorg/qtproject/qt5/android/multimedia/QtCamera;", - cameraId); - } -private: - QJNIObjectPrivate lastCamera; -}; + JCameraPrivate(); + ~JCameraPrivate(); -class JCameraWorker : public QObject -{ - Q_OBJECT - friend class JCamera; - - JCameraWorker(JCamera *camera, int cameraId, jobject cam, QThread *workerThread); - ~JCameraWorker(); + Q_INVOKABLE bool init(int cameraId); Q_INVOKABLE void release(); + Q_INVOKABLE void lock(); + Q_INVOKABLE void unlock(); + Q_INVOKABLE void reconnect(); Q_INVOKABLE JCamera::CameraFacing getFacing(); Q_INVOKABLE int getNativeOrientation(); @@ -182,6 +165,7 @@ class JCameraWorker : public QObject Q_INVOKABLE void setFocusAreas(const QList &areas); Q_INVOKABLE void autoFocus(); + Q_INVOKABLE void cancelAutoFocus(); Q_INVOKABLE bool isAutoExposureLockSupported(); Q_INVOKABLE bool getAutoExposureLock(); @@ -212,26 +196,23 @@ class JCameraWorker : public QObject Q_INVOKABLE void startPreview(); Q_INVOKABLE void stopPreview(); + Q_INVOKABLE void takePicture(); + Q_INVOKABLE void fetchEachFrame(bool fetch); Q_INVOKABLE void fetchLastPreviewFrame(); Q_INVOKABLE void applyParameters(); Q_INVOKABLE QStringList callParametersStringListMethod(const QByteArray &methodName); - Q_INVOKABLE void callVoidMethod(const QByteArray &methodName); int m_cameraId; - QJNIObjectPrivate m_info; - QJNIObjectPrivate m_parameters; - + QMutex m_parametersMutex; QSize m_previewSize; int m_rotation; - - JCamera *q; - - QThread *m_workerThread; - QMutex m_parametersMutex; + QJNIObjectPrivate m_info; + QJNIObjectPrivate m_parameters; QJNIObjectPrivate m_camera; + QJNIObjectPrivate m_cameraListener; Q_SIGNALS: void previewSizeChanged(); @@ -245,122 +226,137 @@ Q_SIGNALS: void previewFetched(const QByteArray &preview); }; +JCamera::JCamera(JCameraPrivate *d, QThread *worker) + : QObject(), + d_ptr(d), + m_worker(worker) - -JCamera::JCamera(int cameraId, jobject cam, QThread *workerThread) - : QObject() { qRegisterMetaType >(); qRegisterMetaType >(); qRegisterMetaType >(); - d = new JCameraWorker(this, cameraId, cam, workerThread); - connect(d, &JCameraWorker::previewSizeChanged, this, &JCamera::previewSizeChanged); - connect(d, &JCameraWorker::previewStarted, this, &JCamera::previewStarted); - connect(d, &JCameraWorker::previewStopped, this, &JCamera::previewStopped); - connect(d, &JCameraWorker::autoFocusStarted, this, &JCamera::autoFocusStarted); - connect(d, &JCameraWorker::whiteBalanceChanged, this, &JCamera::whiteBalanceChanged); - connect(d, &JCameraWorker::previewFetched, this, &JCamera::previewFetched); + connect(d, &JCameraPrivate::previewSizeChanged, this, &JCamera::previewSizeChanged); + connect(d, &JCameraPrivate::previewStarted, this, &JCamera::previewStarted); + connect(d, &JCameraPrivate::previewStopped, this, &JCamera::previewStopped); + connect(d, &JCameraPrivate::autoFocusStarted, this, &JCamera::autoFocusStarted); + connect(d, &JCameraPrivate::whiteBalanceChanged, this, &JCamera::whiteBalanceChanged); + connect(d, &JCameraPrivate::previewFetched, this, &JCamera::previewFetched); } JCamera::~JCamera() { + Q_D(JCamera); if (d->m_camera.isValid()) { - g_objectMapMutex.lock(); - g_objectMap.remove(d->m_cameraId); - g_objectMapMutex.unlock(); + g_cameraMapMutex.lock(); + g_cameraMap->remove(d->m_cameraId); + g_cameraMapMutex.unlock(); } - d->deleteLater(); + + release(); + m_worker->exit(); + m_worker->wait(5000); } JCamera *JCamera::open(int cameraId) { - QThread *cameraThread = new QThread; - connect(cameraThread, &QThread::finished, cameraThread, &QThread::deleteLater); - cameraThread->start(); - JCameraInstantiator *instantiator = new JCameraInstantiator; - instantiator->moveToThread(cameraThread); - QMetaObject::invokeMethod(instantiator, "openCamera", - Qt::BlockingQueuedConnection, - Q_ARG(int, cameraId)); - QJNIObjectPrivate camera = instantiator->result(); - delete instantiator; - - if (!camera.isValid()) { - cameraThread->terminate(); - delete cameraThread; + JCameraPrivate *d = new JCameraPrivate(); + QThread *worker = new QThread; + worker->start(); + d->moveToThread(worker); + connect(worker, &QThread::finished, d, &JCameraPrivate::deleteLater); + bool ok = false; + QMetaObject::invokeMethod(d, "init", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok), Q_ARG(int, cameraId)); + if (!ok) { + worker->quit(); + worker->wait(5000); + delete d; + delete worker; return 0; - } else { - return new JCamera(cameraId, camera.object(), cameraThread); } + + JCamera *q = new JCamera(d, worker); + g_cameraMapMutex.lock(); + g_cameraMap->insert(cameraId, q); + g_cameraMapMutex.unlock(); + return q; } int JCamera::cameraId() const { + Q_D(const JCamera); return d->m_cameraId; } void JCamera::lock() { - QMetaObject::invokeMethod(d, "callVoidMethod", - Qt::BlockingQueuedConnection, - Q_ARG(QByteArray, "lock")); + Q_D(JCamera); + QMetaObject::invokeMethod(d, "lock", Qt::BlockingQueuedConnection); } void JCamera::unlock() { - QMetaObject::invokeMethod(d, "callVoidMethod", - Qt::BlockingQueuedConnection, - Q_ARG(QByteArray, "unlock")); + Q_D(JCamera); + QMetaObject::invokeMethod(d, "unlock", Qt::BlockingQueuedConnection); } void JCamera::reconnect() { - QMetaObject::invokeMethod(d, "callVoidMethod", Q_ARG(QByteArray, "reconnect")); + Q_D(JCamera); + QMetaObject::invokeMethod(d, "reconnect"); } void JCamera::release() { - QMetaObject::invokeMethod(d, "release"); + Q_D(JCamera); + QMetaObject::invokeMethod(d, "release", Qt::BlockingQueuedConnection); } JCamera::CameraFacing JCamera::getFacing() { + Q_D(JCamera); return d->getFacing(); } int JCamera::getNativeOrientation() { + Q_D(JCamera); return d->getNativeOrientation(); } QSize JCamera::getPreferredPreviewSizeForVideo() { + Q_D(JCamera); return d->getPreferredPreviewSizeForVideo(); } QList JCamera::getSupportedPreviewSizes() { + Q_D(JCamera); return d->getSupportedPreviewSizes(); } JCamera::ImageFormat JCamera::getPreviewFormat() { + Q_D(JCamera); return d->getPreviewFormat(); } void JCamera::setPreviewFormat(ImageFormat fmt) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setPreviewFormat", Q_ARG(JCamera::ImageFormat, fmt)); } QSize JCamera::previewSize() const { + Q_D(const JCamera); return d->m_previewSize; } void JCamera::setPreviewSize(const QSize &size) { + Q_D(JCamera); d->m_parametersMutex.lock(); bool areParametersValid = d->m_parameters.isValid(); d->m_parametersMutex.unlock(); @@ -373,176 +369,211 @@ void JCamera::setPreviewSize(const QSize &size) void JCamera::setPreviewTexture(jobject surfaceTexture) { - QMetaObject::invokeMethod(d, "setPreviewTexture", Q_ARG(void *, surfaceTexture)); + Q_D(JCamera); + QMetaObject::invokeMethod(d, "setPreviewTexture", Qt::BlockingQueuedConnection, Q_ARG(void *, surfaceTexture)); } bool JCamera::isZoomSupported() { + Q_D(JCamera); return d->isZoomSupported(); } int JCamera::getMaxZoom() { + Q_D(JCamera); return d->getMaxZoom(); } QList JCamera::getZoomRatios() { + Q_D(JCamera); return d->getZoomRatios(); } int JCamera::getZoom() { + Q_D(JCamera); return d->getZoom(); } void JCamera::setZoom(int value) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setZoom", Q_ARG(int, value)); } QStringList JCamera::getSupportedFlashModes() { + Q_D(JCamera); return d->callParametersStringListMethod("getSupportedFlashModes"); } QString JCamera::getFlashMode() { + Q_D(JCamera); return d->getFlashMode(); } void JCamera::setFlashMode(const QString &value) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setFlashMode", Q_ARG(QString, value)); } QStringList JCamera::getSupportedFocusModes() { + Q_D(JCamera); return d->callParametersStringListMethod("getSupportedFocusModes"); } QString JCamera::getFocusMode() { + Q_D(JCamera); return d->getFocusMode(); } void JCamera::setFocusMode(const QString &value) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setFocusMode", Q_ARG(QString, value)); } int JCamera::getMaxNumFocusAreas() { + Q_D(JCamera); return d->getMaxNumFocusAreas(); } QList JCamera::getFocusAreas() { + Q_D(JCamera); return d->getFocusAreas(); } void JCamera::setFocusAreas(const QList &areas) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setFocusAreas", Q_ARG(QList, areas)); } void JCamera::autoFocus() { + Q_D(JCamera); QMetaObject::invokeMethod(d, "autoFocus"); } void JCamera::cancelAutoFocus() { - QMetaObject::invokeMethod(d, "callVoidMethod", Q_ARG(QByteArray, "cancelAutoFocus")); + Q_D(JCamera); + QMetaObject::invokeMethod(d, "cancelAutoFocus", Qt::QueuedConnection); } bool JCamera::isAutoExposureLockSupported() { + Q_D(JCamera); return d->isAutoExposureLockSupported(); } bool JCamera::getAutoExposureLock() { + Q_D(JCamera); return d->getAutoExposureLock(); } void JCamera::setAutoExposureLock(bool toggle) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setAutoExposureLock", Q_ARG(bool, toggle)); } bool JCamera::isAutoWhiteBalanceLockSupported() { + Q_D(JCamera); return d->isAutoWhiteBalanceLockSupported(); } bool JCamera::getAutoWhiteBalanceLock() { + Q_D(JCamera); return d->getAutoWhiteBalanceLock(); } void JCamera::setAutoWhiteBalanceLock(bool toggle) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setAutoWhiteBalanceLock", Q_ARG(bool, toggle)); } int JCamera::getExposureCompensation() { + Q_D(JCamera); return d->getExposureCompensation(); } void JCamera::setExposureCompensation(int value) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setExposureCompensation", Q_ARG(int, value)); } float JCamera::getExposureCompensationStep() { + Q_D(JCamera); return d->getExposureCompensationStep(); } int JCamera::getMinExposureCompensation() { + Q_D(JCamera); return d->getMinExposureCompensation(); } int JCamera::getMaxExposureCompensation() { + Q_D(JCamera); return d->getMaxExposureCompensation(); } QStringList JCamera::getSupportedSceneModes() { + Q_D(JCamera); return d->callParametersStringListMethod("getSupportedSceneModes"); } QString JCamera::getSceneMode() { + Q_D(JCamera); return d->getSceneMode(); } void JCamera::setSceneMode(const QString &value) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setSceneMode", Q_ARG(QString, value)); } QStringList JCamera::getSupportedWhiteBalance() { + Q_D(JCamera); return d->callParametersStringListMethod("getSupportedWhiteBalance"); } QString JCamera::getWhiteBalance() { + Q_D(JCamera); return d->getWhiteBalance(); } void JCamera::setWhiteBalance(const QString &value) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setWhiteBalance", Q_ARG(QString, value)); } void JCamera::setRotation(int rotation) { + Q_D(JCamera); //We need to do it here and not in worker class because we cache rotation d->m_parametersMutex.lock(); bool areParametersValid = d->m_parameters.isValid(); @@ -556,110 +587,143 @@ void JCamera::setRotation(int rotation) int JCamera::getRotation() const { + Q_D(const JCamera); return d->m_rotation; } QList JCamera::getSupportedPictureSizes() { + Q_D(JCamera); return d->getSupportedPictureSizes(); } void JCamera::setPictureSize(const QSize &size) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setPictureSize", Q_ARG(QSize, size)); } void JCamera::setJpegQuality(int quality) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "setJpegQuality", Q_ARG(int, quality)); } void JCamera::takePicture() { - QMetaObject::invokeMethod(d, "callVoidMethod", Q_ARG(QByteArray, "takePicture")); + Q_D(JCamera); + QMetaObject::invokeMethod(d, "takePicture", Qt::BlockingQueuedConnection); } void JCamera::fetchEachFrame(bool fetch) { + Q_D(JCamera); QMetaObject::invokeMethod(d, "fetchEachFrame", Q_ARG(bool, fetch)); } void JCamera::fetchLastPreviewFrame() { + Q_D(JCamera); QMetaObject::invokeMethod(d, "fetchLastPreviewFrame"); } QJNIObjectPrivate JCamera::getCameraObject() { - return d->m_camera.getObjectField("m_camera", "Landroid/hardware/Camera;"); + Q_D(JCamera); + return d->m_camera; } void JCamera::startPreview() { + Q_D(JCamera); QMetaObject::invokeMethod(d, "startPreview"); } void JCamera::stopPreview() { + Q_D(JCamera); QMetaObject::invokeMethod(d, "stopPreview"); } +JCameraPrivate::JCameraPrivate() + : QObject(), + m_parametersMutex(QMutex::Recursive) +{ +} -//JCameraWorker +JCameraPrivate::~JCameraPrivate() +{ +} -JCameraWorker::JCameraWorker(JCamera *camera, int cameraId, jobject cam, QThread *workerThread) - : QObject(0) - , m_cameraId(cameraId) - , m_rotation(0) - , m_parametersMutex(QMutex::Recursive) - , m_camera(cam) +bool JCameraPrivate::init(int cameraId) { - q = camera; - m_workerThread = workerThread; - moveToThread(m_workerThread); + m_cameraId = cameraId; + m_camera = QJNIObjectPrivate::callStaticObjectMethod("android/hardware/Camera", + "open", + "(I)Landroid/hardware/Camera;", + cameraId); - if (m_camera.isValid()) { - g_objectMapMutex.lock(); - g_objectMap.insert(cameraId, q); - g_objectMapMutex.unlock(); + if (!m_camera.isValid()) + return false; - m_info = QJNIObjectPrivate("android/hardware/Camera$CameraInfo"); - m_camera.callStaticMethod("android/hardware/Camera", - "getCameraInfo", - "(ILandroid/hardware/Camera$CameraInfo;)V", - cameraId, m_info.object()); + m_cameraListener = QJNIObjectPrivate(g_qtCameraListenerClass, "(I)V", m_cameraId); + m_info = QJNIObjectPrivate("android/hardware/Camera$CameraInfo"); + m_camera.callStaticMethod("android/hardware/Camera", + "getCameraInfo", + "(ILandroid/hardware/Camera$CameraInfo;)V", + cameraId, + m_info.object()); - QJNIObjectPrivate params = m_camera.callObjectMethod("getParameters", - "()Landroid/hardware/Camera$Parameters;"); - m_parameters = QJNIObjectPrivate(params); - } -} + QJNIObjectPrivate params = m_camera.callObjectMethod("getParameters", + "()Landroid/hardware/Camera$Parameters;"); + m_parameters = QJNIObjectPrivate(params); -JCameraWorker::~JCameraWorker() -{ - m_workerThread->quit(); + return true; } -void JCameraWorker::release() +void JCameraPrivate::release() { m_previewSize = QSize(); m_parametersMutex.lock(); m_parameters = QJNIObjectPrivate(); m_parametersMutex.unlock(); - m_camera.callMethod("release"); + if (m_camera.isValid()) + m_camera.callMethod("release"); +} + +void JCameraPrivate::lock() +{ + m_camera.callMethod("lock"); +} + +void JCameraPrivate::unlock() +{ + m_camera.callMethod("unlock"); +} + +void JCameraPrivate::reconnect() +{ + QJNIEnvironmentPrivate env; + m_camera.callMethod("reconnect"); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif // QT_DEBUG + env->ExceptionDescribe(); + } } -JCamera::CameraFacing JCameraWorker::getFacing() +JCamera::CameraFacing JCameraPrivate::getFacing() { return JCamera::CameraFacing(m_info.getField("facing")); } -int JCameraWorker::getNativeOrientation() +int JCameraPrivate::getNativeOrientation() { return m_info.getField("orientation"); } -QSize JCameraWorker::getPreferredPreviewSizeForVideo() +QSize JCameraPrivate::getPreferredPreviewSizeForVideo() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -672,7 +736,7 @@ QSize JCameraWorker::getPreferredPreviewSizeForVideo() return QSize(size.getField("width"), size.getField("height")); } -QList JCameraWorker::getSupportedPreviewSizes() +QList JCameraPrivate::getSupportedPreviewSizes() { QList list; @@ -695,7 +759,7 @@ QList JCameraWorker::getSupportedPreviewSizes() return list; } -JCamera::ImageFormat JCameraWorker::getPreviewFormat() +JCamera::ImageFormat JCameraPrivate::getPreviewFormat() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -705,7 +769,7 @@ JCamera::ImageFormat JCameraWorker::getPreviewFormat() return JCamera::ImageFormat(m_parameters.callMethod("getPreviewFormat")); } -void JCameraWorker::setPreviewFormat(JCamera::ImageFormat fmt) +void JCameraPrivate::setPreviewFormat(JCamera::ImageFormat fmt) { QMutexLocker parametersLocker(&m_parametersMutex); @@ -716,7 +780,7 @@ void JCameraWorker::setPreviewFormat(JCamera::ImageFormat fmt) applyParameters(); } -void JCameraWorker::updatePreviewSize() +void JCameraPrivate::updatePreviewSize() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -728,14 +792,14 @@ void JCameraWorker::updatePreviewSize() emit previewSizeChanged(); } -void JCameraWorker::setPreviewTexture(void *surfaceTexture) +void JCameraPrivate::setPreviewTexture(void *surfaceTexture) { m_camera.callMethod("setPreviewTexture", "(Landroid/graphics/SurfaceTexture;)V", static_cast(surfaceTexture)); } -bool JCameraWorker::isZoomSupported() +bool JCameraPrivate::isZoomSupported() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -745,7 +809,7 @@ bool JCameraWorker::isZoomSupported() return m_parameters.callMethod("isZoomSupported"); } -int JCameraWorker::getMaxZoom() +int JCameraPrivate::getMaxZoom() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -755,7 +819,7 @@ int JCameraWorker::getMaxZoom() return m_parameters.callMethod("getMaxZoom"); } -QList JCameraWorker::getZoomRatios() +QList JCameraPrivate::getZoomRatios() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -777,7 +841,7 @@ QList JCameraWorker::getZoomRatios() return ratios; } -int JCameraWorker::getZoom() +int JCameraPrivate::getZoom() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -787,7 +851,7 @@ int JCameraWorker::getZoom() return m_parameters.callMethod("getZoom"); } -void JCameraWorker::setZoom(int value) +void JCameraPrivate::setZoom(int value) { QMutexLocker parametersLocker(&m_parametersMutex); @@ -798,7 +862,7 @@ void JCameraWorker::setZoom(int value) applyParameters(); } -QString JCameraWorker::getFlashMode() +QString JCameraPrivate::getFlashMode() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -814,7 +878,7 @@ QString JCameraWorker::getFlashMode() return value; } -void JCameraWorker::setFlashMode(const QString &value) +void JCameraPrivate::setFlashMode(const QString &value) { QMutexLocker parametersLocker(&m_parametersMutex); @@ -827,7 +891,7 @@ void JCameraWorker::setFlashMode(const QString &value) applyParameters(); } -QString JCameraWorker::getFocusMode() +QString JCameraPrivate::getFocusMode() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -843,7 +907,7 @@ QString JCameraWorker::getFocusMode() return value; } -void JCameraWorker::setFocusMode(const QString &value) +void JCameraPrivate::setFocusMode(const QString &value) { QMutexLocker parametersLocker(&m_parametersMutex); @@ -856,7 +920,7 @@ void JCameraWorker::setFocusMode(const QString &value) applyParameters(); } -int JCameraWorker::getMaxNumFocusAreas() +int JCameraPrivate::getMaxNumFocusAreas() { if (QtAndroidPrivate::androidSdkVersion() < 14) return 0; @@ -869,7 +933,7 @@ int JCameraWorker::getMaxNumFocusAreas() return m_parameters.callMethod("getMaxNumFocusAreas"); } -QList JCameraWorker::getFocusAreas() +QList JCameraPrivate::getFocusAreas() { QList areas; @@ -897,7 +961,7 @@ QList JCameraWorker::getFocusAreas() return areas; } -void JCameraWorker::setFocusAreas(const QList &areas) +void JCameraPrivate::setFocusAreas(const QList &areas) { if (QtAndroidPrivate::androidSdkVersion() < 14) return; @@ -927,13 +991,20 @@ void JCameraWorker::setFocusAreas(const QList &areas) applyParameters(); } -void JCameraWorker::autoFocus() +void JCameraPrivate::autoFocus() { - m_camera.callMethod("autoFocus"); + m_camera.callMethod("autoFocus", + "(Landroid/hardware/Camera$AutoFocusCallback;)V", + m_cameraListener.object()); emit autoFocusStarted(); } -bool JCameraWorker::isAutoExposureLockSupported() +void JCameraPrivate::cancelAutoFocus() +{ + m_camera.callMethod("cancelAutoFocus"); +} + +bool JCameraPrivate::isAutoExposureLockSupported() { if (QtAndroidPrivate::androidSdkVersion() < 14) return false; @@ -946,7 +1017,7 @@ bool JCameraWorker::isAutoExposureLockSupported() return m_parameters.callMethod("isAutoExposureLockSupported"); } -bool JCameraWorker::getAutoExposureLock() +bool JCameraPrivate::getAutoExposureLock() { if (QtAndroidPrivate::androidSdkVersion() < 14) return false; @@ -959,7 +1030,7 @@ bool JCameraWorker::getAutoExposureLock() return m_parameters.callMethod("getAutoExposureLock"); } -void JCameraWorker::setAutoExposureLock(bool toggle) +void JCameraPrivate::setAutoExposureLock(bool toggle) { if (QtAndroidPrivate::androidSdkVersion() < 14) return; @@ -973,7 +1044,7 @@ void JCameraWorker::setAutoExposureLock(bool toggle) applyParameters(); } -bool JCameraWorker::isAutoWhiteBalanceLockSupported() +bool JCameraPrivate::isAutoWhiteBalanceLockSupported() { if (QtAndroidPrivate::androidSdkVersion() < 14) return false; @@ -986,7 +1057,7 @@ bool JCameraWorker::isAutoWhiteBalanceLockSupported() return m_parameters.callMethod("isAutoWhiteBalanceLockSupported"); } -bool JCameraWorker::getAutoWhiteBalanceLock() +bool JCameraPrivate::getAutoWhiteBalanceLock() { if (QtAndroidPrivate::androidSdkVersion() < 14) return false; @@ -999,7 +1070,7 @@ bool JCameraWorker::getAutoWhiteBalanceLock() return m_parameters.callMethod("getAutoWhiteBalanceLock"); } -void JCameraWorker::setAutoWhiteBalanceLock(bool toggle) +void JCameraPrivate::setAutoWhiteBalanceLock(bool toggle) { if (QtAndroidPrivate::androidSdkVersion() < 14) return; @@ -1013,7 +1084,7 @@ void JCameraWorker::setAutoWhiteBalanceLock(bool toggle) applyParameters(); } -int JCameraWorker::getExposureCompensation() +int JCameraPrivate::getExposureCompensation() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1023,7 +1094,7 @@ int JCameraWorker::getExposureCompensation() return m_parameters.callMethod("getExposureCompensation"); } -void JCameraWorker::setExposureCompensation(int value) +void JCameraPrivate::setExposureCompensation(int value) { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1034,7 +1105,7 @@ void JCameraWorker::setExposureCompensation(int value) applyParameters(); } -float JCameraWorker::getExposureCompensationStep() +float JCameraPrivate::getExposureCompensationStep() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1044,7 +1115,7 @@ float JCameraWorker::getExposureCompensationStep() return m_parameters.callMethod("getExposureCompensationStep"); } -int JCameraWorker::getMinExposureCompensation() +int JCameraPrivate::getMinExposureCompensation() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1054,7 +1125,7 @@ int JCameraWorker::getMinExposureCompensation() return m_parameters.callMethod("getMinExposureCompensation"); } -int JCameraWorker::getMaxExposureCompensation() +int JCameraPrivate::getMaxExposureCompensation() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1064,7 +1135,7 @@ int JCameraWorker::getMaxExposureCompensation() return m_parameters.callMethod("getMaxExposureCompensation"); } -QString JCameraWorker::getSceneMode() +QString JCameraPrivate::getSceneMode() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1080,7 +1151,7 @@ QString JCameraWorker::getSceneMode() return value; } -void JCameraWorker::setSceneMode(const QString &value) +void JCameraPrivate::setSceneMode(const QString &value) { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1093,7 +1164,7 @@ void JCameraWorker::setSceneMode(const QString &value) applyParameters(); } -QString JCameraWorker::getWhiteBalance() +QString JCameraPrivate::getWhiteBalance() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1109,7 +1180,7 @@ QString JCameraWorker::getWhiteBalance() return value; } -void JCameraWorker::setWhiteBalance(const QString &value) +void JCameraPrivate::setWhiteBalance(const QString &value) { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1124,7 +1195,7 @@ void JCameraWorker::setWhiteBalance(const QString &value) emit whiteBalanceChanged(); } -void JCameraWorker::updateRotation() +void JCameraPrivate::updateRotation() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1132,7 +1203,7 @@ void JCameraWorker::updateRotation() applyParameters(); } -QList JCameraWorker::getSupportedPictureSizes() +QList JCameraPrivate::getSupportedPictureSizes() { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1155,7 +1226,7 @@ QList JCameraWorker::getSupportedPictureSizes() return list; } -void JCameraWorker::setPictureSize(const QSize &size) +void JCameraPrivate::setPictureSize(const QSize &size) { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1166,7 +1237,7 @@ void JCameraWorker::setPictureSize(const QSize &size) applyParameters(); } -void JCameraWorker::setJpegQuality(int quality) +void JCameraPrivate::setJpegQuality(int quality) { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1177,49 +1248,71 @@ void JCameraWorker::setJpegQuality(int quality) applyParameters(); } -void JCameraWorker::startPreview() -{ - callVoidMethod("startPreview"); +void JCameraPrivate::startPreview() +{ + //We need to clear preview buffers queue here, but there is no method to do it + //Though just resetting preview callback do the trick + m_camera.callMethod("setPreviewCallbackWithBuffer", + "(Landroid/hardware/Camera$PreviewCallback;)V", + jobject(0)); + m_cameraListener.callMethod("preparePreviewBuffer", "(Landroid/hardware/Camera;)V", m_camera.object()); + QJNIObjectPrivate buffer = m_cameraListener.callObjectMethod("callbackBuffer"); + m_camera.callMethod("addCallbackBuffer", "([B)V", buffer.object()); + m_camera.callMethod("setPreviewCallbackWithBuffer", + "(Landroid/hardware/Camera$PreviewCallback;)V", + m_cameraListener.object()); + m_camera.callMethod("startPreview"); emit previewStarted(); } -void JCameraWorker::stopPreview() +void JCameraPrivate::stopPreview() { - callVoidMethod("stopPreview"); + m_camera.callMethod("stopPreview"); emit previewStopped(); } -void JCameraWorker::fetchEachFrame(bool fetch) +void JCameraPrivate::takePicture() +{ + m_camera.callMethod("takePicture", "(Landroid/hardware/Camera$ShutterCallback;" + "Landroid/hardware/Camera$PictureCallback;" + "Landroid/hardware/Camera$PictureCallback;)V", + m_cameraListener.object(), + jobject(0), + m_cameraListener.object()); +} + +void JCameraPrivate::fetchEachFrame(bool fetch) { - m_camera.callMethod("fetchEachFrame", "(Z)V", fetch); + m_cameraListener.callMethod("fetchEachFrame", "(Z)V", fetch); } -void JCameraWorker::fetchLastPreviewFrame() +void JCameraPrivate::fetchLastPreviewFrame() { QJNIEnvironmentPrivate env; - QJNIObjectPrivate dataObj = m_camera.callObjectMethod("lockAndFetchPreviewBuffer", "()[B"); - if (!dataObj.object()) { - m_camera.callMethod("unlockPreviewBuffer"); + QJNIObjectPrivate data = m_cameraListener.callObjectMethod("lockAndFetchPreviewBuffer", "()[B"); + if (!data.isValid()) { + m_cameraListener.callMethod("unlockPreviewBuffer"); return; } - jbyteArray data = static_cast(dataObj.object()); - QByteArray bytes; - int arrayLength = env->GetArrayLength(data); - bytes.resize(arrayLength); - env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); - m_camera.callMethod("unlockPreviewBuffer"); + const int arrayLength = env->GetArrayLength(static_cast(data.object())); + QByteArray bytes(arrayLength, Qt::Uninitialized); + env->GetByteArrayRegion(static_cast(data.object()), + 0, + arrayLength, + reinterpret_cast(bytes.data())); + m_cameraListener.callMethod("unlockPreviewBuffer"); emit previewFetched(bytes); } -void JCameraWorker::applyParameters() +void JCameraPrivate::applyParameters() { m_camera.callMethod("setParameters", "(Landroid/hardware/Camera$Parameters;)V", m_parameters.object()); } -QStringList JCameraWorker::callParametersStringListMethod(const QByteArray &methodName) +QStringList JCameraPrivate::callParametersStringListMethod(const QByteArray &methodName) { QMutexLocker parametersLocker(&m_parametersMutex); @@ -1235,7 +1328,6 @@ QStringList JCameraWorker::callParametersStringListMethod(const QByteArray &meth QJNIObjectPrivate string = list.callObjectMethod("get", "(I)Ljava/lang/Object;", i); - stringList.append(string.toString()); } } @@ -1244,12 +1336,6 @@ QStringList JCameraWorker::callParametersStringListMethod(const QByteArray &meth return stringList; } -void JCameraWorker::callVoidMethod(const QByteArray &methodName) -{ - m_camera.callMethod(methodName.constData()); -} - - static JNINativeMethod methods[] = { {"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete}, {"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed}, @@ -1259,13 +1345,13 @@ static JNINativeMethod methods[] = { bool JCamera::initJNI(JNIEnv *env) { - jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtCamera"); + jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtCameraListener"); if (env->ExceptionCheck()) env->ExceptionClear(); if (clazz) { - g_qtCameraClass = static_cast(env->NewGlobalRef(clazz)); - if (env->RegisterNatives(g_qtCameraClass, + g_qtCameraListenerClass = static_cast(env->NewGlobalRef(clazz)); + if (env->RegisterNatives(g_qtCameraListenerClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) { return false; diff --git a/src/plugins/android/src/wrappers/jcamera.h b/src/plugins/android/src/wrappers/jcamera.h index 81c334eb4..ec5bcc3c7 100644 --- a/src/plugins/android/src/wrappers/jcamera.h +++ b/src/plugins/android/src/wrappers/jcamera.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE class QThread; -class JCameraWorker; +class JCameraPrivate; class JCamera : public QObject { @@ -175,9 +175,11 @@ Q_SIGNALS: void frameFetched(const QByteArray &frame); private: - JCamera(int cameraId, jobject cam, QThread *workerThread); + JCamera(JCameraPrivate *d, QThread *worker); - JCameraWorker *d; + Q_DECLARE_PRIVATE(JCamera) + JCameraPrivate *d_ptr; + QScopedPointer m_worker; }; QT_END_NAMESPACE -- cgit v1.2.3 From 4c8284de46052970de001c5c9b96c4fa365f89b4 Mon Sep 17 00:00:00 2001 From: Niels Weber Date: Mon, 14 Apr 2014 18:36:40 +0200 Subject: Rework qmlvideofx example Task-number: QTBUG-38121 Change-Id: If06ba6ce2c66b4d735baaeb56e004861c62ea533 Reviewed-by: Alessandro Portale --- examples/multimedia/video/qmlvideofx/Info.plist | 30 ++ .../video/qmlvideofx/android/AndroidManifest.xml | 48 +++ .../video/qmlvideofx/images/Dropdown_arrows.png | Bin 0 -> 1156 bytes .../video/qmlvideofx/images/Slider_bar.png | Bin 0 -> 1129 bytes .../video/qmlvideofx/images/Slider_handle.png | Bin 0 -> 2784 bytes .../video/qmlvideofx/images/Triangle_Top.png | Bin 0 -> 2212 bytes .../video/qmlvideofx/images/Triangle_bottom.png | Bin 0 -> 2125 bytes .../multimedia/video/qmlvideofx/images/close.png | Bin 1799 -> 0 bytes .../multimedia/video/qmlvideofx/images/folder.png | Bin 1841 -> 0 bytes .../video/qmlvideofx/images/icon_BackArrow.png | Bin 0 -> 1268 bytes .../video/qmlvideofx/images/icon_Folder.png | Bin 0 -> 1829 bytes .../video/qmlvideofx/images/icon_Menu.png | Bin 0 -> 990 bytes .../video/qmlvideofx/images/titlebar.png | Bin 1436 -> 0 bytes .../video/qmlvideofx/images/titlebar.sci | 5 - examples/multimedia/video/qmlvideofx/images/up.png | Bin 662 -> 0 bytes examples/multimedia/video/qmlvideofx/main.cpp | 16 +- .../video/qmlvideofx/qml/qmlvideofx/Button.qml | 23 +- .../video/qmlvideofx/qml/qmlvideofx/Content.qml | 3 +- .../qmlvideofx/qml/qmlvideofx/ContentImage.qml | 2 +- .../qmlvideofx/qml/qmlvideofx/ContentVideo.qml | 21 +- .../video/qmlvideofx/qml/qmlvideofx/Curtain.qml | 94 +++++ .../video/qmlvideofx/qml/qmlvideofx/Divider.qml | 31 +- .../qmlvideofx/qml/qmlvideofx/EffectBillboard.qml | 2 +- .../qml/qmlvideofx/EffectBlackAndWhite.qml | 2 +- .../qml/qmlvideofx/EffectGaussianBlur.qml | 2 +- .../qmlvideofx/qml/qmlvideofx/EffectIsolate.qml | 4 +- .../qmlvideofx/qml/qmlvideofx/EffectMagnify.qml | 4 +- .../qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml | 2 +- .../qmlvideofx/qml/qmlvideofx/EffectPixelate.qml | 2 +- .../qmlvideofx/qml/qmlvideofx/EffectPosterize.qml | 2 +- .../qmlvideofx/qml/qmlvideofx/EffectRipple.qml | 4 +- .../qml/qmlvideofx/EffectSelectionList.qml | 67 ++++ .../qml/qmlvideofx/EffectSelectionPanel.qml | 154 -------- .../qmlvideofx/qml/qmlvideofx/EffectSharpen.qml | 2 +- .../qmlvideofx/qml/qmlvideofx/EffectShockwave.qml | 2 +- .../qml/qmlvideofx/EffectSobelEdgeDetection1.qml | 2 +- .../qml/qmlvideofx/EffectSobelEdgeDetection2.qml | 56 --- .../video/qmlvideofx/qml/qmlvideofx/EffectToon.qml | 2 +- .../qmlvideofx/qml/qmlvideofx/EffectWobble.qml | 2 +- .../qmlvideofx/qml/qmlvideofx/FileBrowser.qml | 100 +++-- .../video/qmlvideofx/qml/qmlvideofx/FileOpen.qml | 123 ++++--- .../video/qmlvideofx/qml/qmlvideofx/Main.qml | 287 +++++++++++++++ .../qmlvideofx/qml/qmlvideofx/ParameterPanel.qml | 15 +- .../video/qmlvideofx/qml/qmlvideofx/Slider.qml | 123 +++---- .../qmlvideofx/qml/qmlvideofx/main-largescreen.qml | 186 ---------- .../qmlvideofx/qml/qmlvideofx/main-smallscreen.qml | 408 --------------------- .../multimedia/video/qmlvideofx/qmlvideofx.pro | 12 +- .../multimedia/video/qmlvideofx/qmlvideofx.qrc | 21 +- .../qmlvideofx/shaders/sobeledgedetection2.fsh | 77 ---- 49 files changed, 811 insertions(+), 1125 deletions(-) create mode 100644 examples/multimedia/video/qmlvideofx/Info.plist create mode 100644 examples/multimedia/video/qmlvideofx/android/AndroidManifest.xml create mode 100644 examples/multimedia/video/qmlvideofx/images/Dropdown_arrows.png create mode 100644 examples/multimedia/video/qmlvideofx/images/Slider_bar.png create mode 100644 examples/multimedia/video/qmlvideofx/images/Slider_handle.png create mode 100644 examples/multimedia/video/qmlvideofx/images/Triangle_Top.png create mode 100644 examples/multimedia/video/qmlvideofx/images/Triangle_bottom.png delete mode 100644 examples/multimedia/video/qmlvideofx/images/close.png delete mode 100644 examples/multimedia/video/qmlvideofx/images/folder.png create mode 100644 examples/multimedia/video/qmlvideofx/images/icon_BackArrow.png create mode 100644 examples/multimedia/video/qmlvideofx/images/icon_Folder.png create mode 100644 examples/multimedia/video/qmlvideofx/images/icon_Menu.png delete mode 100644 examples/multimedia/video/qmlvideofx/images/titlebar.png delete mode 100644 examples/multimedia/video/qmlvideofx/images/titlebar.sci delete mode 100644 examples/multimedia/video/qmlvideofx/images/up.png create mode 100644 examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Curtain.qml create mode 100644 examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionList.qml delete mode 100644 examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionPanel.qml delete mode 100644 examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection2.qml create mode 100644 examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml delete mode 100644 examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-largescreen.qml delete mode 100644 examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-smallscreen.qml delete mode 100644 examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection2.fsh diff --git a/examples/multimedia/video/qmlvideofx/Info.plist b/examples/multimedia/video/qmlvideofx/Info.plist new file mode 100644 index 000000000..8fc242516 --- /dev/null +++ b/examples/multimedia/video/qmlvideofx/Info.plist @@ -0,0 +1,30 @@ + + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationLandscapeRight + + UIInterfaceOrientation + UIInterfaceOrientationLandscapeRight + CFBundleIconFile + + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleExecutable + qmlvideofx + CFBundleIdentifier + com.digia.${PRODUCT_NAME:rfc1034identifier} + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleName + ${PRODUCT_NAME} + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1.0 + + diff --git a/examples/multimedia/video/qmlvideofx/android/AndroidManifest.xml b/examples/multimedia/video/qmlvideofx/android/AndroidManifest.xml new file mode 100644 index 000000000..0612d484c --- /dev/null +++ b/examples/multimedia/video/qmlvideofx/android/AndroidManifest.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/multimedia/video/qmlvideofx/images/Dropdown_arrows.png b/examples/multimedia/video/qmlvideofx/images/Dropdown_arrows.png new file mode 100644 index 000000000..0a9e25ce2 Binary files /dev/null and b/examples/multimedia/video/qmlvideofx/images/Dropdown_arrows.png differ diff --git a/examples/multimedia/video/qmlvideofx/images/Slider_bar.png b/examples/multimedia/video/qmlvideofx/images/Slider_bar.png new file mode 100644 index 000000000..84be50fae Binary files /dev/null and b/examples/multimedia/video/qmlvideofx/images/Slider_bar.png differ diff --git a/examples/multimedia/video/qmlvideofx/images/Slider_handle.png b/examples/multimedia/video/qmlvideofx/images/Slider_handle.png new file mode 100644 index 000000000..aebecdf19 Binary files /dev/null and b/examples/multimedia/video/qmlvideofx/images/Slider_handle.png differ diff --git a/examples/multimedia/video/qmlvideofx/images/Triangle_Top.png b/examples/multimedia/video/qmlvideofx/images/Triangle_Top.png new file mode 100644 index 000000000..5768e9536 Binary files /dev/null and b/examples/multimedia/video/qmlvideofx/images/Triangle_Top.png differ diff --git a/examples/multimedia/video/qmlvideofx/images/Triangle_bottom.png b/examples/multimedia/video/qmlvideofx/images/Triangle_bottom.png new file mode 100644 index 000000000..509409666 Binary files /dev/null and b/examples/multimedia/video/qmlvideofx/images/Triangle_bottom.png differ diff --git a/examples/multimedia/video/qmlvideofx/images/close.png b/examples/multimedia/video/qmlvideofx/images/close.png deleted file mode 100644 index 6904df0e4..000000000 Binary files a/examples/multimedia/video/qmlvideofx/images/close.png and /dev/null differ diff --git a/examples/multimedia/video/qmlvideofx/images/folder.png b/examples/multimedia/video/qmlvideofx/images/folder.png deleted file mode 100644 index e53e2ad46..000000000 Binary files a/examples/multimedia/video/qmlvideofx/images/folder.png and /dev/null differ diff --git a/examples/multimedia/video/qmlvideofx/images/icon_BackArrow.png b/examples/multimedia/video/qmlvideofx/images/icon_BackArrow.png new file mode 100644 index 000000000..6823de004 Binary files /dev/null and b/examples/multimedia/video/qmlvideofx/images/icon_BackArrow.png differ diff --git a/examples/multimedia/video/qmlvideofx/images/icon_Folder.png b/examples/multimedia/video/qmlvideofx/images/icon_Folder.png new file mode 100644 index 000000000..62d97004f Binary files /dev/null and b/examples/multimedia/video/qmlvideofx/images/icon_Folder.png differ diff --git a/examples/multimedia/video/qmlvideofx/images/icon_Menu.png b/examples/multimedia/video/qmlvideofx/images/icon_Menu.png new file mode 100644 index 000000000..bc078612e Binary files /dev/null and b/examples/multimedia/video/qmlvideofx/images/icon_Menu.png differ diff --git a/examples/multimedia/video/qmlvideofx/images/titlebar.png b/examples/multimedia/video/qmlvideofx/images/titlebar.png deleted file mode 100644 index 51c90082d..000000000 Binary files a/examples/multimedia/video/qmlvideofx/images/titlebar.png and /dev/null differ diff --git a/examples/multimedia/video/qmlvideofx/images/titlebar.sci b/examples/multimedia/video/qmlvideofx/images/titlebar.sci deleted file mode 100644 index 0418d94cd..000000000 --- a/examples/multimedia/video/qmlvideofx/images/titlebar.sci +++ /dev/null @@ -1,5 +0,0 @@ -border.left: 10 -border.top: 12 -border.bottom: 12 -border.right: 10 -source: titlebar.png diff --git a/examples/multimedia/video/qmlvideofx/images/up.png b/examples/multimedia/video/qmlvideofx/images/up.png deleted file mode 100644 index b05f8025d..000000000 Binary files a/examples/multimedia/video/qmlvideofx/images/up.png and /dev/null differ diff --git a/examples/multimedia/video/qmlvideofx/main.cpp b/examples/multimedia/video/qmlvideofx/main.cpp index 7465deab8..f221c954a 100644 --- a/examples/multimedia/video/qmlvideofx/main.cpp +++ b/examples/multimedia/video/qmlvideofx/main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Mobility Components. @@ -48,12 +48,6 @@ #include "filereader.h" #include "trace.h" -#ifdef SMALL_SCREEN_LAYOUT - static const QLatin1String MainQmlFile("main-smallscreen.qml"); -#else - static const QLatin1String MainQmlFile("main-largescreen.qml"); -#endif - #ifdef PERFORMANCEMONITOR_SUPPORT #include "performancemonitordeclarative.h" #endif @@ -99,7 +93,7 @@ int main(int argc, char *argv[]) QQuickView viewer; - viewer.setSource(QLatin1String("qrc:///qml/qmlvideofx/") + MainQmlFile); + viewer.setSource(QUrl(QLatin1String("qrc:///qml/qmlvideofx/Main.qml"))); QQuickItem *rootObject = viewer.rootObject(); rootObject->setProperty("fileName", fileName); viewer.rootObject()->setProperty("volume", volume); @@ -128,13 +122,9 @@ int main(int argc, char *argv[]) viewer.setTitle("qmlvideofx"); viewer.setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - viewer.setMinimumSize(QSize(600, 400)); + viewer.setMinimumSize(QSize(640, 360)); -#ifdef SMALL_SCREEN_PHYSICAL - viewer.showFullScreen(); -#else viewer.show(); -#endif // Delay invocation of init until the event loop has started, to work around // a GL context issue on Harmattan: without this, we get the following error diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml index eb82aceed..dd7cca602 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml @@ -43,29 +43,33 @@ import QtQuick 2.0 Rectangle { id: root - color: textColor - radius: 0.25 * height + color: "transparent" + height: itemHeight + width: itemWidth property string text - property color bgColor: "white" - property color bgColorSelected: "red" - property color textColor: "black" + property color bgColor: "transparent" + property color bgColorSelected: "#14aaff" + property color textColor: "white" property alias enabled: mouseArea.enabled + property bool active: true + property alias horizontalAlign: text.horizontalAlignment signal clicked Rectangle { anchors { fill: parent; margins: 1 } color: mouseArea.pressed ? bgColorSelected : bgColor - radius: 0.25 * height + radius: 0.1 * height Text { id: text - anchors.centerIn: parent + clip: true text: root.text - font.pixelSize: 0.5 * parent.height + anchors { fill: parent; margins: scaledMargin } + font.pixelSize: fontSize color: mouseArea.pressed ? bgColor : textColor - horizontalAlignment: Text.AlignHCenter + horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter } @@ -75,6 +79,7 @@ Rectangle { onClicked: { root.clicked() } + enabled: active } } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml index d3a2e9f42..72b7cca7e 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Content.qml @@ -39,11 +39,10 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick 2.1 Rectangle { id: root - color: "black" property alias effect: effectLoader.item property alias gripSize: divider.gripSize property string effectSource diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentImage.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentImage.qml index 0fa047bb1..2bce20bf0 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentImage.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentImage.qml @@ -39,7 +39,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick 2.1 Image { fillMode: Image.PreserveAspectFit diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml index be09f7ea5..6491ceff2 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ContentVideo.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Mobility Components. @@ -39,13 +39,14 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick 2.1 import QtMultimedia 5.0 VideoOutput { source: mediaPlayer property alias mediaSource: mediaPlayer.source property alias volume: mediaPlayer.volume + property bool isRunning: true MediaPlayer { id: mediaPlayer @@ -55,5 +56,21 @@ VideoOutput { } function play() { mediaPlayer.play() } + function pause() { mediaPlayer.pause() } function stop() { mediaPlayer.stop() } + + function toggleplay() { + if (isRunning) { + pause() + isRunning = false + } else { + play() + isRunning = true + } + } + + MouseArea { + anchors.fill: parent + onClicked: toggleplay() + } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Curtain.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Curtain.qml new file mode 100644 index 000000000..253e3c397 --- /dev/null +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Curtain.qml @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Mobility Components. +** +** $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$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: root + color: "transparent" + radius: 5 + property alias value: grip.value + property color gripColor: "transparent" + property real gripSize: 20 + property real gripTolerance: 3.0 + property real increment: 0.1 + property bool enabled: true + property string imageSource: "qrc:/images/Triangle_Top.png" + + Rectangle { + id: grip + property real value: 0.5 + x: (value * parent.width) - width/2 + anchors.verticalCenter: parent.verticalCenter + width: root.gripTolerance * root.gripSize + height: width + radius: width/2 + color: "transparent" + + Image { + id: sliderhandleimage + source: imageSource + anchors.centerIn: parent + } + + MouseArea { + id: mouseArea + enabled: root.enabled + anchors.fill: parent + drag { + target: grip + axis: Drag.XAxis + minimumX: -parent.width/2 + maximumX: root.width - parent.width/2 + } + onPositionChanged: { + if (drag.active) + updatePosition() + } + onReleased: { + updatePosition() + } + function updatePosition() { + value = (grip.x + grip.width/2) / grip.parent.width + } + } + } +} diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Divider.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Divider.qml index 390818bbc..45c2606f9 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Divider.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Divider.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Mobility Components. @@ -39,7 +39,7 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick 2.1 Rectangle { id: root @@ -53,21 +53,34 @@ Rectangle { id: line anchors { top: parent.top; bottom: parent.bottom } x: parent.value * parent.width - (width / 2) - width: 2 - color: "red" + width: 4 + color: "#14aaff" } - Slider { + // topgrip + Curtain { id: slider increment: 0.0 - lineColor: "transparent" - fillColor: "transparent" - gripColor: "red" anchors { top: parent.top - topMargin: gripSize / 2 + topMargin: (gripSize / 2) + 5 left: parent.left right: parent.right } + onValueChanged: slider2.value = slider.value + } + + // bottomgrip + Curtain { + id: slider2 + increment: 0.0 + anchors { + bottom: parent.bottom + bottomMargin: (gripSize / 2) + 5 + left: parent.left + right: parent.right + } + imageSource: "qrc:/images/Triangle_bottom.png" + onValueChanged: slider.value = slider2.value } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml index 4e3adc3e2..1e2077246 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml @@ -44,7 +44,7 @@ import QtQuick 2.0 Effect { parameters: ListModel { ListElement { - name: "grid spacing" + name: "Grid Spacing" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml index 5e37c70ce..85f2abc7d 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml @@ -44,7 +44,7 @@ import QtQuick 2.0 Effect { parameters: ListModel { ListElement { - name: "threshold" + name: "Threshold" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml index 00fab0448..f0cad5288 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml @@ -49,7 +49,7 @@ Item { property real dividerValue: 0.5 property ListModel parameters: ListModel { ListElement { - name: "radius" + name: "Radius" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml index f3650419c..80c7ccaed 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml @@ -44,11 +44,11 @@ import QtQuick 2.0 Effect { parameters: ListModel { ListElement { - name: "hue" + name: "Hue" value: 0.5 } ListElement { - name: "width" + name: "Width" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml index d93e72c9e..3fd35eaae 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml @@ -46,11 +46,11 @@ Effect { divider: false parameters: ListModel { ListElement { - name: "radius" + name: "Radius" value: 0.5 } ListElement { - name: "diffraction" + name: "Diffraction" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml index e4fc1f78f..c035b9b62 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml @@ -45,7 +45,7 @@ Effect { divider: false parameters: ListModel { ListElement { - name: "extent" + name: "Extent" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml index 002a74a46..7a0f21984 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml @@ -44,7 +44,7 @@ import QtQuick 2.0 Effect { parameters: ListModel { ListElement { - name: "granularity" + name: "Granularity" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml index bda473764..084b28c17 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml @@ -44,7 +44,7 @@ import QtQuick 2.0 Effect { parameters: ListModel { ListElement { - name: "gamma" + name: "Gamma" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml index 7932b4c12..e0a2b0227 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml @@ -44,11 +44,11 @@ import QtQuick 2.0 Effect { parameters: ListModel { ListElement { - name: "amplitude" + name: "Amplitude" value: 0.5 } ListElement { - name: "frequency" + name: "Frequency" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionList.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionList.qml new file mode 100644 index 000000000..fa92bb7ca --- /dev/null +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionList.qml @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Mobility Components. +** +** $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$ +** +****************************************************************************/ + +import QtQuick 2.0 + +ListModel { + id: sources + ListElement { name: "No effect"; source: "EffectPassThrough.qml" } + ListElement { name: "Billboard"; source: "EffectBillboard.qml" } + ListElement { name: "Black & white"; source: "EffectBlackAndWhite.qml" } + ListElement { name: "Blur"; source: "EffectGaussianBlur.qml" } + ListElement { name: "Edge detection"; source: "EffectSobelEdgeDetection1.qml" } + ListElement { name: "Emboss"; source: "EffectEmboss.qml" } + ListElement { name: "Glow"; source: "EffectGlow.qml" } + ListElement { name: "Isolate"; source: "EffectIsolate.qml" } + //ListElement { name: "Magnify"; source: "EffectMagnify.qml" } + ListElement { name: "Page curl"; source: "EffectPageCurl.qml" } + ListElement { name: "Pixelate"; source: "EffectPixelate.qml" } + ListElement { name: "Posterize"; source: "EffectPosterize.qml" } + ListElement { name: "Ripple"; source: "EffectRipple.qml" } + ListElement { name: "Sepia"; source: "EffectSepia.qml" } + ListElement { name: "Sharpen"; source: "EffectSharpen.qml" } + ListElement { name: "Shockwave"; source: "EffectShockwave.qml" } + ListElement { name: "Tilt shift"; source: "EffectTiltShift.qml" } + ListElement { name: "Toon"; source: "EffectToon.qml" } + ListElement { name: "Warhol"; source: "EffectWarhol.qml" } + ListElement { name: "Wobble"; source: "EffectWobble.qml" } + ListElement { name: "Vignette"; source: "EffectVignette.qml" } +} diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionPanel.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionPanel.qml deleted file mode 100644 index 948a4e888..000000000 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSelectionPanel.qml +++ /dev/null @@ -1,154 +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 Mobility Components. -** -** $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$ -** -****************************************************************************/ -import QtQuick 2.0 - -Rectangle { - id: root - property int itemHeight: 25 - property string effectSource: "" - - signal clicked - - QtObject { - id: d - property Item selectedItem - } - - ListModel { - id: sources - ListElement { name: "No effect"; source: "EffectPassThrough.qml" } - ListElement { name: "Billboard"; source: "EffectBillboard.qml" } - ListElement { name: "Black & white"; source: "EffectBlackAndWhite.qml" } - ListElement { name: "Blur"; source: "EffectGaussianBlur.qml" } - ListElement { name: "Edge detection"; source: "EffectSobelEdgeDetection1.qml" } - //ListElement { name: "Edge detection (Sobel, #2)"; source: "EffectSobelEdgeDetection2.qml" } - ListElement { name: "Emboss"; source: "EffectEmboss.qml" } - ListElement { name: "Glow"; source: "EffectGlow.qml" } - ListElement { name: "Isolate"; source: "EffectIsolate.qml" } - ListElement { name: "Magnify"; source: "EffectMagnify.qml" } - ListElement { name: "Page curl"; source: "EffectPageCurl.qml" } - ListElement { name: "Pixelate"; source: "EffectPixelate.qml" } - ListElement { name: "Posterize"; source: "EffectPosterize.qml" } - ListElement { name: "Ripple"; source: "EffectRipple.qml" } - ListElement { name: "Sepia"; source: "EffectSepia.qml" } - ListElement { name: "Sharpen"; source: "EffectSharpen.qml" } - ListElement { name: "Shockwave"; source: "EffectShockwave.qml" } - ListElement { name: "Tilt shift"; source: "EffectTiltShift.qml" } - ListElement { name: "Toon"; source: "EffectToon.qml" } - ListElement { name: "Warhol"; source: "EffectWarhol.qml" } - ListElement { name: "Wobble"; source: "EffectWobble.qml" } - ListElement { name: "Vignette"; source: "EffectVignette.qml" } - } - - Component { - id: sourceDelegate - Item { - id: sourceDelegateItem - width: root.width - height: itemHeight - - Button { - id: sourceSelectorItem - anchors.centerIn: parent - width: 0.9 * parent.width - height: 0.8 * itemHeight - text: name - onClicked: { - if (d.selectedItem) - d.selectedItem.state = "baseState" - d.selectedItem = sourceDelegateItem - d.selectedItem.state = "selected" - effectSource = source - root.clicked() - } - } - - states: [ - State { - name: "selected" - PropertyChanges { - target: sourceSelectorItem - bgColor: "#ff8888" - } - } - ] - - Component.onCompleted: { - if (name == "No effect") { - state = "selected" - d.selectedItem = sourceDelegateItem - } - } - - transitions: [ - Transition { - from: "*" - to: "*" - ColorAnimation { - properties: "color" - easing.type: Easing.OutQuart - duration: 500 - } - } - ] - } - } - - Flickable { - anchors.fill: parent - contentHeight: (itemHeight * sources.count) + layout.anchors.topMargin + layout.spacing - clip: true - - Column { - id: layout - - anchors { - fill: parent - topMargin: 10 - } - - Repeater { - model: sources - delegate: sourceDelegate - } - } - } -} diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml index 25215980d..f59544dc9 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml @@ -44,7 +44,7 @@ import QtQuick 2.0 Effect { parameters: ListModel { ListElement { - name: "sharpness" + name: "Sharpness" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml index 0e1b1785f..746445b46 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml @@ -45,7 +45,7 @@ Effect { id: root parameters: ListModel { ListElement { - name: "amplitude" + name: "Amplitude" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml index 6724a8449..7b03dbfdb 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml @@ -44,7 +44,7 @@ import QtQuick 2.0 Effect { parameters: ListModel { ListElement { - name: "threshold" + name: "Threshold" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection2.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection2.qml deleted file mode 100644 index 33336537f..000000000 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection2.qml +++ /dev/null @@ -1,56 +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 Mobility Components. -** -** $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$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Effect { - parameters: ListModel { - ListElement { - name: "threshold" - value: 0.5 - } - } - - // Transform slider values, and bind result to shader uniforms - property real weight: parameters.get(0).value - - fragmentShaderFilename: "sobeledgedetection2.fsh" -} diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectToon.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectToon.qml index ff985e563..ecba40623 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectToon.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectToon.qml @@ -44,7 +44,7 @@ import QtQuick 2.0 Effect { parameters: ListModel { ListElement { - name: "threshold" + name: "Threshold" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWobble.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWobble.qml index 97e7c061c..aa07c1a68 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWobble.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectWobble.qml @@ -44,7 +44,7 @@ import QtQuick 2.0 Effect { parameters: ListModel { ListElement { - name: "amplitude" + name: "Amplitude" value: 0.5 } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml index 7c8610361..c75b6f255 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileBrowser.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Mobility Components. @@ -39,12 +39,13 @@ ** ****************************************************************************/ -import QtQuick 2.0 -import Qt.labs.folderlistmodel 2.0 +import QtQuick 2.1 +import Qt.labs.folderlistmodel 2.1 Rectangle { id: fileBrowser color: "transparent" + z: 4 property string folder property bool shown: loader.sourceComponent @@ -75,12 +76,12 @@ Rectangle { Rectangle { id: root - color: "white" + color: "black" property bool showFocusHighlight: false property variant folders: folders1 property variant view: view1 property alias folder: folders1.folder - property color textColor: "black" + property color textColor: "white" FolderListModel { id: folders1 @@ -112,7 +113,7 @@ Rectangle { fileBrowser.selectFile(path) } width: root.width - height: 52 + height: itemHeight color: "transparent" Rectangle { @@ -126,10 +127,12 @@ Rectangle { } Item { - width: 48; height: 48 + width: itemHeight; height: itemHeight Image { - source: "qrc:/images/folder.png" - anchors.centerIn: parent + source: "qrc:/images/icon_Folder.png" + fillMode: Image.PreserveAspectFit + anchors.fill: parent + anchors.margins: scaledMargin visible: folders.isFolder(index) } } @@ -138,8 +141,8 @@ Rectangle { id: nameText anchors.fill: parent; verticalAlignment: Text.AlignVCenter text: fileName - anchors.leftMargin: 54 - font.pixelSize: 32 + anchors.leftMargin: itemHeight + scaledMargin + font.pixelSize: fontSize color: (wrapper.ListView.isCurrentItem && root.showFocusHighlight) ? palette.highlightedText : textColor elide: Text.ElideRight } @@ -262,56 +265,45 @@ Rectangle { Keys.onPressed: root.keyPressed(event.key) } - Rectangle { + Button { id: cancelButton - width: 100 - height: titleBar.height - 7 - color: "black" - anchors { bottom: parent.bottom; horizontalCenter: parent.horizontalCenter } - - Text { - anchors { fill: parent; margins: 4 } - text: "Cancel" - color: "white" - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: 20 - } - - MouseArea { - anchors.fill: parent - onClicked: fileBrowser.selectFile("") - } + width: itemWidth + height: itemHeight + color: "#353535" + anchors { bottom: parent.bottom; right: parent.right; margins: 5 * scaledMargin } + text: "Cancel" + horizontalAlign: Text.AlignHCenter + onClicked: fileBrowser.selectFile("") } Keys.onPressed: { root.keyPressed(event.key); - if (event.key == Qt.Key_Return || event.key == Qt.Key_Select || event.key == Qt.Key_Right) { + if (event.key === Qt.Key_Return || event.key === Qt.Key_Select || event.key === Qt.Key_Right) { view.currentItem.launch(); event.accepted = true; - } else if (event.key == Qt.Key_Left) { + } else if (event.key === Qt.Key_Left) { up(); } } - BorderImage { - source: "qrc:/images/titlebar.sci"; + // titlebar + Rectangle { + color: "black" width: parent.width; - height: 52 - y: -7 + height: itemHeight id: titleBar Rectangle { id: upButton - width: 48 - height: titleBar.height - 7 + width: titleBar.height + height: titleBar.height color: "transparent" - Image { anchors.centerIn: parent; source: "qrc:/images/up.png" } - MouseArea { id: upRegion; anchors.centerIn: parent - width: 56 - height: 56 - onClicked: up() - } + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + anchors.margins: scaledMargin + + Image { anchors.fill: parent; anchors.margins: scaledMargin; source: "qrc:/images/icon_BackArrow.png" } + MouseArea { id: upRegion; anchors.fill: parent; onClicked: up() } states: [ State { name: "pressed" @@ -321,23 +313,23 @@ Rectangle { ] } - Rectangle { - color: "gray" - x: 48 - width: 1 - height: 44 - } - Text { anchors.left: upButton.right; anchors.right: parent.right; height: parent.height - anchors.leftMargin: 4; anchors.rightMargin: 4 + anchors.leftMargin: 10; anchors.rightMargin: 4 text: folders.folder color: "white" - elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter - font.pixelSize: 32 + elide: Text.ElideLeft; horizontalAlignment: Text.AlignLeft; verticalAlignment: Text.AlignVCenter + font.pixelSize: fontSize } } + Rectangle { + color: "#353535" + width: parent.width + height: 1 + anchors.top: titleBar.bottom + } + function down(path) { if (folders == folders1) { view = view2 diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml index 716f4165b..b0542cb80 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Mobility Components. @@ -39,56 +39,95 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick 2.1 Rectangle { id: root - color: "white" - property int buttonHeight: 35 - property int topMargin: 0 - + color: "#151515" + signal openCamera signal openImage signal openVideo - signal openCamera signal close - Rectangle { - anchors { - top: parent.top; - topMargin: root.topMargin - bottom: parent.bottom; - horizontalCenter: parent.horizontalCenter - } - width: 0.9 * parent.width - color: "transparent" - - Column { - anchors.fill: parent - spacing: 5 - Button { - text: "Open image" - height: buttonHeight - width: parent.width - onClicked: root.openImage() - } - Button { - text: "Open video" - height: buttonHeight - width: parent.width - onClicked: root.openVideo() + Column { + anchors.fill: parent + spacing: 10 + Rectangle { + height: itemHeight + width: itemHeight + color: "transparent" + anchors.right: parent.right + Image { + id: menu + source: "qrc:///images/icon_Menu.png" + anchors { + right: parent.right + top: parent.top + margins: scaledMargin + } } - Button { - text: "Start camera" - height: buttonHeight - width: parent.width - onClicked: root.openCamera() - } - Button { - text: "Reset" - height: buttonHeight - width: parent.width - onClicked: root.close() + MouseArea { + anchors.fill: parent + onClicked: fileOpen.state == "expanded" ? fileOpen.state = "collapsed" : fileOpen.state = "expanded" } } + Rectangle { + width: 0.9 * parent.width + height: 1 + color: "#353535" + anchors.left: parent.left + } + Button { + text: "Start camera" + height: itemHeight + width: parent.width + onClicked: root.openCamera() + active: fileOpen.state == "expanded" + } + Rectangle { + width: 0.9 * parent.width + height: 1 + color: "#353535" + anchors.left: parent.left + } + Button { + text: "Open image" + height: itemHeight + width: parent.width + onClicked: root.openImage() + active: fileOpen.state == "expanded" + } + Rectangle { + width: 0.9 * parent.width + height: 1 + color: "#353535" + anchors.left: parent.left + } + Button { + text: "Open video" + height: itemHeight + width: parent.width + onClicked: root.openVideo() + active: fileOpen.state == "expanded" + } + Rectangle { + width: 0.9 * parent.width + height: 1 + color: "#353535" + anchors.left: parent.left + } + Button { + text: "Reset" + height: itemHeight + width: parent.width + onClicked: root.close() + active: fileOpen.state == "expanded" + } + Rectangle { + width: 0.9 * parent.width + height: 1 + color: "#353535" + anchors.left: parent.left + } } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml new file mode 100644 index 000000000..5ec13750f --- /dev/null +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml @@ -0,0 +1,287 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Mobility Components. +** +** $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$ +** +****************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Window 2.1 + +Rectangle { + id: root + color: "black" + property string fileName + property alias volume: content.volume + property bool perfMonitorsLogging: false + property bool perfMonitorsVisible: false + property int pixDens: Math.ceil(Screen.pixelDensity) + property int itemWidth: 25 * pixDens + property int itemHeight: 10 * pixDens + property int windowWidth: Screen.desktopAvailableWidth + property int windowHeight: Screen.desktopAvailableHeight + property int scaledMargin: 2 * pixDens + property int fontSize: 5 * pixDens + + QtObject { + id: d + property real gripSize: 20 + } + + Content { + id: content + color: "transparent" + anchors { + top: parent.top + left: parent.left + right: parent.right + bottom: parameterPanel.top + margins: scaledMargin + leftMargin: scaledMargin + itemHeight + } + gripSize: d.gripSize + } + + ParameterPanel { + id: parameterPanel + anchors { + left: parent.left + right: listview.left + bottom: parent.bottom + margins: scaledMargin + leftMargin: scaledMargin + itemHeight + } + gripSize: d.gripSize + height: root.itemHeight * 2.5 + width: root.itemWidth * 3 + + } + + + Button { + id: effectName + anchors { + right: parent.right + bottom: perfHolder.top + top: content.bottom + margins: scaledMargin + } + + text: "No effect" + width: itemWidth * 2 + onClicked: { + effectName.visible = false + listview.visible = true + } + color: "#303030" + } + + + ListView { + id: listview + width: itemWidth * 2 + anchors { + right: parent.right + bottom: perfHolder.top + top: parent.top + margins: scaledMargin + } + visible: false + + model: EffectSelectionList {} + delegate: effectDelegate + + highlight: Rectangle { color: "#14aaff"; radius: 5 } + highlightFollowsCurrentItem: true + highlightRangeMode: ListView.StrictlyEnforceRange + clip: true + focus: true + + Component { + id: effectDelegate + Button { + text: name + width: itemWidth * 2 + onClicked: { + content.effectSource = source + listview.visible = false + effectName.text = name + effectName.visible = true + parameterPanel.model = content.effect.parameters + + } + } + } + } + + Rectangle { + id: perfHolder + color: "transparent" + anchors { + right: parent.right + bottom: parent.bottom + margins: scaledMargin + } + height: root.itemHeight * 1.5 + width: root.itemWidth + + Loader { + id: performanceLoader + function init() { + console.log("[qmlvideofx] performanceLoader.init logging " + root.perfMonitorsLogging + " visible " + root.perfMonitorsVisible) + var enabled = root.perfMonitorsLogging || root.perfMonitorsVisible + source = enabled ? "../performancemonitor/PerformanceItem.qml" : "" + } + onLoaded: { + item.parent = perfHolder + item.anchors.top = perfHolder.top + item.anchors.bottom = perfHolder.bottom + item.anchors.left = perfHolder.left + item.anchors.right = perfHolder.right + item.logging = root.perfMonitorsLogging + item.displayed = root.perfMonitorsVisible + item.init() + } + } + } + + FileOpen { + id: fileOpen + state: "collapsed" + anchors { + left: parent.left + top: parent.top + bottom: parent.bottom + margins: scaledMargin + } + width: itemHeight + scaledMargin + z: 2 + opacity: 0.9 + + states: [ + State { + name: "expanded" + PropertyChanges { + target: fileOpen + width: itemWidth * 1.5 + opacity: 0.8 + } + }, + State { + name: "collapsed" + PropertyChanges { + target: fileOpen + width: itemHeight + scaledMargin + opacity: 0.9 + } + } + ] + + transitions: [ + Transition { + NumberAnimation { target: fileOpen; property: "width"; duration: 400 } + NumberAnimation { target: fileOpen; property: "opacity"; duration: 400 } + } + ] + } + + FileBrowser { + id: imageFileBrowser + anchors.fill: root + Component.onCompleted: fileSelected.connect(content.openImage) + } + + FileBrowser { + id: videoFileBrowser + anchors.fill: root + Component.onCompleted: fileSelected.connect(content.openVideo) + } + + Component.onCompleted: { + fileOpen.openImage.connect(openImage) + fileOpen.openVideo.connect(openVideo) + fileOpen.openCamera.connect(openCamera) + fileOpen.close.connect(close) + } + + function init() { + if (Qt.platform.os === "linux" || Qt.platform.os === "windows" || Qt.platform.os === "osx" || Qt.platform.os === "unix") { + if (Screen.desktopAvailableWidth > 1280) { + windowWidth = 1280 + } + if (Screen.desktopAvailableHeight > 720) { + windowHeight = 720 + } + } + + height = windowHeight + width = windowWidth + + console.log("[qmlvideofx] root.init") + console.log("Height: ", Screen.desktopAvailableHeight) + console.log("Width: ", Screen.desktopAvailableWidth) + console.log("Pixels per mm: ", Math.ceil(Screen.pixelDensity)) + console.log("Orientation: ", Screen.orientation) + imageFileBrowser.folder = imagePath + videoFileBrowser.folder = videoPath + content.init() + performanceLoader.init() + if (fileName != "") + content.openVideo(fileName) + } + + function qmlFramePainted() { + if (performanceLoader.item) + performanceLoader.item.qmlFramePainted() + } + + function openImage() { + imageFileBrowser.show() + } + + function openVideo() { + videoFileBrowser.show() + } + + function openCamera() { + content.openCamera() + } + + function close() { + content.init() + } +} diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml index 83c0d4c8d..aa4315c9d 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml @@ -47,17 +47,12 @@ Rectangle { height: view.model.count * sliderHeight property color lineColor: "black" property real gripSize: 25 - property real spacing: 10 - property real sliderHeight: 40 + property real spacing: 20 + property real sliderHeight: 60 property ListModel model: ListModel { } - Rectangle { - anchors.fill: parent - color: "black" - opacity: 0.5 - radius: 10 - } + anchors.topMargin: 10 Component { id: editDelegate @@ -77,10 +72,10 @@ Rectangle { bottom: parent.bottom left: parent.left } - font.pixelSize: 0.5 * parent.height + font.pixelSize: fontSize horizontalAlignment: Text.AlignRight verticalAlignment: Text.AlignVCenter - width: 150 + width: 8 * fontSize } Slider { diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Slider.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Slider.qml index c12537022..97b52c87b 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Slider.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Slider.qml @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Mobility Components. @@ -39,91 +39,84 @@ ** ****************************************************************************/ -import QtQuick 2.0 +import QtQuick 2.1 Rectangle { id: root color: "transparent" radius: 5 property alias value: grip.value - property color fillColor: "white" - property color lineColor: "black" - property color gripColor: "white" - property real gripSize: 20 + property color fillColor: "#14aaff" + property real gripSize: 40 property real gripTolerance: 3.0 property real increment: 0.1 property bool enabled: true Rectangle { - anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter } - height: 3 - color: displayedColor(root.lineColor) + id: slider + anchors { + left: parent.left + right: parent.right + verticalCenter: parent.verticalCenter + } + height: 10 + color: "transparent" + BorderImage { + id: sliderbarimage + source: "qrc:/images/Slider_bar.png" + anchors { fill: parent; margins: 1 } + border.right: 5 + border.left: 5 + } Rectangle { - anchors { fill: parent; margins: 1 } + height: parent.height -2 + anchors.left: parent.left + anchors.right: grip.horizontalCenter color: root.fillColor + radius: 3 + border.width: 1 + border.color: Qt.darker(color, 1.3) + opacity: 0.8 } - } + Rectangle { + id: grip + property real value: 0.5 + x: (value * parent.width) - width/2 + anchors.verticalCenter: parent.verticalCenter + width: root.gripTolerance * root.gripSize + height: width + radius: width/2 + color: "transparent" - MouseArea { - anchors.fill: parent - enabled: root.enabled - onClicked: { - if (parent.width) { - var newValue = mouse.x / parent.width - if (Math.abs(newValue - parent.value) > parent.increment) { - if (newValue > parent.value) - parent.value = Math.min(1.0, parent.value + parent.increment) - else - parent.value = Math.max(0.0, parent.value - parent.increment) - } + Image { + id: sliderhandleimage + source: "qrc:/images/Slider_handle.png" + anchors.centerIn: parent } - } - } - - Rectangle { - id: grip - property real value: 0.5 - x: (value * parent.width) - width/2 - anchors.verticalCenter: parent.verticalCenter - width: root.gripTolerance * root.gripSize - height: width - radius: width/2 - color: "transparent" - MouseArea { - id: mouseArea - enabled: root.enabled - anchors.fill: parent - drag { - target: grip - axis: Drag.XAxis - minimumX: -parent.width/2 - maximumX: root.width - parent.width/2 - } - onPositionChanged: { - if (drag.active) + MouseArea { + id: mouseArea + enabled: root.enabled + anchors.fill: parent + drag { + target: grip + axis: Drag.XAxis + minimumX: -parent.width/2 + maximumX: root.width - parent.width/2 + } + onPositionChanged: { + if (drag.active) + updatePosition() + } + onReleased: { updatePosition() - } - onReleased: { - updatePosition() - } - function updatePosition() { - value = (grip.x + grip.width/2) / grip.parent.width + } + function updatePosition() { + value = (grip.x + grip.width/2) / slider.width + } } } - Rectangle { - anchors.centerIn: parent - width: root.gripSize - height: width - radius: width/2 - color: root.gripColor - } - } - - function displayedColor(c) { - var tint = Qt.rgba(c.r, c.g, c.b, 0.25) - return enabled ? c : Qt.tint(c, tint) } } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-largescreen.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-largescreen.qml deleted file mode 100644 index 63a0a01ac..000000000 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-largescreen.qml +++ /dev/null @@ -1,186 +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 Mobility Components. -** -** $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$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Rectangle { - id: root - width: 900 - height: 600 - color: "grey" - property string fileName - property alias volume: content.volume - property bool perfMonitorsLogging: false - property bool perfMonitorsVisible: false - - QtObject { - id: d - property real gripSize: 20 - } - - Rectangle { - id: inner - anchors.fill: parent - color: "grey" - - Content { - id: content - anchors { - top: parent.top - bottom: parent.bottom - left: parent.left - right: effectSelectionPanel.left - margins: 5 - } - gripSize: d.gripSize - width: 600 - height: 600 - } - - Loader { - id: performanceLoader - function init() { - console.log("[qmlvideofx] performanceLoader.init logging " + root.perfMonitorsLogging + " visible " + root.perfMonitorsVisible) - var enabled = root.perfMonitorsLogging || root.perfMonitorsVisible - source = enabled ? "../performancemonitor/PerformanceItem.qml" : "" - } - onLoaded: { - item.parent = content - item.anchors.top = content.top - item.anchors.left = content.left - item.anchors.right = content.right - item.logging = root.perfMonitorsLogging - item.displayed = root.perfMonitorsVisible - item.init() - } - } - - ParameterPanel { - id: parameterPanel - anchors { - left: parent.left - bottom: parent.bottom - right: effectSelectionPanel.left - margins: 20 - } - gripSize: d.gripSize - } - - EffectSelectionPanel { - id: effectSelectionPanel - anchors { - top: parent.top - bottom: fileOpen.top - right: parent.right - margins: 5 - } - width: 300 - itemHeight: 40 - onEffectSourceChanged: { - content.effectSource = effectSource - parameterPanel.model = content.effect.parameters - } - } - - FileOpen { - id: fileOpen - anchors { - right: parent.right - bottom: parent.bottom - margins: 5 - } - width: effectSelectionPanel.width - height: 165 - buttonHeight: 32 - topMargin: 10 - } - } - - FileBrowser { - id: imageFileBrowser - anchors.fill: root - Component.onCompleted: fileSelected.connect(content.openImage) - } - - FileBrowser { - id: videoFileBrowser - anchors.fill: root - Component.onCompleted: fileSelected.connect(content.openVideo) - } - - Component.onCompleted: { - fileOpen.openImage.connect(openImage) - fileOpen.openVideo.connect(openVideo) - fileOpen.openCamera.connect(openCamera) - fileOpen.close.connect(close) - } - - function init() { - console.log("[qmlvideofx] main.init") - imageFileBrowser.folder = imagePath - videoFileBrowser.folder = videoPath - content.init() - performanceLoader.init() - if (fileName != "") - content.openVideo(fileName) - } - - function qmlFramePainted() { - if (performanceLoader.item) - performanceLoader.item.qmlFramePainted() - } - - function openImage() { - imageFileBrowser.show() - } - - function openVideo() { - videoFileBrowser.show() - } - - function openCamera() { - content.openCamera() - } - - function close() { - content.openImage("qrc:/images/qt-logo.png") - } -} diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-smallscreen.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-smallscreen.qml deleted file mode 100644 index f715dc8c1..000000000 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/main-smallscreen.qml +++ /dev/null @@ -1,408 +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 Mobility Components. -** -** $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$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Rectangle { - id: root - width: 640 - height: 360 - color: "grey" - property string fileName - property alias volume: content.volume - property bool perfMonitorsLogging: false - property bool perfMonitorsVisible: false - - QtObject { - id: d - property bool dialogShown: (fileOpenContainer.state == "shown" || - effectSelectionPanel.state == "shown" || - videoFileBrowser.shown || - imageFileBrowser.shown) - property real gripSize: 40 - } - - // Create ScreenSaver element via Loader, so this app will still run if the - // SystemInfo module is not available - Loader { - source: "DisableScreenSaver.qml" - } - - Loader { - id: performanceLoader - - Connections { - target: d - onDialogShownChanged: - if (performanceLoader.item) - performanceLoader.item.enabled = !d.dialogShown - ignoreUnknownSignals: true - } - - function init() { - console.log("[qmlvideofx] performanceLoader.init logging " + root.perfMonitorsLogging + " visible " + root.perfMonitorsVisible) - var enabled = root.perfMonitorsLogging || root.perfMonitorsVisible - source = enabled ? "../performancemonitor/PerformanceItem.qml" : "" - } - - onLoaded: { - item.parent = root - item.anchors.top = root.top - item.anchors.left = root.left - item.logging = root.perfMonitorsLogging - item.displayed = root.perfMonitorsVisible - item.init() - } - } - - Rectangle { - id: inner - anchors.fill: parent - color: "grey" - - Content { - id: content - anchors.fill: parent - gripSize: d.gripSize - onVideoFramePainted: performanceLoader.item.videoFramePainted() - } - - ParameterPanel { - id: parameterPanel - anchors { - left: parent.left; - right: parent.right; - margins: 10 - } - y: parent.height - gripSize: d.gripSize - - states: [ - State { - name: "shown" - PropertyChanges { - target: parameterPanel - y: parent.height - (parameterPanel.height + 10) - } - } - ] - - transitions: [ - Transition { - from: "*" - to: "*" - NumberAnimation { - properties: "y" - easing.type: Easing.OutQuart - duration: 500 - } - } - ] - - state: (enabled && !d.dialogShown) ? "shown" : "baseState" - } - - EffectSelectionPanel { - id: effectSelectionPanel - anchors { - top: parent.top; - bottom: parameterPanel.top; - margins: 10 - } - x: parent.width - width: parent.width - 40 - opacity: 0.75 - radius: 20 - itemHeight: 50 - - states: [ - State { - name: "shown" - PropertyChanges { - target: effectSelectionPanel - x: 20 - } - } - ] - - transitions: [ - Transition { - from: "*" - to: "*" - NumberAnimation { - properties: "x" - easing.type: Easing.OutQuart - duration: 500 - } - } - ] - - onEffectSourceChanged: { - content.effectSource = effectSource - if (content.effect.parameters.count) { - parameterPanel.model = content.effect.parameters - parameterPanel.enabled = true - } else { - parameterPanel.enabled = false - } - } - - onClicked: state = "baseState" - } - - Rectangle { - id: fileOpenContainer - anchors { - top: parent.top - bottom: parameterPanel.top - margins: 10 - } - x: -width - width: parent.width - 40 - color: "transparent" - - Column { - anchors.fill: parent - - FileOpen { - id: fileOpen - color: "transparent" - width: parent.width - height: 200 - opacity: 0.75 - radius: 20 - buttonHeight: 40 - } - - MouseArea { - width: parent.width - height: 250 - onClicked: fileOpenContainer.state = "baseState" - } - } - - states: [ - State { - name: "shown" - PropertyChanges { - target: fileOpenContainer - x: 20 - } - } - ] - - transitions: [ - Transition { - from: "*" - to: "*" - NumberAnimation { - properties: "x" - easing.type: Easing.OutQuart - duration: 500 - } - } - ] - } - - Rectangle { - id: splashScreen - anchors { - horizontalCenter: parent.horizontalCenter - verticalCenter: parent.verticalCenter - } - width: 300 - height: 200 - radius: 0.1 * height - color: "white" - opacity: 0.9 - border { color: "black"; width: 2 } - - Text { - anchors { - fill: parent - margins: 5 - } - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.pixelSize: 24 - text: "Tap on left side to switch between sources.\n\nTap on right side to switch between effects." - wrapMode: Text.WordWrap - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = "hidden" - } - - states: [ - State { - name: "hidden" - PropertyChanges { - target: splashScreen - opacity: 0.0 - } - } - ] - - transitions: [ - Transition { - from: "*" - to: "*" - NumberAnimation { - properties: "opacity" - easing.type: Easing.OutQuart - duration: 500 - } - } - ] - } - - HintedMouseArea { - id: fileOpenMouseArea - anchors { - left: parent.left; - top: parent.top; - bottom: parameterPanel.top; - topMargin: 75 - } - width: 100 - onClicked: { - fileOpenMouseArea.hintEnabled = false - effectSelectionPanelMouseArea.hintEnabled = false - splashScreen.state = "hidden" - fileOpenContainer.state = "shown" - } - enabled: !d.dialogShown - } - - HintedMouseArea { - id: effectSelectionPanelMouseArea - anchors { - right: parent.right; - top: parent.top; - bottom: parameterPanel.top; - topMargin: 75 - } - width: 100 - onClicked: { - fileOpenMouseArea.hintEnabled = false - effectSelectionPanelMouseArea.hintEnabled = false - splashScreen.state = "hidden" - effectSelectionPanel.state = "shown" - } - enabled: !d.dialogShown - } - - Image { - source: "qrc:/images/close.png" - - anchors { - top: parent.top - right: parent.right - margins: 5 - } - - MouseArea { - anchors.fill: parent - onClicked: Qt.quit() - } - } - } - - Component.onCompleted: { - fileOpen.openImage.connect(openImage) - fileOpen.openVideo.connect(openVideo) - fileOpen.openCamera.connect(openCamera) - fileOpen.close.connect(close) - } - - FileBrowser { - id: imageFileBrowser - anchors.fill: root - Component.onCompleted: fileSelected.connect(content.openImage) - } - - FileBrowser { - id: videoFileBrowser - anchors.fill: root - Component.onCompleted: fileSelected.connect(content.openVideo) - } - - // Called from main() once root properties have been set - function init() { - console.log("[qmlvideofx] main.init") - imageFileBrowser.folder = imagePath - videoFileBrowser.folder = videoPath - content.init() - performanceLoader.init() - if (fileName != "") { - fileOpenMouseArea.hintEnabled = false - effectSelectionPanelMouseArea.hintEnabled = false - splashScreen.state = "hidden" - content.openVideo(fileName) - } - } - - function qmlFramePainted() { - if (performanceLoader.item) - performanceLoader.item.qmlFramePainted() - } - - function openImage() { - fileOpenContainer.state = "baseState" - imageFileBrowser.show() - } - - function openVideo() { - fileOpenContainer.state = "baseState" - videoFileBrowser.show() - } - - function openCamera() { - fileOpenContainer.state = "baseState" - content.openCamera() - } - - function close() { - fileOpenContainer.state = "baseState" - content.openImage("qrc:/images/qt-logo.png") - } -} diff --git a/examples/multimedia/video/qmlvideofx/qmlvideofx.pro b/examples/multimedia/video/qmlvideofx/qmlvideofx.pro index 563444903..e9633954c 100644 --- a/examples/multimedia/video/qmlvideofx/qmlvideofx.pro +++ b/examples/multimedia/video/qmlvideofx/qmlvideofx.pro @@ -10,10 +10,12 @@ RESOURCES += qmlvideofx.qrc include($$PWD/../snippets/performancemonitor/performancemonitordeclarative.pri) -maemo6: { - DEFINES += SMALL_SCREEN_LAYOUT - DEFINES += SMALL_SCREEN_PHYSICAL -} - target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/video/qmlvideofx INSTALLS += target + +ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android + +OTHER_FILES += \ + android/AndroidManifest.xml + +QMAKE_INFO_PLIST = Info.plist diff --git a/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc b/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc index 93cb4f1f5..e7a361246 100644 --- a/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc +++ b/examples/multimedia/video/qmlvideofx/qmlvideofx.qrc @@ -1,10 +1,5 @@ - images/close.png - images/folder.png - images/titlebar.png - images/titlebar.sci - images/up.png images/qt-logo.png qml/qmlvideofx/Button.qml qml/qmlvideofx/Content.qml @@ -26,12 +21,10 @@ qml/qmlvideofx/EffectPixelate.qml qml/qmlvideofx/EffectPosterize.qml qml/qmlvideofx/EffectRipple.qml - qml/qmlvideofx/EffectSelectionPanel.qml qml/qmlvideofx/EffectSepia.qml qml/qmlvideofx/EffectSharpen.qml qml/qmlvideofx/EffectShockwave.qml qml/qmlvideofx/EffectSobelEdgeDetection1.qml - qml/qmlvideofx/EffectSobelEdgeDetection2.qml qml/qmlvideofx/EffectTiltShift.qml qml/qmlvideofx/EffectToon.qml qml/qmlvideofx/EffectVignette.qml @@ -40,8 +33,6 @@ qml/qmlvideofx/FileBrowser.qml qml/qmlvideofx/FileOpen.qml qml/qmlvideofx/HintedMouseArea.qml - qml/qmlvideofx/main-largescreen.qml - qml/qmlvideofx/main-smallscreen.qml qml/qmlvideofx/ParameterPanel.qml qml/qmlvideofx/Slider.qml shaders/billboard.fsh @@ -61,11 +52,21 @@ shaders/sharpen.fsh shaders/shockwave.fsh shaders/sobeledgedetection1.fsh - shaders/sobeledgedetection2.fsh shaders/tiltshift.fsh shaders/toon.fsh shaders/vignette.fsh shaders/warhol.fsh shaders/wobble.fsh + images/Slider_handle.png + images/Slider_bar.png + qml/qmlvideofx/Curtain.qml + images/Triangle_bottom.png + images/Triangle_Top.png + images/Dropdown_arrows.png + images/icon_Folder.png + images/icon_BackArrow.png + qml/qmlvideofx/Main.qml + images/icon_Menu.png + qml/qmlvideofx/EffectSelectionList.qml diff --git a/examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection2.fsh b/examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection2.fsh deleted file mode 100644 index 039a567d2..000000000 --- a/examples/multimedia/video/qmlvideofx/shaders/sobeledgedetection2.fsh +++ /dev/null @@ -1,77 +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 Mobility Components. -** -** $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$ -** -****************************************************************************/ - -// Based on http://rastergrid.com/blog/downloads/frei-chen-edge-detector/ - -#version 130 -uniform sampler2D source; -uniform float dividerValue; -uniform float weight; -mat3 G[2] = mat3[]( - mat3( 1.0, 2.0, 1.0, 0.0, 0.0, 0.0, -1.0, -2.0, -1.0 ), - mat3( 1.0, 0.0, -1.0, 2.0, 0.0, -2.0, 1.0, 0.0, -1.0 ) -); -uniform lowp float qt_Opacity; -in vec2 qt_TexCoord0; -out vec4 FragmentColor; -void main() { - vec2 uv = qt_TexCoord0.xy; - vec4 c = vec4(0.0); - if (uv.x < dividerValue) { - mat3 intensity; - float conv[2]; - vec3 sample; - for (int i=0; i<3; ++i) { - for (int j=0; j<3; ++j) { - sample = texelFetch(source, ivec2(gl_FragCoord) + ivec2(i-1, j-1), 0).rgb; - intensity[i][j] = length(sample) * weight; - } - } - for (int i=0; i<2; ++i) { - float dp3 = dot(G[i][0], intensity[0]) + dot(G[i][1], intensity[1]) + dot(G[i][2], intensity[2]); - conv[i] = dp3 * dp3; - } - c = vec4(0.5 * sqrt(conv[0]*conv[0] + conv[1]*conv[1])); - } else { - c = texture2D(source, qt_TexCoord0); - } - FragmentColor = qt_Opacity * c; -} -- cgit v1.2.3 From 78cff36ba8e195c8183c3434498bc7fddeb5c00c Mon Sep 17 00:00:00 2001 From: Sergio Ahumada Date: Thu, 17 Apr 2014 17:24:25 +0200 Subject: Bump MODULE_VERSION to 5.3.1 Change-Id: Ie88b34ee769ab3abbd0a5ab0fd8b7938475916ae Reviewed-by: Oswald Buddenhagen --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index efd0e68f0..ef45a002d 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,4 +1,4 @@ load(qt_build_config) CONFIG += qt_example_installs -MODULE_VERSION = 5.3.0 +MODULE_VERSION = 5.3.1 -- cgit v1.2.3 -- cgit v1.2.3 From c9a3bbc3e69b9965b5c1b9d85f8426896f94c02a Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Fri, 25 Apr 2014 10:28:16 +0200 Subject: [QNX] Introduce env variable for default audio sink Make it possible to change the default audio sink via a environment variable. Change-Id: Id0e14318fc99a896b8a41196941b758a31d23600 Reviewed-by: Sean Harmer --- src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp index 2555b2876..abb682784 100644 --- a/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp +++ b/src/plugins/qnx/mediaplayer/mmrenderermediaplayercontrol.cpp @@ -208,7 +208,8 @@ void MmRendererMediaPlayerControl::attach() if (m_videoWindowControl) m_videoWindowControl->attachDisplay(m_context); - m_audioId = mmr_output_attach(m_context, "audio:default", "audio"); + const QByteArray defaultAudioDevice = qgetenv("QQNX_RENDERER_DEFAULT_AUDIO_SINK"); + m_audioId = mmr_output_attach(m_context, defaultAudioDevice.isEmpty() ? "audio:default" : defaultAudioDevice.constData(), "audio"); if (m_audioId == -1) { emitMmError("mmr_output_attach() for audio failed"); return; -- cgit v1.2.3 From 2939c9953ad08e659722c2b832f2c35db6de0115 Mon Sep 17 00:00:00 2001 From: Niels Weber Date: Mon, 28 Apr 2014 09:27:03 +0200 Subject: Add missing background for effect selection list. Also remove highlight and fix button text color. Make Menu animation faster. Task-number: QTBUG-38121 Change-Id: I7d5868d370a8dc7925cee5e694ae043970c569d9 Reviewed-by: Sami Makkonen Reviewed-by: Thomas Hartmann --- .../video/qmlvideofx/qml/qmlvideofx/Button.qml | 3 +- .../video/qmlvideofx/qml/qmlvideofx/Main.qml | 36 +++++++++++++--------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml index dd7cca602..203352832 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Button.qml @@ -60,7 +60,6 @@ Rectangle { Rectangle { anchors { fill: parent; margins: 1 } color: mouseArea.pressed ? bgColorSelected : bgColor - radius: 0.1 * height Text { id: text @@ -68,7 +67,7 @@ Rectangle { text: root.text anchors { fill: parent; margins: scaledMargin } font.pixelSize: fontSize - color: mouseArea.pressed ? bgColor : textColor + color: textColor horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml index 5ec13750f..e39eeafd7 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/Main.qml @@ -80,7 +80,7 @@ Rectangle { id: parameterPanel anchors { left: parent.left - right: listview.left + right: effectName.left bottom: parent.bottom margins: scaledMargin leftMargin: scaledMargin + itemHeight @@ -88,46 +88,50 @@ Rectangle { gripSize: d.gripSize height: root.itemHeight * 2.5 width: root.itemWidth * 3 - } - Button { id: effectName anchors { right: parent.right bottom: perfHolder.top - top: content.bottom margins: scaledMargin } text: "No effect" width: itemWidth * 2 + height: itemHeight onClicked: { effectName.visible = false listview.visible = true + lvbg.visible = true } color: "#303030" } + Rectangle { + id: lvbg + width: itemWidth * 2 + color: "black" + opacity: 0.8 + visible: false + + anchors { + right: parent.right + bottom: perfHolder.top + top: parent.top + margins: scaledMargin + } ListView { id: listview width: itemWidth * 2 - anchors { - right: parent.right - bottom: perfHolder.top - top: parent.top - margins: scaledMargin - } + anchors.fill: parent visible: false model: EffectSelectionList {} delegate: effectDelegate - highlight: Rectangle { color: "#14aaff"; radius: 5 } - highlightFollowsCurrentItem: true - highlightRangeMode: ListView.StrictlyEnforceRange clip: true focus: true @@ -139,6 +143,7 @@ Rectangle { onClicked: { content.effectSource = source listview.visible = false + lvbg.visible = false effectName.text = name effectName.visible = true parameterPanel.model = content.effect.parameters @@ -146,6 +151,7 @@ Rectangle { } } } + } } Rectangle { @@ -213,8 +219,8 @@ Rectangle { transitions: [ Transition { - NumberAnimation { target: fileOpen; property: "width"; duration: 400 } - NumberAnimation { target: fileOpen; property: "opacity"; duration: 400 } + NumberAnimation { target: fileOpen; property: "width"; duration: 100 } + NumberAnimation { target: fileOpen; property: "opacity"; duration: 100 } } ] } -- cgit v1.2.3 From c5d184cbe38d8024c6354952d3103423d51638ec Mon Sep 17 00:00:00 2001 From: Niels Weber Date: Mon, 28 Apr 2014 09:39:16 +0200 Subject: Selecting something now closes menu On a closed menu, the text is now hidden. Task-number: QTBUG-38121 Change-Id: I305fd4f24768115ed21495857cce672d8cbd2135 Reviewed-by: Petref Saraci Reviewed-by: Thomas Hartmann --- .../video/qmlvideofx/qml/qmlvideofx/FileOpen.qml | 76 ++++++++++++++-------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml index b0542cb80..a4de2cbb9 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/FileOpen.qml @@ -49,28 +49,40 @@ Rectangle { signal openVideo signal close - Column { - anchors.fill: parent - spacing: 10 - Rectangle { - height: itemHeight - width: itemHeight - color: "transparent" - anchors.right: parent.right - Image { - id: menu - source: "qrc:///images/icon_Menu.png" - anchors { - right: parent.right - top: parent.top - margins: scaledMargin - } - } - MouseArea { - anchors.fill: parent - onClicked: fileOpen.state == "expanded" ? fileOpen.state = "collapsed" : fileOpen.state = "expanded" + + Rectangle { + id: menuField + height: itemHeight + width: itemHeight + color: "transparent" + anchors.right: parent.right + Image { + id: menu + source: "qrc:///images/icon_Menu.png" + anchors { + right: parent.right + top: parent.top + margins: scaledMargin } } + MouseArea { + anchors.fill: parent + onClicked: fileOpen.state == "expanded" ? fileOpen.state = "collapsed" : fileOpen.state = "expanded" + } + } + + Column { + anchors { + top: menuField.bottom + right: parent.right + left: parent.left + bottom: parent.bottom + topMargin: 10 + } + + spacing: 10 + visible: fileOpen.state == "expanded" + Rectangle { width: 0.9 * parent.width height: 1 @@ -81,8 +93,10 @@ Rectangle { text: "Start camera" height: itemHeight width: parent.width - onClicked: root.openCamera() - active: fileOpen.state == "expanded" + onClicked: { + fileOpen.state = "collapsed" + root.openCamera() + } } Rectangle { width: 0.9 * parent.width @@ -94,8 +108,10 @@ Rectangle { text: "Open image" height: itemHeight width: parent.width - onClicked: root.openImage() - active: fileOpen.state == "expanded" + onClicked: { + fileOpen.state = "collapsed" + root.openImage() + } } Rectangle { width: 0.9 * parent.width @@ -107,8 +123,10 @@ Rectangle { text: "Open video" height: itemHeight width: parent.width - onClicked: root.openVideo() - active: fileOpen.state == "expanded" + onClicked: { + fileOpen.state = "collapsed" + root.openVideo() + } } Rectangle { width: 0.9 * parent.width @@ -120,8 +138,10 @@ Rectangle { text: "Reset" height: itemHeight width: parent.width - onClicked: root.close() - active: fileOpen.state == "expanded" + onClicked: { + fileOpen.state = "collapsed" + root.close() + } } Rectangle { width: 0.9 * parent.width -- cgit v1.2.3 From 02c0229a058e0779d236bec4c48bdad7d3d78399 Mon Sep 17 00:00:00 2001 From: Niels Weber Date: Mon, 28 Apr 2014 10:52:33 +0200 Subject: Handle resizing of mainwindow better Task-number: QTBUG-38121 Change-Id: I877fd5c626418a91850d43de31e71351c14eef25 Reviewed-by: Sami Makkonen Reviewed-by: Thomas Hartmann --- examples/multimedia/video/qmlvideofx/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/multimedia/video/qmlvideofx/main.cpp b/examples/multimedia/video/qmlvideofx/main.cpp index f221c954a..1b09f7aa4 100644 --- a/examples/multimedia/video/qmlvideofx/main.cpp +++ b/examples/multimedia/video/qmlvideofx/main.cpp @@ -122,7 +122,8 @@ int main(int argc, char *argv[]) viewer.setTitle("qmlvideofx"); viewer.setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); - viewer.setMinimumSize(QSize(640, 360)); + viewer.setMinimumSize(QSize(1280, 720)); + viewer.setResizeMode(QQuickView::SizeRootObjectToView); viewer.show(); -- cgit v1.2.3 From 82d96105cea1bca034119adf54a2614c67a24c13 Mon Sep 17 00:00:00 2001 From: Niels Weber Date: Tue, 22 Apr 2014 12:13:23 +0200 Subject: Fix documentation of qmlvideofx example Make the documentation fit to the current state of the example. Task-number: QTBUG-38121 Change-Id: I3379e3328d07ef8bcdb35a5e3821ab194c3443c4 Reviewed-by: Leena Miettinen Reviewed-by: Sami Makkonen Reviewed-by: Yoann Lopes --- .../video/doc/images/qmlvideofx-camera-glow.jpg | Bin 0 -> 74914 bytes .../video/doc/images/qmlvideofx-camera-glow.png | Bin 250540 -> 0 bytes .../video/doc/images/qmlvideofx-camera-magnify.png | Bin 204923 -> 0 bytes .../video/doc/images/qmlvideofx-camera-wobble.jpg | Bin 0 -> 62992 bytes .../video/doc/images/qmlvideofx-effects-menu.jpg | Bin 0 -> 84990 bytes .../video/doc/images/qmlvideofx-effects-menu.png | Bin 171257 -> 0 bytes .../video/doc/images/qmlvideofx-source-menu.png | Bin 257292 -> 0 bytes .../doc/images/qmlvideofx-video-edgedetection.jpg | Bin 0 -> 108916 bytes .../doc/images/qmlvideofx-video-edgedetection.png | Bin 279883 -> 0 bytes .../video/doc/images/qmlvideofx-video-pagecurl.jpg | Bin 0 -> 61450 bytes .../video/doc/images/qmlvideofx-video-pagecurl.png | Bin 220606 -> 0 bytes examples/multimedia/video/doc/src/qmlvideofx.qdoc | 27 +++++++-------------- 12 files changed, 9 insertions(+), 18 deletions(-) create mode 100644 examples/multimedia/video/doc/images/qmlvideofx-camera-glow.jpg delete mode 100644 examples/multimedia/video/doc/images/qmlvideofx-camera-glow.png delete mode 100644 examples/multimedia/video/doc/images/qmlvideofx-camera-magnify.png create mode 100644 examples/multimedia/video/doc/images/qmlvideofx-camera-wobble.jpg create mode 100644 examples/multimedia/video/doc/images/qmlvideofx-effects-menu.jpg delete mode 100644 examples/multimedia/video/doc/images/qmlvideofx-effects-menu.png delete mode 100644 examples/multimedia/video/doc/images/qmlvideofx-source-menu.png create mode 100644 examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.jpg delete mode 100644 examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.png create mode 100644 examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.jpg delete mode 100644 examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.png diff --git a/examples/multimedia/video/doc/images/qmlvideofx-camera-glow.jpg b/examples/multimedia/video/doc/images/qmlvideofx-camera-glow.jpg new file mode 100644 index 000000000..777ed4ffc Binary files /dev/null and b/examples/multimedia/video/doc/images/qmlvideofx-camera-glow.jpg differ diff --git a/examples/multimedia/video/doc/images/qmlvideofx-camera-glow.png b/examples/multimedia/video/doc/images/qmlvideofx-camera-glow.png deleted file mode 100644 index aca874b6c..000000000 Binary files a/examples/multimedia/video/doc/images/qmlvideofx-camera-glow.png and /dev/null differ diff --git a/examples/multimedia/video/doc/images/qmlvideofx-camera-magnify.png b/examples/multimedia/video/doc/images/qmlvideofx-camera-magnify.png deleted file mode 100644 index c3156ce96..000000000 Binary files a/examples/multimedia/video/doc/images/qmlvideofx-camera-magnify.png and /dev/null differ diff --git a/examples/multimedia/video/doc/images/qmlvideofx-camera-wobble.jpg b/examples/multimedia/video/doc/images/qmlvideofx-camera-wobble.jpg new file mode 100644 index 000000000..980ab0d15 Binary files /dev/null and b/examples/multimedia/video/doc/images/qmlvideofx-camera-wobble.jpg differ diff --git a/examples/multimedia/video/doc/images/qmlvideofx-effects-menu.jpg b/examples/multimedia/video/doc/images/qmlvideofx-effects-menu.jpg new file mode 100644 index 000000000..eb5b90321 Binary files /dev/null and b/examples/multimedia/video/doc/images/qmlvideofx-effects-menu.jpg differ diff --git a/examples/multimedia/video/doc/images/qmlvideofx-effects-menu.png b/examples/multimedia/video/doc/images/qmlvideofx-effects-menu.png deleted file mode 100644 index 507fd7384..000000000 Binary files a/examples/multimedia/video/doc/images/qmlvideofx-effects-menu.png and /dev/null differ diff --git a/examples/multimedia/video/doc/images/qmlvideofx-source-menu.png b/examples/multimedia/video/doc/images/qmlvideofx-source-menu.png deleted file mode 100644 index 661aaa73f..000000000 Binary files a/examples/multimedia/video/doc/images/qmlvideofx-source-menu.png and /dev/null differ diff --git a/examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.jpg b/examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.jpg new file mode 100644 index 000000000..35b36c036 Binary files /dev/null and b/examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.jpg differ diff --git a/examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.png b/examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.png deleted file mode 100644 index cedb314c5..000000000 Binary files a/examples/multimedia/video/doc/images/qmlvideofx-video-edgedetection.png and /dev/null differ diff --git a/examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.jpg b/examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.jpg new file mode 100644 index 000000000..5cd8d2bd2 Binary files /dev/null and b/examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.jpg differ diff --git a/examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.png b/examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.png deleted file mode 100644 index 5f5bdfb53..000000000 Binary files a/examples/multimedia/video/doc/images/qmlvideofx-video-pagecurl.png and /dev/null differ diff --git a/examples/multimedia/video/doc/src/qmlvideofx.qdoc b/examples/multimedia/video/doc/src/qmlvideofx.qdoc index 80f087e7f..edbd369c0 100644 --- a/examples/multimedia/video/doc/src/qmlvideofx.qdoc +++ b/examples/multimedia/video/doc/src/qmlvideofx.qdoc @@ -46,31 +46,25 @@ advanced functionality - in this case, C++ code is used to calculate the QML frame rate. This value is rendered in QML in a semi-transparent item overlaid on the video content. -Finally, this application demonstrates the use of different top-level QML -files to handle different physical screen sizes. On small-screen devices, -menus are by default hidden, and only appear when summoned by a gesture. -Large-screen devices show a more traditional layout in which menus are -displayed around the video content pane. - The following screenshots show shader effects being applied. In each case, the effect is implemented using a fragment shader. Here we see an edge detection algorithm being applied to a video clip -(\l{http://orange.blender.org/}{Elephant's Dream from blender.org}). -\image qmlvideofx-video-edgedetection.png +(\l{http://durian.blender.org/}{Sintel from blender.org}). +\image qmlvideofx-video-edgedetection.jpg This image shows a page curl effect, applied to the same video clip. -\image qmlvideofx-video-pagecurl.png +\image qmlvideofx-video-pagecurl.jpg Here we see a 'glow' effect (edge detection plus colour quantization) being applied to the camera viewfinder. -\image qmlvideofx-camera-glow.png +\image qmlvideofx-camera-glow.jpg -This image shows a 'lens magnification' effect applied to the viewfinder. -\image qmlvideofx-camera-magnify.png +This image shows a 'wobble' effect applied to the viewfinder. +\image qmlvideofx-camera-wobble.jpg The application includes many more effects than the ones shown here - look -for Effect*.qml files in the list above to see the full range. +for Effect*.qml files in the list of files below to see the full range. \section1 Application structure @@ -197,11 +191,8 @@ vertical dividing line, which can be dragged left / right by the user. Finally, a \l{video/qmlvideofx/qml/qmlvideofx/ParameterPanel.qml}{ParameterPanel} item renders the sliders corresponding to each effect parameter. -Here is the source selection menu: -\image qmlvideofx-source-menu.png - -And here is the effect selection menu: -\image qmlvideofx-effects-menu.png +Here is the effect selection menu: +\image qmlvideofx-effects-menu.jpg \section1 Calculating and displaying QML painting rate -- cgit v1.2.3 From 5339aed040d58f8486205df1525508b8c02faa9c Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 9 Apr 2014 19:13:45 +0200 Subject: Moved QMediaStorageLocation out of the Android plugin. It's now a private API in the QtMultimedia library in order to be accessible in other plugins. Change-Id: I63541de1e8c540cebc210f9037646ce74d866c6f Reviewed-by: Christian Stromme --- src/multimedia/multimedia.pro | 4 +- src/multimedia/qmediastoragelocation.cpp | 146 +++++++++++++++++++++ src/multimedia/qmediastoragelocation_p.h | 80 +++++++++++ .../android/src/mediacapture/mediacapture.pri | 2 - .../src/mediacapture/qandroidcamerasession.cpp | 8 +- .../src/mediacapture/qandroidcamerasession.h | 6 +- .../src/mediacapture/qandroidcapturesession.cpp | 14 +- .../src/mediacapture/qandroidcapturesession.h | 6 +- .../mediacapture/qandroidmediastoragelocation.cpp | 130 ------------------ .../mediacapture/qandroidmediastoragelocation.h | 75 ----------- 10 files changed, 252 insertions(+), 219 deletions(-) create mode 100644 src/multimedia/qmediastoragelocation.cpp create mode 100644 src/multimedia/qmediastoragelocation_p.h delete mode 100644 src/plugins/android/src/mediacapture/qandroidmediastoragelocation.cpp delete mode 100644 src/plugins/android/src/mediacapture/qandroidmediastoragelocation.h diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro index 23cca2537..0f3ced913 100644 --- a/src/multimedia/multimedia.pro +++ b/src/multimedia/multimedia.pro @@ -21,7 +21,8 @@ PRIVATE_HEADERS += \ qmediaserviceprovider_p.h \ qmediaresourcepolicyplugin_p.h \ qmediaresourcepolicy_p.h \ - qmediaresourceset_p.h + qmediaresourceset_p.h \ + qmediastoragelocation_p.h PUBLIC_HEADERS += \ qmediabindableinterface.h \ @@ -47,6 +48,7 @@ SOURCES += \ qmediaresourcepolicyplugin_p.cpp \ qmediaresourcepolicy_p.cpp \ qmediaresourceset_p.cpp \ + qmediastoragelocation.cpp \ qmultimedia.cpp include(audio/audio.pri) diff --git a/src/multimedia/qmediastoragelocation.cpp b/src/multimedia/qmediastoragelocation.cpp new file mode 100644 index 000000000..877c12138 --- /dev/null +++ b/src/multimedia/qmediastoragelocation.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2014 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 "qmediastoragelocation_p.h" + +#include + +QT_BEGIN_NAMESPACE + +QMediaStorageLocation::QMediaStorageLocation() +{ +} + +void QMediaStorageLocation::addStorageLocation(MediaType type, const QString &location) +{ + m_customLocations[type].append(location); +} + +QDir QMediaStorageLocation::defaultLocation(MediaType type) const +{ + QStringList dirCandidates; + + dirCandidates << m_customLocations.value(type); + + switch (type) { + case Movies: + dirCandidates << QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); + break; + case Music: + dirCandidates << QStandardPaths::writableLocation(QStandardPaths::MusicLocation); + break; + case Pictures: + dirCandidates << QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); + default: + break; + } + + 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 QMediaStorageLocation::generateFileName(const QString &requestedName, + MediaType type, + const QString &prefix, + const QString &extension) const +{ + if (requestedName.isEmpty()) + return generateFileName(prefix, defaultLocation(type), extension); + + QString path = requestedName; + + if (QFileInfo(path).isRelative()) + path = defaultLocation(type).absoluteFilePath(path); + + if (QFileInfo(path).isDir()) + return generateFileName(prefix, QDir(path), extension); + + if (!path.endsWith(extension)) + path.append(QString(QLatin1String(".%1")).arg(extension)); + + return path; +} + +QString QMediaStorageLocation::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(QLatin1String("%1*.%2")).arg(prefix).arg(extension))) { + const qint64 mediaIndex = fileName.midRef(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(QLatin1String("%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/multimedia/qmediastoragelocation_p.h b/src/multimedia/qmediastoragelocation_p.h new file mode 100644 index 000000000..600fb63ff --- /dev/null +++ b/src/multimedia/qmediastoragelocation_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2014 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 QMEDIASTORAGELOCATION_H +#define QMEDIASTORAGELOCATION_H + +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_MULTIMEDIA_EXPORT QMediaStorageLocation +{ +public: + enum MediaType { + Movies, + Music, + Pictures, + Sounds + }; + + QMediaStorageLocation(); + + void addStorageLocation(MediaType type, const QString &location); + + QDir defaultLocation(MediaType type) const; + + QString generateFileName(const QString &requestedName, MediaType type, const QString &prefix, const QString &extension) const; + QString generateFileName(const QString &prefix, const QDir &dir, const QString &extension) const; + +private: + mutable QMutex m_mutex; + mutable QHash m_lastUsedIndex; + QMap m_customLocations; +}; + +QT_END_NAMESPACE + +#endif // QMEDIASTORAGELOCATION_H diff --git a/src/plugins/android/src/mediacapture/mediacapture.pri b/src/plugins/android/src/mediacapture/mediacapture.pri index 01274414b..fde0e3d6f 100644 --- a/src/plugins/android/src/mediacapture/mediacapture.pri +++ b/src/plugins/android/src/mediacapture/mediacapture.pri @@ -12,7 +12,6 @@ SOURCES += \ $$PWD/qandroidcameraimagecapturecontrol.cpp \ $$PWD/qandroidcameracapturedestinationcontrol.cpp \ $$PWD/qandroidcameracapturebufferformatcontrol.cpp \ - $$PWD/qandroidmediastoragelocation.cpp \ $$PWD/qandroidcameraflashcontrol.cpp \ $$PWD/qandroidcamerafocuscontrol.cpp \ $$PWD/qandroidcameralockscontrol.cpp \ @@ -37,7 +36,6 @@ HEADERS += \ $$PWD/qandroidcameraimagecapturecontrol.h \ $$PWD/qandroidcameracapturedestinationcontrol.h \ $$PWD/qandroidcameracapturebufferformatcontrol.h \ - $$PWD/qandroidmediastoragelocation.h \ $$PWD/qandroidcameraflashcontrol.h \ $$PWD/qandroidcamerafocuscontrol.h \ $$PWD/qandroidcameralockscontrol.h \ diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index 6051cf964..53fb2f516 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Toolkit. @@ -111,6 +111,10 @@ QAndroidCameraSession::QAndroidCameraSession(QObject *parent) , m_captureCanceled(false) , m_currentImageCaptureId(-1) { + m_mediaStorageLocation.addStorageLocation( + QMediaStorageLocation::Pictures, + JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::DCIM)); + if (qApp) { connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onApplicationStateChanged(Qt::ApplicationState))); @@ -644,7 +648,7 @@ void QAndroidCameraSession::processCapturedImage(int id, if (dest & QCameraImageCapture::CaptureToFile) { const QString actualFileName = m_mediaStorageLocation.generateFileName(fileName, - QAndroidMediaStorageLocation::Camera, + QMediaStorageLocation::Pictures, QLatin1String("IMG_"), QLatin1String("jpg")); diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h index f3ac67894..4c58cab9e 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.h +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Toolkit. @@ -47,7 +47,7 @@ #include #include #include -#include "qandroidmediastoragelocation.h" +#include QT_BEGIN_NAMESPACE @@ -174,7 +174,7 @@ private: int m_currentImageCaptureId; QString m_currentImageCaptureFileName; - QAndroidMediaStorageLocation m_mediaStorageLocation; + QMediaStorageLocation m_mediaStorageLocation; QSet m_videoProbes; QMutex m_videoProbesMutex; diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp index 008ebc7d5..4b1c58255 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Toolkit. @@ -65,6 +65,14 @@ QAndroidCaptureSession::QAndroidCaptureSession(QAndroidCameraSession *cameraSess , m_audioEncoder(JMediaRecorder::DefaultAudioEncoder) , m_videoEncoder(JMediaRecorder::DefaultVideoEncoder) { + m_mediaStorageLocation.addStorageLocation( + QMediaStorageLocation::Movies, + JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::DCIM)); + + m_mediaStorageLocation.addStorageLocation( + QMediaStorageLocation::Sounds, + JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::Sounds)); + connect(this, SIGNAL(stateChanged(QMediaRecorder::State)), this, SLOT(updateStatus())); if (cameraSession) { @@ -214,8 +222,8 @@ bool QAndroidCaptureSession::start() QString filePath = m_mediaStorageLocation.generateFileName( m_requestedOutputLocation.isLocalFile() ? m_requestedOutputLocation.toLocalFile() : m_requestedOutputLocation.toString(), - m_cameraSession ? QAndroidMediaStorageLocation::Camera - : QAndroidMediaStorageLocation::Audio, + m_cameraSession ? QMediaStorageLocation::Movies + : QMediaStorageLocation::Sounds, m_cameraSession ? QLatin1String("VID_") : QLatin1String("REC_"), m_containerFormat); diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.h b/src/plugins/android/src/mediacapture/qandroidcapturesession.h index 32ca9d1ae..4b6121dfa 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.h +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Toolkit. @@ -47,7 +47,7 @@ #include #include #include -#include "qandroidmediastoragelocation.h" +#include #include "jmediarecorder.h" QT_BEGIN_NAMESPACE @@ -152,7 +152,7 @@ private: QString m_audioInput; JMediaRecorder::AudioSource m_audioSource; - QAndroidMediaStorageLocation m_mediaStorageLocation; + QMediaStorageLocation m_mediaStorageLocation; QElapsedTimer m_elapsedTime; QTimer m_notifyTimer; diff --git a/src/plugins/android/src/mediacapture/qandroidmediastoragelocation.cpp b/src/plugins/android/src/mediacapture/qandroidmediastoragelocation.cpp deleted file mode 100644 index 2bd3da195..000000000 --- a/src/plugins/android/src/mediacapture/qandroidmediastoragelocation.cpp +++ /dev/null @@ -1,130 +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 "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.midRef(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 deleted file mode 100644 index 2e63f3df5..000000000 --- a/src/plugins/android/src/mediacapture/qandroidmediastoragelocation.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 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 -- cgit v1.2.3 From 101dce7a2958c9b4cee2caa5b61e9c9ca86affcf Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 29 Apr 2014 17:30:21 +0200 Subject: GStreamer: disable clock syncing in video sink for live sources. Task-number: QTBUG-38465 Change-Id: Icdf2df36b9b3c09dd047e60ac24e221a3d233c6f Reviewed-by: Christian Stromme --- src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp index 27446e07d..87b71d7e2 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp @@ -1535,6 +1535,7 @@ void QGstreamerPlayerSession::playbinNotifySource(GObject *o, GParamSpec *p, gpo qDebug() << "Current source is a non-live source"; #endif + g_object_set(G_OBJECT(self->m_videoSink), "sync", !self->m_isLiveSource, NULL); gst_object_unref(source); } -- cgit v1.2.3 From 364258abfcc438f79908e8c47fd0fd68cfecee36 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 9 May 2014 15:31:33 +0200 Subject: PLS parser: Don't translate entries. Each entry in a PLS file uses the keywords 'File', 'Title' and 'Length' in English, it should not be translated to the user's locale... Task-number: QTBUG-38755 Change-Id: Ibd5bee18a856b3ebc1fdb177241db7a39b65d264 Reviewed-by: Christian Stromme --- src/multimedia/playback/playlistfileparser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/multimedia/playback/playlistfileparser.cpp b/src/multimedia/playback/playlistfileparser.cpp index ae14d2159..1254d6131 100644 --- a/src/multimedia/playback/playlistfileparser.cpp +++ b/src/multimedia/playback/playlistfileparser.cpp @@ -307,9 +307,9 @@ Version=2 void setCount(int count) { m_count = count; - m_fileName = QString(tr("File%1")).arg(count); - m_titleName = QString(tr("Title%1")).arg(count); - m_lengthName = QString(tr("Length%1")).arg(count); + m_fileName = QStringLiteral("File%1").arg(count); + m_titleName = QStringLiteral("Title%1").arg(count); + m_lengthName = QStringLiteral("Length%1").arg(count); m_item.clear(); m_readFlags = 0; } -- cgit v1.2.3 From 1d6872ae9c2de1ae7501c375b4960b1ac9374693 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Thu, 8 May 2014 23:47:38 +0800 Subject: Doc: Clean up references to Qt System Info The module is not released yet; the current documentation is misleading. Change-Id: Ia20ac8e3504942f6f60b94264f3a12497e09da24 Reviewed-by: Niels Weber Reviewed-by: Jerome Pasion Reviewed-by: Yoann Lopes --- .../multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml | 1 + .../multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml | 1 + src/imports/multimedia/Video.qml | 4 ++++ src/qtmultimediaquicktools/qdeclarativevideooutput.cpp | 4 ++++ 4 files changed, 10 insertions(+) diff --git a/examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml b/examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml index efc657cfc..01ed95e8a 100644 --- a/examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml +++ b/examples/multimedia/video/qmlvideo/qml/qmlvideo/DisableScreenSaver.qml @@ -41,6 +41,7 @@ import QtQuick 2.0 import QtSystemInfo 5.0 +// NOTE: The QtSystemInfo module is not yet part of Qt 5 Item { ScreenSaver { diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml index f36b2b14f..362386bc4 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/DisableScreenSaver.qml @@ -41,6 +41,7 @@ import QtQuick 2.0 import QtMobility.systeminfo 1.1 +// NOTE: The QtSystemInfo module is not yet part of Qt 5 Item { ScreenSaver { diff --git a/src/imports/multimedia/Video.qml b/src/imports/multimedia/Video.qml index 0b8dc1118..9da808462 100644 --- a/src/imports/multimedia/Video.qml +++ b/src/imports/multimedia/Video.qml @@ -85,6 +85,7 @@ import QtMultimedia 5.0 \sa MediaPlayer, VideoOutput +\omit \section1 Screen Saver If it is likely that an application will be playing video for an extended @@ -97,8 +98,11 @@ import QtMultimedia 5.0 ScreenSaver { screenSaverEnabled: false } \endqml +\endomit */ +// TODO: Restore Qt System Info docs when the module is released + Item { id: video diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp index b13665f66..e904307df 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp @@ -104,6 +104,7 @@ QT_BEGIN_NAMESPACE \sa MediaPlayer, Camera +\omit \section1 Screen Saver If it is likely that an application will be playing video for an extended @@ -116,8 +117,11 @@ QT_BEGIN_NAMESPACE ScreenSaver { screenSaverEnabled: false } \endqml +\endomit */ +// TODO: Restore Qt System Info docs when the module is released + /*! \internal \class QDeclarativeVideoOutput -- cgit v1.2.3 From 469f9a0c077cedaffafee55a4889dd878bfb2b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 30 Apr 2014 12:31:21 +0200 Subject: Android: Fix namespace usage. Make it possible to build multimedia with a Qt namespace Change-Id: Ibaeaf7edb38f8d784b8d0fcb9a26ca712488c23b Reviewed-by: Yoann Lopes --- src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h | 2 ++ .../android/src/mediacapture/qandroidmediavideoprobecontrol.cpp | 4 ++++ src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.h | 4 ++++ src/plugins/android/src/qandroidmediaserviceplugin.cpp | 4 ++-- src/plugins/android/src/wrappers/jmediaplayer.cpp | 4 ---- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h b/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h index 23e397d4d..7dcc884a9 100644 --- a/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h +++ b/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.h @@ -69,4 +69,6 @@ private: QList m_supportedResolutions; }; +QT_END_NAMESPACE + #endif // QANDROIDIMAGEENCODERCONTROL_H diff --git a/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.cpp b/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.cpp index a4ebc8fe4..8e0cf6d16 100644 --- a/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.cpp +++ b/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.cpp @@ -43,6 +43,8 @@ #include "qandroidmediavideoprobecontrol.h" #include +QT_BEGIN_NAMESPACE + QAndroidMediaVideoProbeControl::QAndroidMediaVideoProbeControl(QObject *parent) : QMediaVideoProbeControl(parent) { @@ -57,3 +59,5 @@ void QAndroidMediaVideoProbeControl::newFrameProbed(const QVideoFrame &frame) { emit videoFrameProbed(frame); } + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.h b/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.h index 7bb34d883..0a0007c9f 100644 --- a/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.h +++ b/src/plugins/android/src/mediacapture/qandroidmediavideoprobecontrol.h @@ -45,6 +45,8 @@ #include +QT_BEGIN_NAMESPACE + class QAndroidMediaVideoProbeControl : public QMediaVideoProbeControl { Q_OBJECT @@ -56,4 +58,6 @@ public: }; +QT_END_NAMESPACE + #endif // QANDROIDMEDIAVIDEOPROBECONTROL_H diff --git a/src/plugins/android/src/qandroidmediaserviceplugin.cpp b/src/plugins/android/src/qandroidmediaserviceplugin.cpp index 0af43210f..6c1515308 100644 --- a/src/plugins/android/src/qandroidmediaserviceplugin.cpp +++ b/src/plugins/android/src/qandroidmediaserviceplugin.cpp @@ -147,9 +147,11 @@ int QAndroidMediaServicePlugin::cameraOrientation(const QByteArray &device) cons return QAndroidCameraInfoControl::orientation(device); } +QT_END_NAMESPACE Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/) { + QT_USE_NAMESPACE typedef union { JNIEnv *nativeEnvironment; void *venv; @@ -173,5 +175,3 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/) return JNI_VERSION_1_4; } - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jmediaplayer.cpp b/src/plugins/android/src/wrappers/jmediaplayer.cpp index de86cd041..98ccbfd5a 100644 --- a/src/plugins/android/src/wrappers/jmediaplayer.cpp +++ b/src/plugins/android/src/wrappers/jmediaplayer.cpp @@ -155,8 +155,6 @@ void JMediaPlayer::setDisplay(jobject surfaceHolder) mMediaPlayer.callMethod("setDisplay", "(Landroid/view/SurfaceHolder;)V", surfaceHolder); } -QT_END_NAMESPACE - static void onErrorNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id) { Q_UNUSED(env); @@ -238,8 +236,6 @@ static void onVideoSizeChangedNative(JNIEnv *env, Q_EMIT mp->videoSizeChanged(width, height); } -QT_BEGIN_NAMESPACE - bool JMediaPlayer::initJNI(JNIEnv *env) { jclass jClass = env->FindClass("org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer"); -- cgit v1.2.3 From 64726bfd15458db8c5e80bac479ed3a35a6f652e Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Sun, 26 May 2013 15:42:43 +0800 Subject: Doc: Copy snippets from the Qt Multimedia module Extract a compilable subsection of... - src/multimedia/doc/snippets/multimedia-snippets/camera.cpp - src/multimedia/doc/snippets/multimedia-snippets/video.cpp ...into the snippet folder searched by: - src/multimediawidgets/qcameraviewfinder.cpp - src/multimediawidgets/qgraphicsvideoitem.cpp - src/multimediawidgets/qvideowidget.cpp - src/multimediawidgets/qvideowidgetcontrol.cpp Change-Id: Ica3c21b65bc57d5686a594afca09e771cc376cc0 Reviewed-by: Jerome Pasion --- .../doc/snippets/multimedia-snippets/camera.cpp | 68 +++++++++++++ .../doc/snippets/multimedia-snippets/video.cpp | 112 +++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 src/multimediawidgets/doc/snippets/multimedia-snippets/camera.cpp create mode 100644 src/multimediawidgets/doc/snippets/multimedia-snippets/video.cpp diff --git a/src/multimediawidgets/doc/snippets/multimedia-snippets/camera.cpp b/src/multimediawidgets/doc/snippets/multimedia-snippets/camera.cpp new file mode 100644 index 000000000..70c3cb6fb --- /dev/null +++ b/src/multimediawidgets/doc/snippets/multimedia-snippets/camera.cpp @@ -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 documentation 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$ +** +****************************************************************************/ + +// Camera snippets +// Extracted from src/multimedia/doc/snippets/multimedia-snippets/camera.cpp +#include "qcamera.h" +#include "qcameraviewfinder.h" +#include "qcameraimagecapture.h" + +/* Globals so that everything is consistent. */ +QCamera *camera = 0; +QCameraViewfinder *viewfinder = 0; +QCameraImageCapture *imageCapture = 0; + +void camera_blah() +{ + //! [Camera] + camera = new QCamera; + + viewfinder = new QCameraViewfinder(); + viewfinder->show(); + + camera->setViewfinder(viewfinder); + + imageCapture = new QCameraImageCapture(camera); + + camera->setCaptureMode(QCamera::CaptureStillImage); + camera->start(); + //! [Camera] +} diff --git a/src/multimediawidgets/doc/snippets/multimedia-snippets/video.cpp b/src/multimediawidgets/doc/snippets/multimedia-snippets/video.cpp new file mode 100644 index 000000000..717419409 --- /dev/null +++ b/src/multimediawidgets/doc/snippets/multimedia-snippets/video.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +// Video related snippets +// Extracted from src/multimedia/doc/snippets/multimedia-snippets/video.cpp +#include "qmediaservice.h" +#include "qmediaplayer.h" +#include "qvideowidgetcontrol.h" +#include "qvideowindowcontrol.h" +#include "qgraphicsvideoitem.h" +#include "qmediaplaylist.h" + +#include +#include + +class VideoExample : public QObject { + Q_OBJECT +public: + void VideoGraphicsItem(); + void VideoWidget(); + void VideoWidgetControl(); + +private: + // Common naming + QMediaService *mediaService; + QMediaPlaylist *playlist; + QVideoWidget *videoWidget; + QFormLayout *layout; + QMediaPlayer *player; + QGraphicsView *graphicsView; +}; + +void VideoExample::VideoWidget() +{ + //! [Video widget] + player = new QMediaPlayer; + + playlist = new QMediaPlaylist(player); + playlist->addMedia(QUrl("http://example.com/myclip1.mp4")); + playlist->addMedia(QUrl("http://example.com/myclip2.mp4")); + + videoWidget = new QVideoWidget; + player->setVideoOutput(videoWidget); + + videoWidget->show(); + playlist->setCurrentIndex(1); + player->play(); + //! [Video widget] + + player->stop(); +} + +void VideoExample::VideoWidgetControl() +{ + //! [Video widget control] + QVideoWidgetControl *widgetControl = mediaService->requestControl(); + layout->addWidget(widgetControl->videoWidget()); + //! [Video widget control] +} + +void VideoExample::VideoGraphicsItem() +{ + //! [Video graphics item] + player = new QMediaPlayer(this); + + QGraphicsVideoItem *item = new QGraphicsVideoItem; + player->setVideoOutput(item); + graphicsView->scene()->addItem(item); + graphicsView->show(); + + player->setMedia(QUrl("http://example.com/myclip4.ogv")); + player->play(); + //! [Video graphics item] +} -- cgit v1.2.3 From 9cf77e3bb531320f3c982a88ee31df8a75482f13 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Mon, 12 May 2014 16:50:30 +0200 Subject: Improve documentation for the QMediaPlayer::bufferStatus property. The corresponding properties in the Audio and MediaPlayer QML elements are also updated. Change-Id: I7104d274d431e7712db2f045c375756e8c2ac03a Reviewed-by: Jerome Pasion --- src/imports/multimedia/qdeclarativeaudio.cpp | 20 ++++++++++++++++---- src/multimedia/playback/qmediaplayer.cpp | 8 +++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/imports/multimedia/qdeclarativeaudio.cpp b/src/imports/multimedia/qdeclarativeaudio.cpp index 37509b17e..83e420196 100644 --- a/src/imports/multimedia/qdeclarativeaudio.cpp +++ b/src/imports/multimedia/qdeclarativeaudio.cpp @@ -601,8 +601,14 @@ bool QDeclarativeAudio::hasVideo() const /*! \qmlproperty real QtMultimedia::Audio::bufferProgress - This property holds how much of the data buffer is currently filled, from 0.0 (empty) to 1.0 - (full). + This property holds how much of the data buffer is currently filled, from \c 0.0 (empty) to + \c 1.0 (full). + + Playback can start or resume only when the buffer is entirely filled, in which case the + status is \c Audio.Buffered or \c Audio.Buffering. A value lower than \c 1.0 implies that + the status is \c Audio.Stalled. + + \sa status */ /*! @@ -1394,8 +1400,14 @@ void QDeclarativeAudio::_q_statusChanged() /*! \qmlproperty real QtMultimedia::MediaPlayer::bufferProgress - This property holds how much of the data buffer is currently filled, from 0.0 (empty) to 1.0 - (full). + This property holds how much of the data buffer is currently filled, from \c 0.0 (empty) to + \c 1.0 (full). + + Playback can start or resume only when the buffer is entirely filled, in which case the + status is \c MediaPlayer.Buffered or \c MediaPlayer.Buffering. A value lower than \c 1.0 + implies that the status is \c MediaPlayer.Stalled. + + \sa status */ /*! diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp index bf6294a1e..cb054fe52 100644 --- a/src/multimedia/playback/qmediaplayer.cpp +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -1238,12 +1238,14 @@ QMultimedia::AvailabilityStatus QMediaPlayer::availability() const /*! \property QMediaPlayer::bufferStatus - \brief the percentage of the temporary buffer filled before playback begins. + \brief the percentage of the temporary buffer filled before playback begins or resumes, from + \c 0 (empty) to \c 100 (full). When the player object is buffering; this property holds the percentage of the temporary buffer that is filled. The buffer will need to reach 100% - filled before playback can resume, at which time the MediaStatus will be - BufferedMedia. + filled before playback can start or resume, at which time mediaStatus() will return + BufferedMedia or BufferingMedia. If the value is anything lower than \c 100, mediaStatus() will + return StalledMedia. \sa mediaStatus() */ -- cgit v1.2.3 From c376e13abdcce32e65512db1236cb4b41d4fa1ea Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Wed, 14 May 2014 04:18:16 +0000 Subject: Fix QSGVideoNode rendering of frames with stride != width. Adjust texture coordinates to not render padding at the end of lines, and better calculate the stride of UV planes. Task-number: QTBUG-38218 Task-number: QTBUG-30447 Change-Id: I7b7577979719c48460b838f7dcc89b9d17741f79 Reviewed-by: Yoann Lopes --- src/qtmultimediaquicktools/qsgvideonode_i420.cpp | 56 ++++++++++++++++++------ src/qtmultimediaquicktools/qsgvideonode_rgb.cpp | 35 +++++++++++++-- 2 files changed, 73 insertions(+), 18 deletions(-) diff --git a/src/qtmultimediaquicktools/qsgvideonode_i420.cpp b/src/qtmultimediaquicktools/qsgvideonode_i420.cpp index d7eb04863..2d84f6ed1 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_i420.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_i420.cpp @@ -87,11 +87,15 @@ protected: virtual const char *vertexShader() const { const char *shader = "uniform highp mat4 qt_Matrix; \n" + "uniform highp float yWidth; \n" + "uniform highp float uvWidth; \n" "attribute highp vec4 qt_VertexPosition; \n" "attribute highp vec2 qt_VertexTexCoord; \n" - "varying highp vec2 qt_TexCoord; \n" + "varying highp vec2 yTexCoord; \n" + "varying highp vec2 uvTexCoord; \n" "void main() { \n" - " qt_TexCoord = qt_VertexTexCoord; \n" + " yTexCoord = qt_VertexTexCoord * vec2(yWidth, 1);\n" + " uvTexCoord = qt_VertexTexCoord * vec2(uvWidth, 1);\n" " gl_Position = qt_Matrix * qt_VertexPosition; \n" "}"; return shader; @@ -105,13 +109,14 @@ protected: "uniform mediump mat4 colorMatrix;" "uniform lowp float opacity;" "" - "varying highp vec2 qt_TexCoord;" + "varying highp vec2 yTexCoord;" + "varying highp vec2 uvTexCoord;" "" "void main()" "{" - " mediump float Y = texture2D(yTexture, qt_TexCoord).r;" - " mediump float U = texture2D(uTexture, qt_TexCoord).r;" - " mediump float V = texture2D(vTexture, qt_TexCoord).r;" + " mediump float Y = texture2D(yTexture, yTexCoord).r;" + " mediump float U = texture2D(uTexture, uvTexCoord).r;" + " mediump float V = texture2D(vTexture, uvTexCoord).r;" " mediump vec4 color = vec4(Y, U, V, 1.);" " gl_FragColor = colorMatrix * color * opacity;" "}"; @@ -120,6 +125,8 @@ protected: virtual void initialize() { m_id_matrix = program()->uniformLocation("qt_Matrix"); + m_id_yWidth = program()->uniformLocation("yWidth"); + m_id_uvWidth = program()->uniformLocation("uvWidth"); m_id_yTexture = program()->uniformLocation("yTexture"); m_id_uTexture = program()->uniformLocation("uTexture"); m_id_vTexture = program()->uniformLocation("vTexture"); @@ -128,6 +135,8 @@ protected: } int m_id_matrix; + int m_id_yWidth; + int m_id_uvWidth; int m_id_yTexture; int m_id_uTexture; int m_id_vTexture; @@ -181,6 +190,8 @@ public: GLuint m_textureIds[Num_Texture_IDs]; qreal m_opacity; + GLfloat m_yWidth; + GLfloat m_uvWidth; QMatrix4x4 m_colorMatrix; QVideoFrame m_frame; @@ -189,7 +200,9 @@ public: QSGVideoMaterial_YUV420::QSGVideoMaterial_YUV420(const QVideoSurfaceFormat &format) : m_format(format), - m_opacity(1.0) + m_opacity(1.0), + m_yWidth(1.0), + m_uvWidth(1.0) { memset(m_textureIds, 0, sizeof(m_textureIds)); @@ -245,21 +258,34 @@ void QSGVideoMaterial_YUV420::bind() } const uchar *bits = m_frame.bits(); - int bpl = m_frame.bytesPerLine(); - int bpl2 = (bpl / 2 + 3) & ~3; - int offsetU = bpl * fh; - int offsetV = bpl * fh + bpl2 * fh / 2; + int yStride = m_frame.bytesPerLine(); + // The UV stride is usually half the Y stride and is 32-bit aligned. + // However it's not always the case, at least on Windows where the + // UV planes are sometimes not aligned. + // We calculate the stride using the UV byte count to always + // have a correct stride. + int uvStride = (m_frame.mappedBytes() - yStride * fh) / fh; + int offsetU = yStride * fh; + int offsetV = yStride * fh + uvStride * fh / 2; + + m_yWidth = qreal(fw) / yStride; + m_uvWidth = qreal(fw) / (2 * uvStride); if (m_frame.pixelFormat() == QVideoFrame::Format_YV12) qSwap(offsetU, offsetV); + GLint previousAlignment; + glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousAlignment); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); functions->glActiveTexture(GL_TEXTURE1); - bindTexture(m_textureIds[1], fw/2, fh / 2, bits + offsetU); + bindTexture(m_textureIds[1], uvStride, fh / 2, bits + offsetU); functions->glActiveTexture(GL_TEXTURE2); - bindTexture(m_textureIds[2], fw/2, fh / 2, bits + offsetV); + bindTexture(m_textureIds[2], uvStride, fh / 2, bits + offsetV); functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit - bindTexture(m_textureIds[0], fw, fh, bits); + bindTexture(m_textureIds[0], yStride, fh, bits); + + glPixelStorei(GL_UNPACK_ALIGNMENT, previousAlignment); m_frame.unmap(); } @@ -318,6 +344,8 @@ void QSGVideoMaterialShader_YUV420::updateState(const RenderState &state, mat->bind(); program()->setUniformValue(m_id_colorMatrix, mat->m_colorMatrix); + program()->setUniformValue(m_id_yWidth, mat->m_yWidth); + program()->setUniformValue(m_id_uvWidth, mat->m_uvWidth); if (state.isOpacityDirty()) { mat->m_opacity = state.opacity(); program()->setUniformValue(m_id_opacity, GLfloat(mat->m_opacity)); diff --git a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp index fbe60c9a7..ad01a08ae 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp @@ -79,6 +79,7 @@ public: QSGVideoMaterialShader_RGB(QVideoFrame::PixelFormat pixelFormat) : QSGMaterialShader(), m_id_matrix(-1), + m_id_width(-1), m_id_rgbTexture(-1), m_id_opacity(-1), m_pixelFormat(pixelFormat) @@ -101,11 +102,12 @@ protected: virtual const char *vertexShader() const { const char *shader = "uniform highp mat4 qt_Matrix; \n" + "uniform highp float width; \n" "attribute highp vec4 qt_VertexPosition; \n" "attribute highp vec2 qt_VertexTexCoord; \n" "varying highp vec2 qt_TexCoord; \n" "void main() { \n" - " qt_TexCoord = qt_VertexTexCoord; \n" + " qt_TexCoord = qt_VertexTexCoord * vec2(width, 1);\n" " gl_Position = qt_Matrix * qt_VertexPosition; \n" "}"; return shader; @@ -146,11 +148,13 @@ protected: virtual void initialize() { m_id_matrix = program()->uniformLocation("qt_Matrix"); + m_id_width = program()->uniformLocation("width"); m_id_rgbTexture = program()->uniformLocation("rgbTexture"); m_id_opacity = program()->uniformLocation("opacity"); } int m_id_matrix; + int m_id_width; int m_id_rgbTexture; int m_id_opacity; QVideoFrame::PixelFormat m_pixelFormat; @@ -163,7 +167,8 @@ public: QSGVideoMaterial_RGB(const QVideoSurfaceFormat &format) : m_format(format), m_textureId(0), - m_opacity(1.0) + m_opacity(1.0), + m_width(1.0) { setFlag(Blending, false); } @@ -204,11 +209,25 @@ public: QMutexLocker lock(&m_frameMutex); if (m_frame.isValid()) { if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) { - if (m_textureSize != m_frame.size()) { + QSize textureSize = m_frame.size(); + + int stride = m_frame.bytesPerLine(); + switch (m_frame.pixelFormat()) { + case QVideoFrame::Format_RGB565: + stride /= 2; + break; + default: + stride /= 4; + } + + m_width = qreal(m_frame.width() / stride); + textureSize.setWidth(stride); + + if (m_textureSize != textureSize) { if (!m_textureSize.isEmpty()) glDeleteTextures(1, &m_textureId); glGenTextures(1, &m_textureId); - m_textureSize = m_frame.size(); + m_textureSize = textureSize; } GLint dataType = GL_UNSIGNED_BYTE; @@ -219,12 +238,18 @@ public: dataFormat = GL_RGB; } + GLint previousAlignment; + glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousAlignment); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + functions->glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_textureId); glTexImage2D(GL_TEXTURE_2D, 0, dataFormat, m_textureSize.width(), m_textureSize.height(), 0, dataFormat, dataType, m_frame.bits()); + glPixelStorei(GL_UNPACK_ALIGNMENT, previousAlignment); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -245,6 +270,7 @@ public: QVideoSurfaceFormat m_format; GLuint m_textureId; qreal m_opacity; + GLfloat m_width; }; @@ -276,6 +302,7 @@ void QSGVideoMaterialShader_RGB::updateState(const RenderState &state, mat->bind(); + program()->setUniformValue(m_id_width, mat->m_width); if (state.isOpacityDirty()) { mat->m_opacity = state.opacity(); mat->updateBlending(); -- cgit v1.2.3 From 235c863db9c495e820fe7ac53918e74f342b71e6 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Mon, 12 May 2014 17:21:52 +0200 Subject: Android: fix QMediaPlayer::bufferStatus value. It was returning the buffering progress for the whole media, which is not what is expected according to the documentation. It should return instead how much the playback buffer is filled. This information is not available on Android so we simply return 100% when the status is BufferedMedia or BufferingMedia, 0% otherwise. Change-Id: I9fb55a9317948ba9375291a57bbf100f186382a2 Reviewed-by: Christian Stromme --- .../src/mediaplayer/qandroidmediaplayercontrol.cpp | 18 +++++++++++++++--- .../src/mediaplayer/qandroidmediaplayercontrol.h | 2 ++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp index f5614a57a..23ffb320c 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp @@ -54,6 +54,7 @@ QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent) mVideoOutput(0), mSeekable(true), mBufferPercent(-1), + mBufferFilled(false), mAudioAvailable(false), mVideoAvailable(false), mBuffering(false), @@ -221,7 +222,7 @@ void QAndroidMediaPlayerControl::setMuted(bool muted) int QAndroidMediaPlayerControl::bufferStatus() const { - return mBufferPercent; + return mBufferFilled ? 100 : 0; } bool QAndroidMediaPlayerControl::isAudioAvailable() const @@ -487,7 +488,6 @@ void QAndroidMediaPlayerControl::onBufferingChanged(qint32 percent) { mBuffering = percent != 100; mBufferPercent = percent; - Q_EMIT bufferStatusChanged(mBufferPercent); updateAvailablePlaybackRanges(); @@ -621,6 +621,8 @@ void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status mCurrentMediaStatus = status; Q_EMIT mediaStatusChanged(mCurrentMediaStatus); + + updateBufferStatus(); } void QAndroidMediaPlayerControl::setSeekable(bool seekable) @@ -658,7 +660,6 @@ void QAndroidMediaPlayerControl::resetBufferingProgress() mBuffering = false; mBufferPercent = 0; mAvailablePlaybackRange = QMediaTimeRange(); - Q_EMIT bufferStatusChanged(mBufferPercent); } void QAndroidMediaPlayerControl::flushPendingStates() @@ -694,4 +695,15 @@ void QAndroidMediaPlayerControl::flushPendingStates() } } +void QAndroidMediaPlayerControl::updateBufferStatus() +{ + bool bufferFilled = (mCurrentMediaStatus == QMediaPlayer::BufferedMedia + || mCurrentMediaStatus == QMediaPlayer::BufferingMedia); + + if (mBufferFilled != bufferFilled) { + mBufferFilled = bufferFilled; + Q_EMIT bufferStatusChanged(bufferStatus()); + } +} + QT_END_NAMESPACE diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h index 1be3b4428..27e6afc12 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h @@ -106,6 +106,7 @@ private: QAndroidVideoOutput *mVideoOutput; bool mSeekable; int mBufferPercent; + bool mBufferFilled; bool mAudioAvailable; bool mVideoAvailable; QSize mVideoSize; @@ -127,6 +128,7 @@ private: void updateAvailablePlaybackRanges(); void resetBufferingProgress(); void flushPendingStates(); + void updateBufferStatus(); }; QT_END_NAMESPACE -- cgit v1.2.3 From e9e10b2b1f025c3aa53a8904ec0a65e88fcb2887 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 14 May 2014 18:45:37 +0200 Subject: WMF: fix video frames' viewport. It was not taken into account at all. Change-Id: I4ce85aba214cb4d89dcd018b1616a2a38094b5a6 Reviewed-by: Christian Stromme --- src/plugins/wmf/player/mfvideorenderercontrol.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp index 040682965..420473666 100644 --- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp +++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp @@ -572,6 +572,18 @@ namespace QVideoSurfaceFormat format(QSize(width, height), m_pixelFormats[index]); m_surfaceFormat = format; + MFVideoArea viewport; + if (SUCCEEDED(pMediaType->GetBlob(MF_MT_GEOMETRIC_APERTURE, + reinterpret_cast(&viewport), + sizeof(MFVideoArea), + NULL))) { + + m_surfaceFormat.setViewport(QRect(viewport.OffsetX.value, + viewport.OffsetY.value, + viewport.Area.cx, + viewport.Area.cy)); + } + if (FAILED(pMediaType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&m_bytesPerLine))) { m_bytesPerLine = getBytesPerLine(format); } -- cgit v1.2.3 From 93e73fd8eeccfd42430acaa760bdeb8dc6f17f39 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Mon, 19 May 2014 14:34:57 +0200 Subject: DirectShow: remove debug output. Task-number: QTBUG-38924 Change-Id: Ibc08fd99f6eb10035e4d7da963d4d384012bbdbf Reviewed-by: Mitch Curtis --- src/plugins/directshow/player/directshowiosource.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/plugins/directshow/player/directshowiosource.cpp b/src/plugins/directshow/player/directshowiosource.cpp index acce1de28..c6cb21824 100644 --- a/src/plugins/directshow/player/directshowiosource.cpp +++ b/src/plugins/directshow/player/directshowiosource.cpp @@ -622,17 +622,10 @@ DirectShowRcSource::DirectShowRcSource(DirectShowEventLoop *loop) bool DirectShowRcSource::open(const QUrl &url) { m_file.moveToThread(QCoreApplication::instance()->thread()); - m_file.setFileName(QLatin1Char(':') + url.path()); - qDebug("qrc file %s", qPrintable(m_file.fileName())); - if (m_file.open(QIODevice::ReadOnly)) { - qDebug("Size %d", int(m_file.size())); - qDebug("Sequential %d", int(m_file.isSequential())); - setDevice(&m_file); - return true; } else { return false; -- cgit v1.2.3 From 7e668fe58fc9546eb91bbf39992566f709b5e6c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Fri, 16 May 2014 14:53:13 +0200 Subject: Android: Fix loading from qrc On Android < 4.1 our temporary file is discarded without checking the content. With this change we just open the file and pass the fd to the mediaplayer instead. Change-Id: I9233822725d8987c572b2d0b598721cee886de80 Reviewed-by: Yoann Lopes --- .../org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java | 5 +++++ src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java index 86ec30a5f..01f260910 100644 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java @@ -43,6 +43,7 @@ package org.qtproject.qt5.android.multimedia; import java.io.IOException; import java.lang.String; +import java.io.FileInputStream; // API is level is < 9 unless marked otherwise. import android.app.Activity; @@ -387,6 +388,10 @@ public class QtAndroidMediaPlayer final long length = afd.getLength(); FileDescriptor fd = afd.getFileDescriptor(); mMediaPlayer.setDataSource(fd, offset, length); + } else if (mUri.getScheme().compareTo("tempfile") == 0) { + FileInputStream fis = new FileInputStream(mUri.getPath()); + FileDescriptor fd = fis.getFD(); + mMediaPlayer.setDataSource(fd); } else { mMediaPlayer.setDataSource(mActivity, mUri); } diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp index 23ffb320c..68fb5e473 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp @@ -312,7 +312,7 @@ void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent, const QString path = url.toString().mid(3); mTempFile.reset(QTemporaryFile::createNativeFile(path)); if (!mTempFile.isNull()) - mediaPath = QLatin1String("file://") + mTempFile->fileName(); + mediaPath = QLatin1String("tempfile://") + mTempFile->fileName(); } else { mediaPath = url.toString(); } -- cgit v1.2.3 From 92096afdb496eaf5c4458155f7b1740a0dbb68bf Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Mon, 19 May 2014 12:48:59 +0200 Subject: Android: fix calling start() and stop() on the video surface. We restart the surface when the frame size changes, though we were not using the correct function to get the surface's current frame size. This was causing start() and stop() to be called for every frame. Change-Id: I8ff4b4852cb7fcc92ac3b1b3ad7bf991d7bddc6b Reviewed-by: Christian Stromme --- src/plugins/android/src/common/qandroidvideorendercontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/android/src/common/qandroidvideorendercontrol.cpp b/src/plugins/android/src/common/qandroidvideorendercontrol.cpp index 5f14a4691..1891e9d10 100644 --- a/src/plugins/android/src/common/qandroidvideorendercontrol.cpp +++ b/src/plugins/android/src/common/qandroidvideorendercontrol.cpp @@ -267,7 +267,7 @@ void QAndroidVideoRendererControl::onFrameAvailable() QVideoFrame frame(buffer, m_nativeSize, QVideoFrame::Format_BGR32); if (m_surface->isActive() && (m_surface->surfaceFormat().pixelFormat() != frame.pixelFormat() - || m_surface->nativeResolution() != frame.size())) { + || m_surface->surfaceFormat().frameSize() != frame.size())) { m_surface->stop(); } -- cgit v1.2.3 From 69598e22f36b5e65cc7c979d1aee002ac564da5a Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Mon, 19 May 2014 14:09:23 +0200 Subject: Remove C++11 code in iMX6 video node plugin. Use Q_FOREACH instead of C++11 range-based For loops. Task-number: QTBUG-38900 Change-Id: I2b9f8444f2ac3ae71811112244c687cab79753c9 Reviewed-by: Thomas Senyk Reviewed-by: Laszlo Agocs --- src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp index 44f9f4d12..0f3dd59f8 100644 --- a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp @@ -70,7 +70,7 @@ QSGVivanteVideoMaterial::QSGVivanteVideoMaterial() : QSGVivanteVideoMaterial::~QSGVivanteVideoMaterial() { - for (GLuint id : mBitsToTextureMap.values()) { + Q_FOREACH (GLuint id, mBitsToTextureMap.values()) { #ifdef QT_VIVANTE_VIDEO_DEBUG qDebug() << "delete texture: " << id; #endif @@ -154,7 +154,7 @@ GLuint QSGVivanteVideoMaterial::vivanteMapping(QVideoFrame vF) mWidth = vF.width(); mHeight = vF.height(); mFormat = vF.pixelFormat(); - for (GLuint id : mBitsToTextureMap.values()) { + Q_FOREACH (GLuint id, mBitsToTextureMap.values()) { #ifdef QT_VIVANTE_VIDEO_DEBUG qDebug() << "delete texture: " << id; #endif -- cgit v1.2.3 From 5a0e49369da7ac04c9bd9eb089a4b001f6a13278 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 21 May 2014 12:47:03 +0200 Subject: OpenSL: don't try to enqueue new buffers when the buffer queue is full. It could lead to corrupted sound since we were overwritting buffers that weren't played yet. Task-number: QTBUG-39015 Change-Id: I4c015c5383b813955998145d6316acc8c22f19a3 Reviewed-by: jian liang Reviewed-by: Christian Stromme --- src/plugins/opensles/qopenslesaudiooutput.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/opensles/qopenslesaudiooutput.cpp b/src/plugins/opensles/qopenslesaudiooutput.cpp index df91e6ff1..49bea0b36 100644 --- a/src/plugins/opensles/qopenslesaudiooutput.cpp +++ b/src/plugins/opensles/qopenslesaudiooutput.cpp @@ -568,7 +568,7 @@ void QOpenSLESAudioOutput::destroyPlayer() qint64 QOpenSLESAudioOutput::writeData(const char *data, qint64 len) { - if (!len) + if (!len || !m_availableBuffers.load()) return 0; if (len > m_bufferSize) -- cgit v1.2.3 From efa4628e7489677166aadde5f94376d5e41146f9 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Mon, 26 May 2014 16:20:49 +0200 Subject: Use Q_CONSTRUCTOR_FUNCTION macro to register multimedia meta types. Task-number: QTBUG-39131 Change-Id: I2493c9e3e6f0065d0441a74ff240d7d91fbe059c Reviewed-by: Christian Stromme --- src/multimedia/audio/qaudio.cpp | 20 +++++---------- src/multimedia/audio/qaudiobuffer.cpp | 14 ++++------- src/multimedia/audio/qaudiodecoder.cpp | 15 ++++------- src/multimedia/audio/qaudiodeviceinfo.cpp | 13 +++------- src/multimedia/audio/qaudioformat.cpp | 16 ++++-------- src/multimedia/camera/qcamera.cpp | 29 +++++++++------------- src/multimedia/camera/qcameraexposure.cpp | 16 ++++-------- src/multimedia/camera/qcamerafocus.cpp | 16 +++++------- src/multimedia/camera/qcameraimagecapture.cpp | 17 +++++-------- src/multimedia/camera/qcameraimageprocessing.cpp | 13 +++------- .../controls/qcameraimageprocessingcontrol.cpp | 13 +++------- src/multimedia/controls/qmediastreamscontrol.cpp | 14 ++++------- src/multimedia/playback/qmediacontent.cpp | 13 +++------- src/multimedia/playback/qmediaplayer.cpp | 18 ++++++-------- src/multimedia/playback/qmediaplaylist.cpp | 17 +++++-------- src/multimedia/playback/qmediaresource.cpp | 18 ++++++-------- src/multimedia/qmultimedia.cpp | 20 ++++++--------- src/multimedia/radio/qradiodata.cpp | 17 +++++-------- src/multimedia/radio/qradiotuner.cpp | 23 +++++++---------- src/multimedia/recording/qmediaencodersettings.cpp | 18 ++++++-------- src/multimedia/recording/qmediarecorder.cpp | 18 ++++++-------- src/multimedia/video/qabstractvideobuffer.cpp | 16 +++++------- src/multimedia/video/qabstractvideosurface.cpp | 13 +++------- src/multimedia/video/qvideoframe.cpp | 17 +++++-------- src/multimedia/video/qvideosurfaceformat.cpp | 17 +++++-------- 25 files changed, 150 insertions(+), 271 deletions(-) diff --git a/src/multimedia/audio/qaudio.cpp b/src/multimedia/audio/qaudio.cpp index 13cc2947f..5039729be 100644 --- a/src/multimedia/audio/qaudio.cpp +++ b/src/multimedia/audio/qaudio.cpp @@ -45,23 +45,15 @@ QT_BEGIN_NAMESPACE -namespace QAudio +static void qRegisterAudioMetaTypes() { - -class RegisterMetaTypes -{ -public: - RegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - } - -} _register; - + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterAudioMetaTypes) + /*! \namespace QAudio \brief The QAudio namespace contains enums used by the audio classes. diff --git a/src/multimedia/audio/qaudiobuffer.cpp b/src/multimedia/audio/qaudiobuffer.cpp index 586ab4490..3d7346a97 100644 --- a/src/multimedia/audio/qaudiobuffer.cpp +++ b/src/multimedia/audio/qaudiobuffer.cpp @@ -47,18 +47,14 @@ QT_BEGIN_NAMESPACE -namespace + +static void qRegisterAudioBufferMetaTypes() { - class QAudioBufferPrivateRegisterMetaTypes - { - public: - QAudioBufferPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterAudioBufferMetaTypes) + class QAudioBufferPrivate : public QSharedData { diff --git a/src/multimedia/audio/qaudiodecoder.cpp b/src/multimedia/audio/qaudiodecoder.cpp index 3f0fcd4dd..9397d7419 100644 --- a/src/multimedia/audio/qaudiodecoder.cpp +++ b/src/multimedia/audio/qaudiodecoder.cpp @@ -72,19 +72,14 @@ QT_BEGIN_NAMESPACE \sa QAudioBuffer */ -namespace +static void qRegisterAudioDecoderMetaTypes() { -class AudioDecoderRegisterMetaTypes -{ -public: - AudioDecoderRegisterMetaTypes() - { - qRegisterMetaType("QAudioDecoder::State"); - qRegisterMetaType("QAudioDecoder::Error"); - } -} _registerPlayerMetaTypes; + qRegisterMetaType("QAudioDecoder::State"); + qRegisterMetaType("QAudioDecoder::Error"); } +Q_CONSTRUCTOR_FUNCTION(qRegisterAudioDecoderMetaTypes) + class QAudioDecoderPrivate : public QMediaObjectPrivate { Q_DECLARE_NON_CONST_PUBLIC(QAudioDecoder) diff --git a/src/multimedia/audio/qaudiodeviceinfo.cpp b/src/multimedia/audio/qaudiodeviceinfo.cpp index ff31f3534..ca42373e2 100644 --- a/src/multimedia/audio/qaudiodeviceinfo.cpp +++ b/src/multimedia/audio/qaudiodeviceinfo.cpp @@ -47,18 +47,13 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterAudioDeviceInfoMetaTypes() { - class QAudioInfoPrivateRegisterMetaTypes - { - public: - QAudioInfoPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterAudioDeviceInfoMetaTypes) + class QAudioDeviceInfoPrivate : public QSharedData { public: diff --git a/src/multimedia/audio/qaudioformat.cpp b/src/multimedia/audio/qaudioformat.cpp index b83256a10..6992bf992 100644 --- a/src/multimedia/audio/qaudioformat.cpp +++ b/src/multimedia/audio/qaudioformat.cpp @@ -44,20 +44,14 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterAudioFormatMetaTypes() { - class QAudioFormatPrivateRegisterMetaTypes - { - public: - QAudioFormatPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterAudioFormatMetaTypes) class QAudioFormatPrivate : public QSharedData { diff --git a/src/multimedia/camera/qcamera.cpp b/src/multimedia/camera/qcamera.cpp index 32bab0019..84833c6a3 100644 --- a/src/multimedia/camera/qcamera.cpp +++ b/src/multimedia/camera/qcamera.cpp @@ -56,26 +56,21 @@ #include -namespace -{ -class CameraRegisterMetaTypes +QT_BEGIN_NAMESPACE + +static void qRegisterCameraMetaTypes() { -public: - CameraRegisterMetaTypes() - { - qRegisterMetaType("QCamera::Error"); - qRegisterMetaType("QCamera::State"); - qRegisterMetaType("QCamera::Status"); - qRegisterMetaType("QCamera::CaptureModes"); - qRegisterMetaType("QCamera::LockType"); - qRegisterMetaType("QCamera::LockStatus"); - qRegisterMetaType("QCamera::LockChangeReason"); - qRegisterMetaType("QCamera::Position"); - } -} _registerCameraMetaTypes; + qRegisterMetaType("QCamera::Error"); + qRegisterMetaType("QCamera::State"); + qRegisterMetaType("QCamera::Status"); + qRegisterMetaType("QCamera::CaptureModes"); + qRegisterMetaType("QCamera::LockType"); + qRegisterMetaType("QCamera::LockStatus"); + qRegisterMetaType("QCamera::LockChangeReason"); + qRegisterMetaType("QCamera::Position"); } -QT_BEGIN_NAMESPACE +Q_CONSTRUCTOR_FUNCTION(qRegisterCameraMetaTypes) /*! \class QCamera diff --git a/src/multimedia/camera/qcameraexposure.cpp b/src/multimedia/camera/qcameraexposure.cpp index 4385cd4a4..7f1ef842a 100644 --- a/src/multimedia/camera/qcameraexposure.cpp +++ b/src/multimedia/camera/qcameraexposure.cpp @@ -65,20 +65,14 @@ QT_BEGIN_NAMESPACE //#define DEBUG_EXPOSURE_CHANGES 1 -namespace +static void qRegisterCameraExposureMetaTypes() { -class CameraExposureRegisterMetaTypes -{ -public: - CameraExposureRegisterMetaTypes() - { - qRegisterMetaType("QCameraExposure::ExposureMode"); - qRegisterMetaType("QCameraExposure::FlashModes"); - qRegisterMetaType("QCameraExposure::MeteringMode"); - } -} _registerCameraExposureMetaTypes; + qRegisterMetaType("QCameraExposure::ExposureMode"); + qRegisterMetaType("QCameraExposure::FlashModes"); + qRegisterMetaType("QCameraExposure::MeteringMode"); } +Q_CONSTRUCTOR_FUNCTION(qRegisterCameraExposureMetaTypes) class QCameraExposurePrivate diff --git a/src/multimedia/camera/qcamerafocus.cpp b/src/multimedia/camera/qcamerafocus.cpp index cae285167..0b6d331b4 100644 --- a/src/multimedia/camera/qcamerafocus.cpp +++ b/src/multimedia/camera/qcamerafocus.cpp @@ -55,19 +55,15 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterCameraFocusMetaTypes() { -class CameraFocusRegisterMetaTypes -{ -public: - CameraFocusRegisterMetaTypes() - { - qRegisterMetaType("QCameraFocus::FocusModes"); - qRegisterMetaType("QCameraFocus::FocusPointMode"); - } -} _registerCameraFocusMetaTypes; + qRegisterMetaType("QCameraFocus::FocusModes"); + qRegisterMetaType("QCameraFocus::FocusPointMode"); } +Q_CONSTRUCTOR_FUNCTION(qRegisterCameraFocusMetaTypes) + + class QCameraFocusFakeZoomControl : public QCameraZoomControl { public: diff --git a/src/multimedia/camera/qcameraimagecapture.cpp b/src/multimedia/camera/qcameraimagecapture.cpp index 409db4947..400c2b925 100644 --- a/src/multimedia/camera/qcameraimagecapture.cpp +++ b/src/multimedia/camera/qcameraimagecapture.cpp @@ -83,20 +83,15 @@ QT_BEGIN_NAMESPACE \value CaptureToBuffer Capture the image to a buffer for further processing. */ -namespace +static void qRegisterCameraImageCaptureMetaTypes() { -class MediaRecorderRegisterMetaTypes -{ -public: - MediaRecorderRegisterMetaTypes() - { - qRegisterMetaType("QCameraImageCapture::Error"); - qRegisterMetaType("QCameraImageCapture::CaptureDestination"); - qRegisterMetaType("QCameraImageCapture::CaptureDestinations"); - } -} _registerRecorderMetaTypes; + qRegisterMetaType("QCameraImageCapture::Error"); + qRegisterMetaType("QCameraImageCapture::CaptureDestination"); + qRegisterMetaType("QCameraImageCapture::CaptureDestinations"); } +Q_CONSTRUCTOR_FUNCTION(qRegisterCameraImageCaptureMetaTypes) + class QCameraImageCapturePrivate { diff --git a/src/multimedia/camera/qcameraimageprocessing.cpp b/src/multimedia/camera/qcameraimageprocessing.cpp index 7df222458..6f08b7860 100644 --- a/src/multimedia/camera/qcameraimageprocessing.cpp +++ b/src/multimedia/camera/qcameraimageprocessing.cpp @@ -52,20 +52,15 @@ #include -namespace -{ - class QCameraImageProcessingPrivateRegisterMetaTypes - { - public: - QCameraImageProcessingPrivateRegisterMetaTypes() +QT_BEGIN_NAMESPACE + +static void qRegisterCameraImageProcessingMetaTypes() { qRegisterMetaType(); } - } _registerMetaTypes; -} +Q_CONSTRUCTOR_FUNCTION(qRegisterCameraImageProcessingMetaTypes) -QT_BEGIN_NAMESPACE /*! \class QCameraImageProcessing diff --git a/src/multimedia/controls/qcameraimageprocessingcontrol.cpp b/src/multimedia/controls/qcameraimageprocessingcontrol.cpp index f9cb8c86f..944b09643 100644 --- a/src/multimedia/controls/qcameraimageprocessingcontrol.cpp +++ b/src/multimedia/controls/qcameraimageprocessingcontrol.cpp @@ -44,18 +44,13 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterCameraImageProcessingControlMetaTypes() { - class QCameraImageProcessingControlPrivateRegisterMetaTypes - { - public: - QCameraImageProcessingControlPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterCameraImageProcessingControlMetaTypes) + /*! \class QCameraImageProcessingControl \inmodule QtMultimedia diff --git a/src/multimedia/controls/qmediastreamscontrol.cpp b/src/multimedia/controls/qmediastreamscontrol.cpp index a054289f7..11d31599d 100644 --- a/src/multimedia/controls/qmediastreamscontrol.cpp +++ b/src/multimedia/controls/qmediastreamscontrol.cpp @@ -44,18 +44,14 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterMediaStreamControlMetaTypes() { - class QMediaStreamsControlPrivateRegisterMetaTypes - { - public: - QMediaStreamsControlPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterMediaStreamControlMetaTypes) + + /*! \class QMediaStreamsControl \inmodule QtMultimedia diff --git a/src/multimedia/playback/qmediacontent.cpp b/src/multimedia/playback/qmediacontent.cpp index 4c32128f5..ff3ed28d3 100644 --- a/src/multimedia/playback/qmediacontent.cpp +++ b/src/multimedia/playback/qmediacontent.cpp @@ -48,18 +48,13 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterMediaContentMetaTypes() { - class QMediaContentPrivateRegisterMetaTypes - { - public: - QMediaContentPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterMediaContentMetaTypes) + class QMediaContentPrivate : public QSharedData { diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp index cb054fe52..e8899ddff 100644 --- a/src/multimedia/playback/qmediaplayer.cpp +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -90,20 +90,16 @@ QT_BEGIN_NAMESPACE \sa QMediaObject, QMediaService, QVideoWidget, QMediaPlaylist */ -namespace +static void qRegisterMediaPlayerMetaTypes() { -class MediaPlayerRegisterMetaTypes -{ -public: - MediaPlayerRegisterMetaTypes() - { - qRegisterMetaType("QMediaPlayer::State"); - qRegisterMetaType("QMediaPlayer::MediaStatus"); - qRegisterMetaType("QMediaPlayer::Error"); - } -} _registerPlayerMetaTypes; + qRegisterMetaType("QMediaPlayer::State"); + qRegisterMetaType("QMediaPlayer::MediaStatus"); + qRegisterMetaType("QMediaPlayer::Error"); } +Q_CONSTRUCTOR_FUNCTION(qRegisterMediaPlayerMetaTypes) + + #define MAX_NESTED_PLAYLISTS 16 class QMediaPlayerPrivate : public QMediaObjectPrivate diff --git a/src/multimedia/playback/qmediaplaylist.cpp b/src/multimedia/playback/qmediaplaylist.cpp index 68a8917f5..a81681079 100644 --- a/src/multimedia/playback/qmediaplaylist.cpp +++ b/src/multimedia/playback/qmediaplaylist.cpp @@ -61,19 +61,14 @@ QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, playlistIOLoader, (QMediaPlaylistIOInterface_iid, QLatin1String("playlistformats"), Qt::CaseInsensitive)) -namespace -{ - class QMediaPlaylistPrivateRegisterMetaTypes - { - public: - QMediaPlaylistPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - } - } _registerMetaTypes; +static void qRegisterMediaPlaylistMetaTypes() +{ + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterMediaPlaylistMetaTypes) + /*! \class QMediaPlaylist diff --git a/src/multimedia/playback/qmediaresource.cpp b/src/multimedia/playback/qmediaresource.cpp index 62c982ca7..4997620a9 100644 --- a/src/multimedia/playback/qmediaresource.cpp +++ b/src/multimedia/playback/qmediaresource.cpp @@ -47,19 +47,15 @@ QT_BEGIN_NAMESPACE -namespace -{ - class QMediaResourcePrivateRegisterMetaTypes - { - public: - QMediaResourcePrivateRegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - } - } _registerMetaTypes; +static void qRegisterMediaResourceMetaTypes() +{ + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterMediaResourceMetaTypes) + + /*! \class QMediaResource diff --git a/src/multimedia/qmultimedia.cpp b/src/multimedia/qmultimedia.cpp index 0f4d98f7f..140d4a348 100644 --- a/src/multimedia/qmultimedia.cpp +++ b/src/multimedia/qmultimedia.cpp @@ -41,21 +41,17 @@ QT_BEGIN_NAMESPACE */ -namespace +static void qRegisterMultimediaMetaTypes() { - class QMultimediaNamespacePrivateRegisterMetaTypes - { - public: - QMultimediaNamespacePrivateRegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterMultimediaMetaTypes) + + /*! \enum QMultimedia::SupportEstimate diff --git a/src/multimedia/radio/qradiodata.cpp b/src/multimedia/radio/qradiodata.cpp index 66b051a47..d6bde35ba 100644 --- a/src/multimedia/radio/qradiodata.cpp +++ b/src/multimedia/radio/qradiodata.cpp @@ -50,20 +50,15 @@ QT_BEGIN_NAMESPACE - -namespace +static void qRegisterRadioDataMetaTypes() { - class QRadioDataPrivateRegisterMetaTypes - { - public: - QRadioDataPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterRadioDataMetaTypes) + + /*! \class QRadioData \brief The QRadioData class provides interfaces to the RDS functionality of the system radio. diff --git a/src/multimedia/radio/qradiotuner.cpp b/src/multimedia/radio/qradiotuner.cpp index 9255783d0..29a0d6d37 100644 --- a/src/multimedia/radio/qradiotuner.cpp +++ b/src/multimedia/radio/qradiotuner.cpp @@ -52,22 +52,17 @@ QT_BEGIN_NAMESPACE -namespace -{ - class QRadioTunerPrivateRegisterMetaTypes - { - public: - QRadioTunerPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - } - } _registerMetaTypes; +static void qRegisterRadioTunerMetaTypes() +{ + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterRadioTunerMetaTypes) + /*! \class QRadioTuner diff --git a/src/multimedia/recording/qmediaencodersettings.cpp b/src/multimedia/recording/qmediaencodersettings.cpp index 731692643..e75115116 100644 --- a/src/multimedia/recording/qmediaencodersettings.cpp +++ b/src/multimedia/recording/qmediaencodersettings.cpp @@ -43,20 +43,16 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterEncoderSettingsMetaTypes() { -class QMediaEncoderSettingsPrivateRegisterMetaTypes -{ -public: - QMediaEncoderSettingsPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - } -} _registerMetaTypes; + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterEncoderSettingsMetaTypes) + + class QAudioEncoderSettingsPrivate : public QSharedData { public: diff --git a/src/multimedia/recording/qmediarecorder.cpp b/src/multimedia/recording/qmediarecorder.cpp index f38de025c..7c28caf98 100644 --- a/src/multimedia/recording/qmediarecorder.cpp +++ b/src/multimedia/recording/qmediarecorder.cpp @@ -80,20 +80,16 @@ QT_BEGIN_NAMESPACE \sa QAudioRecorder */ -namespace +static void qRegisterMediaRecorderMetaTypes() { -class MediaRecorderRegisterMetaTypes -{ -public: - MediaRecorderRegisterMetaTypes() - { - qRegisterMetaType("QMediaRecorder::State"); - qRegisterMetaType("QMediaRecorder::Status"); - qRegisterMetaType("QMediaRecorder::Error"); - } -} _registerRecorderMetaTypes; + qRegisterMetaType("QMediaRecorder::State"); + qRegisterMetaType("QMediaRecorder::Status"); + qRegisterMetaType("QMediaRecorder::Error"); } +Q_CONSTRUCTOR_FUNCTION(qRegisterMediaRecorderMetaTypes) + + QMediaRecorderPrivate::QMediaRecorderPrivate(): mediaObject(0), control(0), diff --git a/src/multimedia/video/qabstractvideobuffer.cpp b/src/multimedia/video/qabstractvideobuffer.cpp index 5f69382e3..79da6f9b7 100644 --- a/src/multimedia/video/qabstractvideobuffer.cpp +++ b/src/multimedia/video/qabstractvideobuffer.cpp @@ -48,19 +48,15 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterAbstractVideoBufferMetaTypes() { - class QAbstractVideoBufferPrivateRegisterMetaTypes - { - public: - QAbstractVideoBufferPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterAbstractVideoBufferMetaTypes) + + /*! \class QAbstractVideoBuffer \brief The QAbstractVideoBuffer class is an abstraction for video data. diff --git a/src/multimedia/video/qabstractvideosurface.cpp b/src/multimedia/video/qabstractvideosurface.cpp index e62c514d7..ff9356122 100644 --- a/src/multimedia/video/qabstractvideosurface.cpp +++ b/src/multimedia/video/qabstractvideosurface.cpp @@ -50,18 +50,13 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterAbstractVideoSurfaceMetaTypes() { - class QAbstractVideoSurfacePrivateRegisterMetaTypes - { - public: - QAbstractVideoSurfacePrivateRegisterMetaTypes() - { - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterAbstractVideoSurfaceMetaTypes) + class QAbstractVideoSurfacePrivate { public: diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp index 29f6e4731..ad81c80e7 100644 --- a/src/multimedia/video/qvideoframe.cpp +++ b/src/multimedia/video/qvideoframe.cpp @@ -55,20 +55,15 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterVideoFrameMetaTypes() { -class QVideoFramePrivateRegisterMetaTypes -{ -public: - QVideoFramePrivateRegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - } -} _registerMetaTypes; + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterVideoFrameMetaTypes) + class QVideoFramePrivate : public QSharedData { diff --git a/src/multimedia/video/qvideosurfaceformat.cpp b/src/multimedia/video/qvideosurfaceformat.cpp index 5806f3b9b..56814f478 100644 --- a/src/multimedia/video/qvideosurfaceformat.cpp +++ b/src/multimedia/video/qvideosurfaceformat.cpp @@ -49,20 +49,15 @@ QT_BEGIN_NAMESPACE -namespace +static void qRegisterVideoSurfaceFormatMetaTypes() { - class QVideoSurfaceFormatPrivateRegisterMetaTypes - { - public: - QVideoSurfaceFormatPrivateRegisterMetaTypes() - { - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - } - } _registerMetaTypes; + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); } +Q_CONSTRUCTOR_FUNCTION(qRegisterVideoSurfaceFormatMetaTypes) + class QVideoSurfaceFormatPrivate : public QSharedData { -- cgit v1.2.3 From 92147420124f28c4c844b4603de7ab412e084d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Fri, 9 May 2014 17:32:28 +0200 Subject: Android: Rename the wrapper classes Change-Id: I2ce15c8475da3186f128ba59b7c58f9b5b0a67e1 Reviewed-by: Yoann Lopes --- .../src/common/qandroidvideorendercontrol.cpp | 5 +- .../src/common/qandroidvideorendercontrol.h | 4 +- .../mediacapture/qandroidcameraexposurecontrol.cpp | 2 +- .../mediacapture/qandroidcameraflashcontrol.cpp | 2 +- .../mediacapture/qandroidcamerafocuscontrol.cpp | 2 +- .../qandroidcameraimageprocessingcontrol.cpp | 2 +- .../mediacapture/qandroidcameralockscontrol.cpp | 2 +- .../src/mediacapture/qandroidcamerasession.cpp | 32 +- .../src/mediacapture/qandroidcamerasession.h | 6 +- .../src/mediacapture/qandroidcamerazoomcontrol.cpp | 2 +- .../src/mediacapture/qandroidcapturesession.cpp | 77 +- .../src/mediacapture/qandroidcapturesession.h | 24 +- .../mediacapture/qandroidimageencodercontrol.cpp | 2 +- .../qandroidvideodeviceselectorcontrol.cpp | 2 +- .../src/mediaplayer/qandroidmediaplayercontrol.cpp | 156 +-- .../src/mediaplayer/qandroidmediaplayercontrol.h | 4 +- .../mediaplayer/qandroidmetadatareadercontrol.cpp | 38 +- .../mediaplayer/qandroidmetadatareadercontrol.h | 4 +- .../android/src/qandroidmediaserviceplugin.cpp | 20 +- src/plugins/android/src/src.pro | 2 +- src/plugins/android/src/wrappers/jcamera.cpp | 1366 -------------------- src/plugins/android/src/wrappers/jcamera.h | 187 --- .../src/wrappers/jmediametadataretriever.cpp | 130 -- .../android/src/wrappers/jmediametadataretriever.h | 93 -- src/plugins/android/src/wrappers/jmediaplayer.cpp | 266 ---- src/plugins/android/src/wrappers/jmediaplayer.h | 135 -- .../android/src/wrappers/jmediarecorder.cpp | 299 ----- src/plugins/android/src/wrappers/jmediarecorder.h | 135 -- .../android/src/wrappers/jmultimediautils.cpp | 80 -- .../android/src/wrappers/jmultimediautils.h | 68 - .../android/src/wrappers/jni/androidcamera.cpp | 1366 ++++++++++++++++++++ .../android/src/wrappers/jni/androidcamera.h | 187 +++ .../wrappers/jni/androidmediametadataretriever.cpp | 130 ++ .../wrappers/jni/androidmediametadataretriever.h | 93 ++ .../src/wrappers/jni/androidmediaplayer.cpp | 266 ++++ .../android/src/wrappers/jni/androidmediaplayer.h | 135 ++ .../src/wrappers/jni/androidmediarecorder.cpp | 299 +++++ .../src/wrappers/jni/androidmediarecorder.h | 135 ++ .../src/wrappers/jni/androidmultimediautils.cpp | 80 ++ .../src/wrappers/jni/androidmultimediautils.h | 68 + .../src/wrappers/jni/androidsurfacetexture.cpp | 158 +++ .../src/wrappers/jni/androidsurfacetexture.h | 78 ++ src/plugins/android/src/wrappers/jni/jni.pri | 19 + .../android/src/wrappers/jsurfacetexture.cpp | 158 --- src/plugins/android/src/wrappers/jsurfacetexture.h | 78 -- src/plugins/android/src/wrappers/wrappers.pri | 19 - 46 files changed, 3208 insertions(+), 3208 deletions(-) delete mode 100644 src/plugins/android/src/wrappers/jcamera.cpp delete mode 100644 src/plugins/android/src/wrappers/jcamera.h delete mode 100644 src/plugins/android/src/wrappers/jmediametadataretriever.cpp delete mode 100644 src/plugins/android/src/wrappers/jmediametadataretriever.h delete mode 100644 src/plugins/android/src/wrappers/jmediaplayer.cpp delete mode 100644 src/plugins/android/src/wrappers/jmediaplayer.h delete mode 100644 src/plugins/android/src/wrappers/jmediarecorder.cpp delete mode 100644 src/plugins/android/src/wrappers/jmediarecorder.h delete mode 100644 src/plugins/android/src/wrappers/jmultimediautils.cpp delete mode 100644 src/plugins/android/src/wrappers/jmultimediautils.h create mode 100644 src/plugins/android/src/wrappers/jni/androidcamera.cpp create mode 100644 src/plugins/android/src/wrappers/jni/androidcamera.h create mode 100644 src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp create mode 100644 src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h create mode 100644 src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp create mode 100644 src/plugins/android/src/wrappers/jni/androidmediaplayer.h create mode 100644 src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp create mode 100644 src/plugins/android/src/wrappers/jni/androidmediarecorder.h create mode 100644 src/plugins/android/src/wrappers/jni/androidmultimediautils.cpp create mode 100644 src/plugins/android/src/wrappers/jni/androidmultimediautils.h create mode 100644 src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp create mode 100644 src/plugins/android/src/wrappers/jni/androidsurfacetexture.h create mode 100644 src/plugins/android/src/wrappers/jni/jni.pri delete mode 100644 src/plugins/android/src/wrappers/jsurfacetexture.cpp delete mode 100644 src/plugins/android/src/wrappers/jsurfacetexture.h delete mode 100644 src/plugins/android/src/wrappers/wrappers.pri diff --git a/src/plugins/android/src/common/qandroidvideorendercontrol.cpp b/src/plugins/android/src/common/qandroidvideorendercontrol.cpp index 1891e9d10..dfeea33c1 100644 --- a/src/plugins/android/src/common/qandroidvideorendercontrol.cpp +++ b/src/plugins/android/src/common/qandroidvideorendercontrol.cpp @@ -40,8 +40,8 @@ ****************************************************************************/ #include "qandroidvideorendercontrol.h" +#include "androidsurfacetexture.h" -#include #include #include #include @@ -50,7 +50,6 @@ #include #include #include -#include QT_BEGIN_NAMESPACE @@ -175,7 +174,7 @@ bool QAndroidVideoRendererControl::initSurfaceTexture() return false; } - m_surfaceTexture = new JSurfaceTexture(m_externalTex); + m_surfaceTexture = new AndroidSurfaceTexture(m_externalTex); if (m_surfaceTexture->object()) { connect(m_surfaceTexture, SIGNAL(frameAvailable()), this, SLOT(onFrameAvailable())); diff --git a/src/plugins/android/src/common/qandroidvideorendercontrol.h b/src/plugins/android/src/common/qandroidvideorendercontrol.h index 75fd7ef12..83d57a437 100644 --- a/src/plugins/android/src/common/qandroidvideorendercontrol.h +++ b/src/plugins/android/src/common/qandroidvideorendercontrol.h @@ -45,13 +45,13 @@ #include #include #include "qandroidvideooutput.h" -#include "jsurfacetexture.h" QT_BEGIN_NAMESPACE class QOpenGLTexture; class QOpenGLFramebufferObject; class QOpenGLShaderProgram; +class AndroidSurfaceTexture; class OpenGLResourcesDeleter : public QObject { @@ -113,7 +113,7 @@ private: QSize m_nativeSize; QJNIObjectPrivate *m_androidSurface; - JSurfaceTexture *m_surfaceTexture; + AndroidSurfaceTexture *m_surfaceTexture; QJNIObjectPrivate *m_surfaceHolder; quint32 m_externalTex; diff --git a/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp index 03bbadb93..57057ebd7 100644 --- a/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcameraexposurecontrol.cpp @@ -42,7 +42,7 @@ #include "qandroidcameraexposurecontrol.h" #include "qandroidcamerasession.h" -#include "jcamera.h" +#include "androidcamera.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.cpp index 253b1baa5..de8e521ee 100644 --- a/src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcameraflashcontrol.cpp @@ -42,7 +42,7 @@ #include "qandroidcameraflashcontrol.h" #include "qandroidcamerasession.h" -#include "jcamera.h" +#include "androidcamera.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp index 345a29174..0b6ab80fc 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerafocuscontrol.cpp @@ -42,7 +42,7 @@ #include "qandroidcamerafocuscontrol.h" #include "qandroidcamerasession.h" -#include "jcamera.h" +#include "androidcamera.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp index ec5a3bcbf..4e4a416dd 100644 --- a/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcameraimageprocessingcontrol.cpp @@ -42,7 +42,7 @@ #include "qandroidcameraimageprocessingcontrol.h" #include "qandroidcamerasession.h" -#include "jcamera.h" +#include "androidcamera.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcameralockscontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcameralockscontrol.cpp index d9f20ec04..bfb48d06e 100644 --- a/src/plugins/android/src/mediacapture/qandroidcameralockscontrol.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcameralockscontrol.cpp @@ -42,7 +42,7 @@ #include "qandroidcameralockscontrol.h" #include "qandroidcamerasession.h" -#include "jcamera.h" +#include "androidcamera.h" #include QT_BEGIN_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index 53fb2f516..f8633147d 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -41,8 +41,8 @@ #include "qandroidcamerasession.h" -#include "jcamera.h" -#include "jmultimediautils.h" +#include "androidcamera.h" +#include "androidmultimediautils.h" #include "qandroidvideooutput.h" #include "qandroidmediavideoprobecontrol.h" #include "qandroidmultimediautils.h" @@ -113,7 +113,7 @@ QAndroidCameraSession::QAndroidCameraSession(QObject *parent) { m_mediaStorageLocation.addStorageLocation( QMediaStorageLocation::Pictures, - JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::DCIM)); + AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::DCIM)); if (qApp) { connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), @@ -195,17 +195,17 @@ void QAndroidCameraSession::updateAvailableCameras() "(ILandroid/hardware/Camera$CameraInfo;)V", i, cameraInfo.object()); - JCamera::CameraFacing facing = JCamera::CameraFacing(cameraInfo.getField("facing")); + AndroidCamera::CameraFacing facing = AndroidCamera::CameraFacing(cameraInfo.getField("facing")); // The orientation provided by Android is counter-clockwise, we need it clockwise info.orientation = (360 - cameraInfo.getField("orientation")) % 360; switch (facing) { - case JCamera::CameraFacingBack: + case AndroidCamera::CameraFacingBack: info.name = QByteArray("back"); info.description = QStringLiteral("Rear-facing camera"); info.position = QCamera::BackFace; break; - case JCamera::CameraFacingFront: + case AndroidCamera::CameraFacingFront: info.name = QByteArray("front"); info.description = QStringLiteral("Front-facing camera"); info.position = QCamera::FrontFace; @@ -234,7 +234,7 @@ bool QAndroidCameraSession::open() m_status = QCamera::LoadingStatus; emit statusChanged(m_status); - m_camera = JCamera::open(m_selectedCamera); + m_camera = AndroidCamera::open(m_selectedCamera); if (m_camera) { connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed())); @@ -250,8 +250,8 @@ bool QAndroidCameraSession::open() m_status = QCamera::LoadedStatus; - if (m_camera->getPreviewFormat() != JCamera::NV21) - m_camera->setPreviewFormat(JCamera::NV21); + if (m_camera->getPreviewFormat() != AndroidCamera::NV21) + m_camera->setPreviewFormat(AndroidCamera::NV21); m_camera->fetchEachFrame(m_videoProbes.count()); @@ -356,7 +356,7 @@ void QAndroidCameraSession::startPreview() if (m_videoOutput && m_videoOutput->isReady()) onVideoOutputReady(true); - JMultimediaUtils::enableOrientationListener(true); + AndroidMultimediaUtils::enableOrientationListener(true); m_camera->startPreview(); m_previewStarted = true; @@ -370,7 +370,7 @@ void QAndroidCameraSession::stopPreview() m_status = QCamera::StoppingStatus; emit statusChanged(m_status); - JMultimediaUtils::enableOrientationListener(false); + AndroidMultimediaUtils::enableOrientationListener(false); m_camera->stopPreview(); m_camera->setPreviewSize(QSize()); @@ -407,8 +407,8 @@ int QAndroidCameraSession::currentCameraRotation() const // subtract natural camera orientation and physical device orientation int rotation = 0; - int deviceOrientation = (JMultimediaUtils::getDeviceOrientation() + 45) / 90 * 90; - if (m_camera->getFacing() == JCamera::CameraFacingFront) + int deviceOrientation = (AndroidMultimediaUtils::getDeviceOrientation() + 45) / 90 * 90; + if (m_camera->getFacing() == AndroidCamera::CameraFacingFront) rotation = (m_nativeOrientation - deviceOrientation + 360) % 360; else // back-facing camera rotation = (m_nativeOrientation + deviceOrientation) % 360; @@ -658,9 +658,9 @@ void QAndroidCameraSession::processCapturedImage(int id, // 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); + QString standardLoc = AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::DCIM); if (actualFileName.startsWith(standardLoc)) - JMultimediaUtils::registerMediaFile(actualFileName); + AndroidMultimediaUtils::registerMediaFile(actualFileName); emit imageSaved(id, actualFileName); } else { @@ -697,7 +697,7 @@ QImage QAndroidCameraSession::prepareImageFromPreviewData(const QByteArray &data // Preview display of front-facing cameras is flipped horizontally, but the frame data // we get here is not. Flip it ourselves if the camera is front-facing to match what the user // sees on the viewfinder. - if (m_camera->getFacing() == JCamera::CameraFacingFront) + if (m_camera->getFacing() == AndroidCamera::CameraFacingFront) transform.scale(-1, 1); transform.rotate(rotation); diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h index 4c58cab9e..51aba4a9b 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.h +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.h @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE -class JCamera; +class AndroidCamera; class QAndroidVideoOutput; class QAndroidMediaVideoProbeControl; @@ -73,7 +73,7 @@ public: static const QList &availableCameras(); void setSelectedCamera(int cameraId) { m_selectedCamera = cameraId; } - JCamera *camera() const { return m_camera; } + AndroidCamera *camera() const { return m_camera; } QCamera::State state() const { return m_state; } void setState(QCamera::State state); @@ -154,7 +154,7 @@ private: const QString &fileName); int m_selectedCamera; - JCamera *m_camera; + AndroidCamera *m_camera; int m_nativeOrientation; QAndroidVideoOutput *m_videoOutput; diff --git a/src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.cpp index b7030e56b..385cd942a 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerazoomcontrol.cpp @@ -42,7 +42,7 @@ #include "qandroidcamerazoomcontrol.h" #include "qandroidcamerasession.h" -#include "jcamera.h" +#include "androidcamera.h" #include "qandroidmultimediautils.h" #include diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp index 4b1c58255..f8641073e 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp @@ -41,11 +41,10 @@ #include "qandroidcapturesession.h" -#include "jcamera.h" +#include "androidcamera.h" #include "qandroidcamerasession.h" -#include "jmultimediautils.h" +#include "androidmultimediautils.h" #include "qandroidmultimediautils.h" -#include QT_BEGIN_NAMESPACE @@ -53,7 +52,7 @@ QAndroidCaptureSession::QAndroidCaptureSession(QAndroidCameraSession *cameraSess : QObject() , m_mediaRecorder(0) , m_cameraSession(cameraSession) - , m_audioSource(JMediaRecorder::DefaultAudioSource) + , m_audioSource(AndroidMediaRecorder::DefaultAudioSource) , m_duration(0) , m_state(QMediaRecorder::StoppedState) , m_status(QMediaRecorder::UnloadedStatus) @@ -61,17 +60,17 @@ QAndroidCaptureSession::QAndroidCaptureSession(QAndroidCameraSession *cameraSess , m_containerFormatDirty(true) , m_videoSettingsDirty(true) , m_audioSettingsDirty(true) - , m_outputFormat(JMediaRecorder::DefaultOutputFormat) - , m_audioEncoder(JMediaRecorder::DefaultAudioEncoder) - , m_videoEncoder(JMediaRecorder::DefaultVideoEncoder) + , m_outputFormat(AndroidMediaRecorder::DefaultOutputFormat) + , m_audioEncoder(AndroidMediaRecorder::DefaultAudioEncoder) + , m_videoEncoder(AndroidMediaRecorder::DefaultVideoEncoder) { m_mediaStorageLocation.addStorageLocation( QMediaStorageLocation::Movies, - JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::DCIM)); + AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::DCIM)); m_mediaStorageLocation.addStorageLocation( QMediaStorageLocation::Sounds, - JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::Sounds)); + AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::Sounds)); connect(this, SIGNAL(stateChanged(QMediaRecorder::State)), this, SLOT(updateStatus())); @@ -103,19 +102,19 @@ void QAndroidCaptureSession::setAudioInput(const QString &input) m_audioInput = input; if (m_audioInput == QLatin1String("default")) - m_audioSource = JMediaRecorder::DefaultAudioSource; + m_audioSource = AndroidMediaRecorder::DefaultAudioSource; else if (m_audioInput == QLatin1String("mic")) - m_audioSource = JMediaRecorder::Mic; + m_audioSource = AndroidMediaRecorder::Mic; else if (m_audioInput == QLatin1String("voice_uplink")) - m_audioSource = JMediaRecorder::VoiceUplink; + m_audioSource = AndroidMediaRecorder::VoiceUplink; else if (m_audioInput == QLatin1String("voice_downlink")) - m_audioSource = JMediaRecorder::VoiceDownlink; + m_audioSource = AndroidMediaRecorder::VoiceDownlink; else if (m_audioInput == QLatin1String("voice_call")) - m_audioSource = JMediaRecorder::VoiceCall; + m_audioSource = AndroidMediaRecorder::VoiceCall; else if (m_audioInput == QLatin1String("voice_recognition")) - m_audioSource = JMediaRecorder::VoiceRecognition; + m_audioSource = AndroidMediaRecorder::VoiceRecognition; else - m_audioSource = JMediaRecorder::DefaultAudioSource; + m_audioSource = AndroidMediaRecorder::DefaultAudioSource; emit audioInputChanged(m_audioInput); } @@ -184,7 +183,7 @@ bool QAndroidCaptureSession::start() m_mediaRecorder->release(); delete m_mediaRecorder; } - m_mediaRecorder = new JMediaRecorder; + m_mediaRecorder = new AndroidMediaRecorder; connect(m_mediaRecorder, SIGNAL(error(int,int)), this, SLOT(onError(int,int))); connect(m_mediaRecorder, SIGNAL(info(int,int)), this, SLOT(onInfo(int,int))); @@ -193,8 +192,8 @@ bool QAndroidCaptureSession::start() updateViewfinder(); m_cameraSession->camera()->unlock(); m_mediaRecorder->setCamera(m_cameraSession->camera()); - m_mediaRecorder->setAudioSource(JMediaRecorder::Camcorder); - m_mediaRecorder->setVideoSource(JMediaRecorder::Camera); + m_mediaRecorder->setAudioSource(AndroidMediaRecorder::Camcorder); + m_mediaRecorder->setVideoSource(AndroidMediaRecorder::Camera); } else { m_mediaRecorder->setAudioSource(m_audioSource); } @@ -280,10 +279,10 @@ void QAndroidCaptureSession::stop(bool error) // with the Android media scanner so it appears immediately in apps // such as the gallery. QString mediaPath = m_actualOutputLocation.toLocalFile(); - QString standardLoc = m_cameraSession ? JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::DCIM) - : JMultimediaUtils::getDefaultMediaDirectory(JMultimediaUtils::Sounds); + QString standardLoc = m_cameraSession ? AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::DCIM) + : AndroidMultimediaUtils::getDefaultMediaDirectory(AndroidMultimediaUtils::Sounds); if (mediaPath.startsWith(standardLoc)) - JMultimediaUtils::registerMediaFile(mediaPath); + AndroidMultimediaUtils::registerMediaFile(mediaPath); m_actualOutputLocation = m_usedOutputLocation; emit actualLocationChanged(m_actualOutputLocation); @@ -347,14 +346,14 @@ void QAndroidCaptureSession::applySettings() m_containerFormat = m_defaultSettings.outputFileExtension; m_outputFormat = m_defaultSettings.outputFormat; } else if (m_containerFormat == QLatin1String("3gp")) { - m_outputFormat = JMediaRecorder::THREE_GPP; + m_outputFormat = AndroidMediaRecorder::THREE_GPP; } else if (!m_cameraSession && m_containerFormat == QLatin1String("amr")) { - m_outputFormat = JMediaRecorder::AMR_NB_Format; + m_outputFormat = AndroidMediaRecorder::AMR_NB_Format; } else if (!m_cameraSession && m_containerFormat == QLatin1String("awb")) { - m_outputFormat = JMediaRecorder::AMR_WB_Format; + m_outputFormat = AndroidMediaRecorder::AMR_WB_Format; } else { m_containerFormat = QStringLiteral("mp4"); - m_outputFormat = JMediaRecorder::MPEG_4; + m_outputFormat = AndroidMediaRecorder::MPEG_4; } m_containerFormatDirty = false; @@ -372,11 +371,11 @@ void QAndroidCaptureSession::applySettings() if (m_audioSettings.codec().isEmpty()) m_audioEncoder = m_defaultSettings.audioEncoder; else if (m_audioSettings.codec() == QLatin1String("aac")) - m_audioEncoder = JMediaRecorder::AAC; + m_audioEncoder = AndroidMediaRecorder::AAC; else if (m_audioSettings.codec() == QLatin1String("amr-nb")) - m_audioEncoder = JMediaRecorder::AMR_NB_Encoder; + m_audioEncoder = AndroidMediaRecorder::AMR_NB_Encoder; else if (m_audioSettings.codec() == QLatin1String("amr-wb")) - m_audioEncoder = JMediaRecorder::AMR_WB_Encoder; + m_audioEncoder = AndroidMediaRecorder::AMR_WB_Encoder; else m_audioEncoder = m_defaultSettings.audioEncoder; @@ -410,11 +409,11 @@ void QAndroidCaptureSession::applySettings() if (m_videoSettings.codec().isEmpty()) m_videoEncoder = m_defaultSettings.videoEncoder; else if (m_videoSettings.codec() == QLatin1String("h263")) - m_videoEncoder = JMediaRecorder::H263; + m_videoEncoder = AndroidMediaRecorder::H263; else if (m_videoSettings.codec() == QLatin1String("h264")) - m_videoEncoder = JMediaRecorder::H264; + m_videoEncoder = AndroidMediaRecorder::H264; else if (m_videoSettings.codec() == QLatin1String("mpeg4_sp")) - m_videoEncoder = JMediaRecorder::MPEG_4_SP; + m_videoEncoder = AndroidMediaRecorder::MPEG_4_SP; else m_videoEncoder = m_defaultSettings.videoEncoder; @@ -489,24 +488,24 @@ QAndroidCaptureSession::CaptureProfile QAndroidCaptureSession::getProfile(int id id); - profile.outputFormat = JMediaRecorder::OutputFormat(obj.getField("fileFormat")); - profile.audioEncoder = JMediaRecorder::AudioEncoder(obj.getField("audioCodec")); + profile.outputFormat = AndroidMediaRecorder::OutputFormat(obj.getField("fileFormat")); + profile.audioEncoder = AndroidMediaRecorder::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.videoEncoder = AndroidMediaRecorder::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) + if (profile.outputFormat == AndroidMediaRecorder::MPEG_4) profile.outputFileExtension = QStringLiteral("mp4"); - else if (profile.outputFormat == JMediaRecorder::THREE_GPP) + else if (profile.outputFormat == AndroidMediaRecorder::THREE_GPP) profile.outputFileExtension = QStringLiteral("3gp"); - else if (profile.outputFormat == JMediaRecorder::AMR_NB_Format) + else if (profile.outputFormat == AndroidMediaRecorder::AMR_NB_Format) profile.outputFileExtension = QStringLiteral("amr"); - else if (profile.outputFormat == JMediaRecorder::AMR_WB_Format) + else if (profile.outputFormat == AndroidMediaRecorder::AMR_WB_Format) profile.outputFileExtension = QStringLiteral("awb"); profile.isNull = false; diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.h b/src/plugins/android/src/mediacapture/qandroidcapturesession.h index 4b6121dfa..4ff2cb145 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.h +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.h @@ -48,7 +48,7 @@ #include #include #include -#include "jmediarecorder.h" +#include "androidmediarecorder.h" QT_BEGIN_NAMESPACE @@ -106,15 +106,15 @@ private Q_SLOTS: private: struct CaptureProfile { - JMediaRecorder::OutputFormat outputFormat; + AndroidMediaRecorder::OutputFormat outputFormat; QString outputFileExtension; - JMediaRecorder::AudioEncoder audioEncoder; + AndroidMediaRecorder::AudioEncoder audioEncoder; int audioBitRate; int audioChannels; int audioSampleRate; - JMediaRecorder::VideoEncoder videoEncoder; + AndroidMediaRecorder::VideoEncoder videoEncoder; int videoBitRate; int videoFrameRate; QSize videoResolution; @@ -122,13 +122,13 @@ private: bool isNull; CaptureProfile() - : outputFormat(JMediaRecorder::MPEG_4) + : outputFormat(AndroidMediaRecorder::MPEG_4) , outputFileExtension(QLatin1String("mp4")) - , audioEncoder(JMediaRecorder::DefaultAudioEncoder) + , audioEncoder(AndroidMediaRecorder::DefaultAudioEncoder) , audioBitRate(128000) , audioChannels(2) , audioSampleRate(44100) - , videoEncoder(JMediaRecorder::DefaultVideoEncoder) + , videoEncoder(AndroidMediaRecorder::DefaultVideoEncoder) , videoBitRate(1) , videoFrameRate(-1) , videoResolution(320, 240) @@ -146,11 +146,11 @@ private: void updateViewfinder(); void restartViewfinder(); - JMediaRecorder *m_mediaRecorder; + AndroidMediaRecorder *m_mediaRecorder; QAndroidCameraSession *m_cameraSession; QString m_audioInput; - JMediaRecorder::AudioSource m_audioSource; + AndroidMediaRecorder::AudioSource m_audioSource; QMediaStorageLocation m_mediaStorageLocation; @@ -173,9 +173,9 @@ private: bool m_containerFormatDirty; bool m_videoSettingsDirty; bool m_audioSettingsDirty; - JMediaRecorder::OutputFormat m_outputFormat; - JMediaRecorder::AudioEncoder m_audioEncoder; - JMediaRecorder::VideoEncoder m_videoEncoder; + AndroidMediaRecorder::OutputFormat m_outputFormat; + AndroidMediaRecorder::AudioEncoder m_audioEncoder; + AndroidMediaRecorder::VideoEncoder m_videoEncoder; QList m_supportedResolutions; QList m_supportedFramerates; diff --git a/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp b/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp index 79e0651a3..a239f510b 100644 --- a/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp +++ b/src/plugins/android/src/mediacapture/qandroidimageencodercontrol.cpp @@ -42,7 +42,7 @@ #include "qandroidimageencodercontrol.h" #include "qandroidcamerasession.h" -#include "jcamera.h" +#include "androidcamera.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp b/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp index 3fcb199f7..17a349d9d 100644 --- a/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp +++ b/src/plugins/android/src/mediacapture/qandroidvideodeviceselectorcontrol.cpp @@ -42,7 +42,7 @@ #include "qandroidvideodeviceselectorcontrol.h" #include "qandroidcamerasession.h" -#include "jcamera.h" +#include "androidcamera.h" QT_BEGIN_NAMESPACE diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp index 68fb5e473..2d49e78b1 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp @@ -40,14 +40,14 @@ ****************************************************************************/ #include "qandroidmediaplayercontrol.h" -#include "jmediaplayer.h" +#include "androidmediaplayer.h" #include "qandroidvideooutput.h" QT_BEGIN_NAMESPACE QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent) : QMediaPlayerControl(parent), - mMediaPlayer(new JMediaPlayer), + mMediaPlayer(new AndroidMediaPlayer), mCurrentState(QMediaPlayer::StoppedState), mCurrentMediaStatus(QMediaPlayer::NoMedia), mMediaStream(0), @@ -58,7 +58,7 @@ QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent) mAudioAvailable(false), mVideoAvailable(false), mBuffering(false), - mState(JMediaPlayer::Uninitialized), + mState(AndroidMediaPlayer::Uninitialized), mPendingState(-1), mPendingPosition(-1), mPendingSetMedia(false), @@ -99,11 +99,11 @@ QMediaPlayer::MediaStatus QAndroidMediaPlayerControl::mediaStatus() const qint64 QAndroidMediaPlayerControl::duration() const { - if ((mState & (JMediaPlayer::Prepared - | JMediaPlayer::Started - | JMediaPlayer::Paused - | JMediaPlayer::Stopped - | JMediaPlayer::PlaybackCompleted)) == 0) { + if ((mState & (AndroidMediaPlayer::Prepared + | AndroidMediaPlayer::Started + | AndroidMediaPlayer::Paused + | AndroidMediaPlayer::Stopped + | AndroidMediaPlayer::PlaybackCompleted)) == 0) { return 0; } @@ -115,13 +115,13 @@ qint64 QAndroidMediaPlayerControl::position() const if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia) return duration(); - if ((mState & (JMediaPlayer::Idle - | JMediaPlayer::Initialized - | JMediaPlayer::Prepared - | JMediaPlayer::Started - | JMediaPlayer::Paused - | JMediaPlayer::Stopped - | JMediaPlayer::PlaybackCompleted)) == 0) { + if ((mState & (AndroidMediaPlayer::Idle + | AndroidMediaPlayer::Initialized + | AndroidMediaPlayer::Prepared + | AndroidMediaPlayer::Started + | AndroidMediaPlayer::Paused + | AndroidMediaPlayer::Stopped + | AndroidMediaPlayer::PlaybackCompleted)) == 0) { return (mPendingPosition == -1) ? 0 : mPendingPosition; } @@ -135,10 +135,10 @@ void QAndroidMediaPlayerControl::setPosition(qint64 position) const int seekPosition = (position > INT_MAX) ? INT_MAX : position; - if ((mState & (JMediaPlayer::Prepared - | JMediaPlayer::Started - | JMediaPlayer::Paused - | JMediaPlayer::PlaybackCompleted)) == 0) { + if ((mState & (AndroidMediaPlayer::Prepared + | AndroidMediaPlayer::Started + | AndroidMediaPlayer::Paused + | AndroidMediaPlayer::PlaybackCompleted)) == 0) { if (mPendingPosition != seekPosition) { mPendingPosition = seekPosition; Q_EMIT positionChanged(seekPosition); @@ -165,13 +165,13 @@ int QAndroidMediaPlayerControl::volume() const void QAndroidMediaPlayerControl::setVolume(int volume) { - if ((mState & (JMediaPlayer::Idle - | JMediaPlayer::Initialized - | JMediaPlayer::Stopped - | JMediaPlayer::Prepared - | JMediaPlayer::Started - | JMediaPlayer::Paused - | JMediaPlayer::PlaybackCompleted)) == 0) { + if ((mState & (AndroidMediaPlayer::Idle + | AndroidMediaPlayer::Initialized + | AndroidMediaPlayer::Stopped + | AndroidMediaPlayer::Prepared + | AndroidMediaPlayer::Started + | AndroidMediaPlayer::Paused + | AndroidMediaPlayer::PlaybackCompleted)) == 0) { if (mPendingVolume != volume) { mPendingVolume = volume; Q_EMIT volumeChanged(volume); @@ -196,13 +196,13 @@ bool QAndroidMediaPlayerControl::isMuted() const void QAndroidMediaPlayerControl::setMuted(bool muted) { - if ((mState & (JMediaPlayer::Idle - | JMediaPlayer::Initialized - | JMediaPlayer::Stopped - | JMediaPlayer::Prepared - | JMediaPlayer::Started - | JMediaPlayer::Paused - | JMediaPlayer::PlaybackCompleted)) == 0) { + if ((mState & (AndroidMediaPlayer::Idle + | AndroidMediaPlayer::Initialized + | AndroidMediaPlayer::Stopped + | AndroidMediaPlayer::Prepared + | AndroidMediaPlayer::Started + | AndroidMediaPlayer::Paused + | AndroidMediaPlayer::PlaybackCompleted)) == 0) { if (mPendingMute != muted) { mPendingMute = muted; Q_EMIT mutedChanged(muted); @@ -291,7 +291,7 @@ void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent, } // Release the mediaplayer if it's not in in Idle or Uninitialized state - if ((mState & (JMediaPlayer::Idle | JMediaPlayer::Uninitialized)) == 0) + if ((mState & (AndroidMediaPlayer::Idle | AndroidMediaPlayer::Uninitialized)) == 0) mMediaPlayer->release(); if (mediaContent.isNull()) { @@ -353,16 +353,16 @@ void QAndroidMediaPlayerControl::setVideoOutput(QObject *videoOutput) void QAndroidMediaPlayerControl::play() { // We need to prepare the mediaplayer again. - if ((mState & JMediaPlayer::Stopped) && !mMediaContent.isNull()) { + if ((mState & AndroidMediaPlayer::Stopped) && !mMediaContent.isNull()) { setMedia(mMediaContent, mMediaStream); } setState(QMediaPlayer::PlayingState); - if ((mState & (JMediaPlayer::Prepared - | JMediaPlayer::Started - | JMediaPlayer::Paused - | JMediaPlayer::PlaybackCompleted)) == 0) { + if ((mState & (AndroidMediaPlayer::Prepared + | AndroidMediaPlayer::Started + | AndroidMediaPlayer::Paused + | AndroidMediaPlayer::PlaybackCompleted)) == 0) { mPendingState = QMediaPlayer::PlayingState; return; } @@ -374,9 +374,9 @@ void QAndroidMediaPlayerControl::pause() { setState(QMediaPlayer::PausedState); - if ((mState & (JMediaPlayer::Started - | JMediaPlayer::Paused - | JMediaPlayer::PlaybackCompleted)) == 0) { + if ((mState & (AndroidMediaPlayer::Started + | AndroidMediaPlayer::Paused + | AndroidMediaPlayer::PlaybackCompleted)) == 0) { mPendingState = QMediaPlayer::PausedState; return; } @@ -388,12 +388,12 @@ void QAndroidMediaPlayerControl::stop() { setState(QMediaPlayer::StoppedState); - if ((mState & (JMediaPlayer::Prepared - | JMediaPlayer::Started - | JMediaPlayer::Stopped - | JMediaPlayer::Paused - | JMediaPlayer::PlaybackCompleted)) == 0) { - if ((mState & (JMediaPlayer::Idle | JMediaPlayer::Uninitialized | JMediaPlayer::Error)) == 0) + if ((mState & (AndroidMediaPlayer::Prepared + | AndroidMediaPlayer::Started + | AndroidMediaPlayer::Stopped + | AndroidMediaPlayer::Paused + | AndroidMediaPlayer::PlaybackCompleted)) == 0) { + if ((mState & (AndroidMediaPlayer::Idle | AndroidMediaPlayer::Uninitialized | AndroidMediaPlayer::Error)) == 0) mPendingState = QMediaPlayer::StoppedState; return; } @@ -405,28 +405,28 @@ void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra) { Q_UNUSED(extra); switch (what) { - case JMediaPlayer::MEDIA_INFO_UNKNOWN: + case AndroidMediaPlayer::MEDIA_INFO_UNKNOWN: break; - case JMediaPlayer::MEDIA_INFO_VIDEO_TRACK_LAGGING: + case AndroidMediaPlayer::MEDIA_INFO_VIDEO_TRACK_LAGGING: // IGNORE break; - case JMediaPlayer::MEDIA_INFO_VIDEO_RENDERING_START: + case AndroidMediaPlayer::MEDIA_INFO_VIDEO_RENDERING_START: break; - case JMediaPlayer::MEDIA_INFO_BUFFERING_START: + case AndroidMediaPlayer::MEDIA_INFO_BUFFERING_START: mPendingState = mCurrentState; setState(QMediaPlayer::PausedState); setMediaStatus(QMediaPlayer::StalledMedia); break; - case JMediaPlayer::MEDIA_INFO_BUFFERING_END: + case AndroidMediaPlayer::MEDIA_INFO_BUFFERING_END: if (mCurrentState != QMediaPlayer::StoppedState) flushPendingStates(); break; - case JMediaPlayer::MEDIA_INFO_BAD_INTERLEAVING: + case AndroidMediaPlayer::MEDIA_INFO_BAD_INTERLEAVING: break; - case JMediaPlayer::MEDIA_INFO_NOT_SEEKABLE: + case AndroidMediaPlayer::MEDIA_INFO_NOT_SEEKABLE: setSeekable(false); break; - case JMediaPlayer::MEDIA_INFO_METADATA_UPDATE: + case AndroidMediaPlayer::MEDIA_INFO_METADATA_UPDATE: Q_EMIT metaDataUpdated(); break; } @@ -438,44 +438,44 @@ void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra) QMediaPlayer::Error error = QMediaPlayer::ResourceError; switch (what) { - case JMediaPlayer::MEDIA_ERROR_UNKNOWN: + case AndroidMediaPlayer::MEDIA_ERROR_UNKNOWN: errorString = QLatin1String("Error:"); break; - case JMediaPlayer::MEDIA_ERROR_SERVER_DIED: + case AndroidMediaPlayer::MEDIA_ERROR_SERVER_DIED: errorString = QLatin1String("Error: Server died"); error = QMediaPlayer::ServiceMissingError; break; - case JMediaPlayer::MEDIA_ERROR_INVALID_STATE: + case AndroidMediaPlayer::MEDIA_ERROR_INVALID_STATE: errorString = QLatin1String("Error: Invalid state"); error = QMediaPlayer::ServiceMissingError; break; } switch (extra) { - case JMediaPlayer::MEDIA_ERROR_IO: // Network OR file error + case AndroidMediaPlayer::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: + case AndroidMediaPlayer::MEDIA_ERROR_MALFORMED: errorString += QLatin1String(" (Malformed bitstream)"); error = QMediaPlayer::FormatError; setMediaStatus(QMediaPlayer::InvalidMedia); break; - case JMediaPlayer::MEDIA_ERROR_UNSUPPORTED: + case AndroidMediaPlayer::MEDIA_ERROR_UNSUPPORTED: errorString += QLatin1String(" (Unsupported media)"); error = QMediaPlayer::FormatError; setMediaStatus(QMediaPlayer::InvalidMedia); break; - case JMediaPlayer::MEDIA_ERROR_TIMED_OUT: + case AndroidMediaPlayer::MEDIA_ERROR_TIMED_OUT: errorString += QLatin1String(" (Timed out)"); break; - case JMediaPlayer::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: + case AndroidMediaPlayer::MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: errorString += QLatin1String(" (Unable to start progressive playback')"); error = QMediaPlayer::FormatError; setMediaStatus(QMediaPlayer::InvalidMedia); break; - case JMediaPlayer::MEDIA_ERROR_BAD_THINGS_ARE_GOING_TO_HAPPEN: + case AndroidMediaPlayer::MEDIA_ERROR_BAD_THINGS_ARE_GOING_TO_HAPPEN: errorString += QLatin1String(" (Unknown error/Insufficient resources)"); error = QMediaPlayer::ServiceMissingError; break; @@ -512,21 +512,21 @@ void QAndroidMediaPlayerControl::onVideoSizeChanged(qint32 width, qint32 height) void QAndroidMediaPlayerControl::onStateChanged(qint32 state) { // If reloading, don't report state changes unless the new state is Prepared or Error. - if ((mState & JMediaPlayer::Stopped) - && (state & (JMediaPlayer::Prepared | JMediaPlayer::Error | JMediaPlayer::Uninitialized)) == 0) { + if ((mState & AndroidMediaPlayer::Stopped) + && (state & (AndroidMediaPlayer::Prepared | AndroidMediaPlayer::Error | AndroidMediaPlayer::Uninitialized)) == 0) { return; } mState = state; switch (mState) { - case JMediaPlayer::Idle: + case AndroidMediaPlayer::Idle: break; - case JMediaPlayer::Initialized: + case AndroidMediaPlayer::Initialized: break; - case JMediaPlayer::Preparing: + case AndroidMediaPlayer::Preparing: setMediaStatus(QMediaPlayer::LoadingMedia); break; - case JMediaPlayer::Prepared: + case AndroidMediaPlayer::Prepared: setMediaStatus(QMediaPlayer::LoadedMedia); if (mBuffering) { setMediaStatus(mBufferPercent == 100 ? QMediaPlayer::BufferedMedia @@ -537,7 +537,7 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state) setAudioAvailable(true); flushPendingStates(); break; - case JMediaPlayer::Started: + case AndroidMediaPlayer::Started: setState(QMediaPlayer::PlayingState); if (mBuffering) { setMediaStatus(mBufferPercent == 100 ? QMediaPlayer::BufferedMedia @@ -546,25 +546,25 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state) setMediaStatus(QMediaPlayer::BufferedMedia); } break; - case JMediaPlayer::Paused: + case AndroidMediaPlayer::Paused: setState(QMediaPlayer::PausedState); break; - case JMediaPlayer::Error: + case AndroidMediaPlayer::Error: setState(QMediaPlayer::StoppedState); setMediaStatus(QMediaPlayer::UnknownMediaStatus); mMediaPlayer->release(); break; - case JMediaPlayer::Stopped: + case AndroidMediaPlayer::Stopped: setState(QMediaPlayer::StoppedState); setMediaStatus(QMediaPlayer::LoadedMedia); setPosition(0); break; - case JMediaPlayer::PlaybackCompleted: + case AndroidMediaPlayer::PlaybackCompleted: setState(QMediaPlayer::StoppedState); setPosition(0); setMediaStatus(QMediaPlayer::EndOfMedia); break; - case JMediaPlayer::Uninitialized: + case AndroidMediaPlayer::Uninitialized: // reset some properties resetBufferingProgress(); mPendingPosition = -1; @@ -579,7 +579,7 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state) break; } - if ((mState & (JMediaPlayer::Stopped | JMediaPlayer::Uninitialized)) != 0) { + if ((mState & (AndroidMediaPlayer::Stopped | AndroidMediaPlayer::Uninitialized)) != 0) { mMediaPlayer->setDisplay(0); if (mVideoOutput) { mVideoOutput->stop(); diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h index 27e6afc12..5744c11b8 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE -class JMediaPlayer; +class AndroidMediaPlayer; class QAndroidVideoOutput; class QAndroidMediaPlayerControl : public QMediaPlayerControl @@ -98,7 +98,7 @@ private Q_SLOTS: void onStateChanged(qint32 state); private: - JMediaPlayer *mMediaPlayer; + AndroidMediaPlayer *mMediaPlayer; QMediaPlayer::State mCurrentState; QMediaPlayer::MediaStatus mCurrentMediaStatus; QMediaContent mMediaContent; diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp index dcc3dfbe0..82bd74997 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp +++ b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.cpp @@ -41,7 +41,7 @@ #include "qandroidmetadatareadercontrol.h" -#include "jmediametadataretriever.h" +#include "androidmediametadataretriever.h" #include #include #include @@ -74,7 +74,7 @@ static const char* qt_ID3GenreNames[] = QAndroidMetaDataReaderControl::QAndroidMetaDataReaderControl(QObject *parent) : QMetaDataReaderControl(parent) , m_available(false) - , m_retriever(new JMediaMetadataRetriever) + , m_retriever(new AndroidMediaMetadataRetriever) { } @@ -124,56 +124,56 @@ void QAndroidMetaDataReaderControl::updateData() if (!m_mediaContent.isNull()) { if (m_retriever->setDataSource(m_mediaContent.canonicalUrl())) { - QString mimeType = m_retriever->extractMetadata(JMediaMetadataRetriever::MimeType); + QString mimeType = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::MimeType); if (!mimeType.isNull()) m_metadata.insert(QMediaMetaData::MediaType, mimeType); - bool isVideo = !m_retriever->extractMetadata(JMediaMetadataRetriever::HasVideo).isNull() + bool isVideo = !m_retriever->extractMetadata(AndroidMediaMetadataRetriever::HasVideo).isNull() || mimeType.startsWith(QStringLiteral("video")); - QString string = m_retriever->extractMetadata(JMediaMetadataRetriever::Album); + QString string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::Album); if (!string.isNull()) m_metadata.insert(QMediaMetaData::AlbumTitle, string); - string = m_retriever->extractMetadata(JMediaMetadataRetriever::AlbumArtist); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::AlbumArtist); if (!string.isNull()) m_metadata.insert(QMediaMetaData::AlbumArtist, string); - string = m_retriever->extractMetadata(JMediaMetadataRetriever::Artist); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::Artist); if (!string.isNull()) { m_metadata.insert(isVideo ? QMediaMetaData::LeadPerformer : QMediaMetaData::ContributingArtist, string.split('/', QString::SkipEmptyParts)); } - string = m_retriever->extractMetadata(JMediaMetadataRetriever::Author); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::Author); if (!string.isNull()) m_metadata.insert(QMediaMetaData::Author, string.split('/', QString::SkipEmptyParts)); - string = m_retriever->extractMetadata(JMediaMetadataRetriever::Bitrate); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::Bitrate); if (!string.isNull()) { m_metadata.insert(isVideo ? QMediaMetaData::VideoBitRate : QMediaMetaData::AudioBitRate, string.toInt()); } - string = m_retriever->extractMetadata(JMediaMetadataRetriever::CDTrackNumber); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::CDTrackNumber); if (!string.isNull()) m_metadata.insert(QMediaMetaData::TrackNumber, string.toInt()); - string = m_retriever->extractMetadata(JMediaMetadataRetriever::Composer); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::Composer); if (!string.isNull()) m_metadata.insert(QMediaMetaData::Composer, string.split('/', QString::SkipEmptyParts)); - string = m_retriever->extractMetadata(JMediaMetadataRetriever::Date); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::Date); if (!string.isNull()) m_metadata.insert(QMediaMetaData::Date, QDateTime::fromString(string, QStringLiteral("yyyyMMddTHHmmss.zzzZ")).date()); - string = m_retriever->extractMetadata(JMediaMetadataRetriever::Duration); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::Duration); if (!string.isNull()) m_metadata.insert(QMediaMetaData::Duration, string.toLongLong()); - string = m_retriever->extractMetadata(JMediaMetadataRetriever::Genre); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::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(')')) { @@ -185,22 +185,22 @@ void QAndroidMetaDataReaderControl::updateData() m_metadata.insert(QMediaMetaData::Genre, string); } - string = m_retriever->extractMetadata(JMediaMetadataRetriever::Title); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::Title); if (!string.isNull()) m_metadata.insert(QMediaMetaData::Title, string); - string = m_retriever->extractMetadata(JMediaMetadataRetriever::VideoHeight); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::VideoHeight); if (!string.isNull()) { int height = string.toInt(); - int width = m_retriever->extractMetadata(JMediaMetadataRetriever::VideoWidth).toInt(); + int width = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::VideoWidth).toInt(); m_metadata.insert(QMediaMetaData::Resolution, QSize(width, height)); } - string = m_retriever->extractMetadata(JMediaMetadataRetriever::Writer); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::Writer); if (!string.isNull()) m_metadata.insert(QMediaMetaData::Writer, string.split('/', QString::SkipEmptyParts)); - string = m_retriever->extractMetadata(JMediaMetadataRetriever::Year); + string = m_retriever->extractMetadata(AndroidMediaMetadataRetriever::Year); if (!string.isNull()) m_metadata.insert(QMediaMetaData::Year, string.toInt()); } diff --git a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h index 7ea736ffd..67b92f1eb 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h +++ b/src/plugins/android/src/mediaplayer/qandroidmetadatareadercontrol.h @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE -class JMediaMetadataRetriever; +class AndroidMediaMetadataRetriever; class QAndroidMetaDataReaderControl : public QMetaDataReaderControl { @@ -72,7 +72,7 @@ private: bool m_available; QVariantMap m_metadata; - JMediaMetadataRetriever *m_retriever; + AndroidMediaMetadataRetriever *m_retriever; }; QT_END_NAMESPACE diff --git a/src/plugins/android/src/qandroidmediaserviceplugin.cpp b/src/plugins/android/src/qandroidmediaserviceplugin.cpp index 6c1515308..4d777ce97 100644 --- a/src/plugins/android/src/qandroidmediaserviceplugin.cpp +++ b/src/plugins/android/src/qandroidmediaserviceplugin.cpp @@ -46,11 +46,11 @@ #include "qandroidaudioinputselectorcontrol.h" #include "qandroidcamerainfocontrol.h" #include "qandroidcamerasession.h" -#include "jmediaplayer.h" -#include "jsurfacetexture.h" -#include "jcamera.h" -#include "jmultimediautils.h" -#include "jmediarecorder.h" +#include "androidmediaplayer.h" +#include "androidsurfacetexture.h" +#include "androidcamera.h" +#include "androidmultimediautils.h" +#include "androidmediarecorder.h" #include QT_BEGIN_NAMESPACE @@ -149,6 +149,7 @@ int QAndroidMediaServicePlugin::cameraOrientation(const QByteArray &device) cons QT_END_NAMESPACE +#ifndef Q_OS_ANDROID_NO_SDK Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/) { QT_USE_NAMESPACE @@ -165,13 +166,14 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/) JNIEnv *jniEnv = uenv.nativeEnvironment; - if (!JMediaPlayer::initJNI(jniEnv) || - !JCamera::initJNI(jniEnv) || - !JMediaRecorder::initJNI(jniEnv)) { + if (!AndroidMediaPlayer::initJNI(jniEnv) || + !AndroidCamera::initJNI(jniEnv) || + !AndroidMediaRecorder::initJNI(jniEnv)) { return JNI_ERR; } - JSurfaceTexture::initJNI(jniEnv); + AndroidSurfaceTexture::initJNI(jniEnv); return JNI_VERSION_1_4; } +#endif // Q_OS_ANDROID_NO_SDK diff --git a/src/plugins/android/src/src.pro b/src/plugins/android/src/src.pro index d071f6fcd..6a472a0a8 100644 --- a/src/plugins/android/src/src.pro +++ b/src/plugins/android/src/src.pro @@ -11,7 +11,7 @@ HEADERS += \ SOURCES += \ qandroidmediaserviceplugin.cpp -include (wrappers/wrappers.pri) +include (wrappers/jni/jni.pri) include (common/common.pri) include (mediaplayer/mediaplayer.pri) include (mediacapture/mediacapture.pri) diff --git a/src/plugins/android/src/wrappers/jcamera.cpp b/src/plugins/android/src/wrappers/jcamera.cpp deleted file mode 100644 index 5401e6d1f..000000000 --- a/src/plugins/android/src/wrappers/jcamera.cpp +++ /dev/null @@ -1,1366 +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 "jcamera.h" - -#include -#include -#include "qandroidmultimediautils.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -static jclass g_qtCameraListenerClass = 0; -static QMutex g_cameraMapMutex; -typedef QMap CameraMap; -Q_GLOBAL_STATIC(CameraMap, g_cameraMap) - -static QRect areaToRect(jobject areaObj) -{ - QJNIObjectPrivate area(areaObj); - QJNIObjectPrivate rect = area.getObjectField("rect", "Landroid/graphics/Rect;"); - - return QRect(rect.getField("left"), - rect.getField("top"), - rect.callMethod("width"), - rect.callMethod("height")); -} - -static QJNIObjectPrivate rectToArea(const QRect &rect) -{ - QJNIObjectPrivate jrect("android/graphics/Rect", - "(IIII)V", - rect.left(), rect.top(), rect.right(), rect.bottom()); - - QJNIObjectPrivate area("android/hardware/Camera$Area", - "(Landroid/graphics/Rect;I)V", - jrect.object(), 500); - - return area; -} - -// native method for QtCameraLisener.java -static void notifyAutoFocusComplete(JNIEnv* , jobject, int id, jboolean success) -{ - QMutexLocker locker(&g_cameraMapMutex); - JCamera *obj = g_cameraMap->value(id, 0); - if (obj) - Q_EMIT obj->autoFocusComplete(success); -} - -static void notifyPictureExposed(JNIEnv* , jobject, int id) -{ - QMutexLocker locker(&g_cameraMapMutex); - JCamera *obj = g_cameraMap->value(id, 0); - if (obj) - Q_EMIT obj->pictureExposed(); -} - -static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data) -{ - QMutexLocker locker(&g_cameraMapMutex); - JCamera *obj = g_cameraMap->value(id, 0); - if (obj) { - const int arrayLength = env->GetArrayLength(data); - QByteArray bytes(arrayLength, Qt::Uninitialized); - env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); - Q_EMIT obj->pictureCaptured(bytes); - } -} - -static void notifyFrameFetched(JNIEnv *env, jobject, int id, jbyteArray data) -{ - QMutexLocker locker(&g_cameraMapMutex); - JCamera *obj = g_cameraMap->value(id, 0); - if (obj) { - const int arrayLength = env->GetArrayLength(data); - QByteArray bytes(arrayLength, Qt::Uninitialized); - env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); - - Q_EMIT obj->frameFetched(bytes); - } -} - -class JCameraPrivate : public QObject -{ - Q_OBJECT -public: - JCameraPrivate(); - ~JCameraPrivate(); - - Q_INVOKABLE bool init(int cameraId); - - Q_INVOKABLE void release(); - Q_INVOKABLE void lock(); - Q_INVOKABLE void unlock(); - Q_INVOKABLE void reconnect(); - - Q_INVOKABLE JCamera::CameraFacing getFacing(); - Q_INVOKABLE int getNativeOrientation(); - - Q_INVOKABLE QSize getPreferredPreviewSizeForVideo(); - Q_INVOKABLE QList getSupportedPreviewSizes(); - - Q_INVOKABLE JCamera::ImageFormat getPreviewFormat(); - Q_INVOKABLE void setPreviewFormat(JCamera::ImageFormat fmt); - - Q_INVOKABLE QSize previewSize() const { return m_previewSize; } - Q_INVOKABLE void updatePreviewSize(); - Q_INVOKABLE void setPreviewTexture(void *surfaceTexture); - - Q_INVOKABLE bool isZoomSupported(); - Q_INVOKABLE int getMaxZoom(); - Q_INVOKABLE QList getZoomRatios(); - Q_INVOKABLE int getZoom(); - Q_INVOKABLE void setZoom(int value); - - Q_INVOKABLE QString getFlashMode(); - Q_INVOKABLE void setFlashMode(const QString &value); - - Q_INVOKABLE QString getFocusMode(); - Q_INVOKABLE void setFocusMode(const QString &value); - - Q_INVOKABLE int getMaxNumFocusAreas(); - Q_INVOKABLE QList getFocusAreas(); - Q_INVOKABLE void setFocusAreas(const QList &areas); - - Q_INVOKABLE void autoFocus(); - Q_INVOKABLE void cancelAutoFocus(); - - Q_INVOKABLE bool isAutoExposureLockSupported(); - Q_INVOKABLE bool getAutoExposureLock(); - Q_INVOKABLE void setAutoExposureLock(bool toggle); - - Q_INVOKABLE bool isAutoWhiteBalanceLockSupported(); - Q_INVOKABLE bool getAutoWhiteBalanceLock(); - Q_INVOKABLE void setAutoWhiteBalanceLock(bool toggle); - - Q_INVOKABLE int getExposureCompensation(); - Q_INVOKABLE void setExposureCompensation(int value); - Q_INVOKABLE float getExposureCompensationStep(); - Q_INVOKABLE int getMinExposureCompensation(); - Q_INVOKABLE int getMaxExposureCompensation(); - - Q_INVOKABLE QString getSceneMode(); - Q_INVOKABLE void setSceneMode(const QString &value); - - Q_INVOKABLE QString getWhiteBalance(); - Q_INVOKABLE void setWhiteBalance(const QString &value); - - Q_INVOKABLE void updateRotation(); - - Q_INVOKABLE QList getSupportedPictureSizes(); - Q_INVOKABLE void setPictureSize(const QSize &size); - Q_INVOKABLE void setJpegQuality(int quality); - - Q_INVOKABLE void startPreview(); - Q_INVOKABLE void stopPreview(); - - Q_INVOKABLE void takePicture(); - - Q_INVOKABLE void fetchEachFrame(bool fetch); - Q_INVOKABLE void fetchLastPreviewFrame(); - - Q_INVOKABLE void applyParameters(); - - Q_INVOKABLE QStringList callParametersStringListMethod(const QByteArray &methodName); - - int m_cameraId; - QMutex m_parametersMutex; - QSize m_previewSize; - int m_rotation; - QJNIObjectPrivate m_info; - QJNIObjectPrivate m_parameters; - QJNIObjectPrivate m_camera; - QJNIObjectPrivate m_cameraListener; - -Q_SIGNALS: - void previewSizeChanged(); - void previewStarted(); - void previewStopped(); - - void autoFocusStarted(); - - void whiteBalanceChanged(); - - void previewFetched(const QByteArray &preview); -}; - -JCamera::JCamera(JCameraPrivate *d, QThread *worker) - : QObject(), - d_ptr(d), - m_worker(worker) - -{ - qRegisterMetaType >(); - qRegisterMetaType >(); - qRegisterMetaType >(); - - connect(d, &JCameraPrivate::previewSizeChanged, this, &JCamera::previewSizeChanged); - connect(d, &JCameraPrivate::previewStarted, this, &JCamera::previewStarted); - connect(d, &JCameraPrivate::previewStopped, this, &JCamera::previewStopped); - connect(d, &JCameraPrivate::autoFocusStarted, this, &JCamera::autoFocusStarted); - connect(d, &JCameraPrivate::whiteBalanceChanged, this, &JCamera::whiteBalanceChanged); - connect(d, &JCameraPrivate::previewFetched, this, &JCamera::previewFetched); -} - -JCamera::~JCamera() -{ - Q_D(JCamera); - if (d->m_camera.isValid()) { - g_cameraMapMutex.lock(); - g_cameraMap->remove(d->m_cameraId); - g_cameraMapMutex.unlock(); - } - - release(); - m_worker->exit(); - m_worker->wait(5000); -} - -JCamera *JCamera::open(int cameraId) -{ - JCameraPrivate *d = new JCameraPrivate(); - QThread *worker = new QThread; - worker->start(); - d->moveToThread(worker); - connect(worker, &QThread::finished, d, &JCameraPrivate::deleteLater); - bool ok = false; - QMetaObject::invokeMethod(d, "init", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok), Q_ARG(int, cameraId)); - if (!ok) { - worker->quit(); - worker->wait(5000); - delete d; - delete worker; - return 0; - } - - JCamera *q = new JCamera(d, worker); - g_cameraMapMutex.lock(); - g_cameraMap->insert(cameraId, q); - g_cameraMapMutex.unlock(); - return q; -} - -int JCamera::cameraId() const -{ - Q_D(const JCamera); - return d->m_cameraId; -} - -void JCamera::lock() -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "lock", Qt::BlockingQueuedConnection); -} - -void JCamera::unlock() -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "unlock", Qt::BlockingQueuedConnection); -} - -void JCamera::reconnect() -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "reconnect"); -} - -void JCamera::release() -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "release", Qt::BlockingQueuedConnection); -} - -JCamera::CameraFacing JCamera::getFacing() -{ - Q_D(JCamera); - return d->getFacing(); -} - -int JCamera::getNativeOrientation() -{ - Q_D(JCamera); - return d->getNativeOrientation(); -} - -QSize JCamera::getPreferredPreviewSizeForVideo() -{ - Q_D(JCamera); - return d->getPreferredPreviewSizeForVideo(); -} - -QList JCamera::getSupportedPreviewSizes() -{ - Q_D(JCamera); - return d->getSupportedPreviewSizes(); -} - -JCamera::ImageFormat JCamera::getPreviewFormat() -{ - Q_D(JCamera); - return d->getPreviewFormat(); -} - -void JCamera::setPreviewFormat(ImageFormat fmt) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setPreviewFormat", Q_ARG(JCamera::ImageFormat, fmt)); -} - -QSize JCamera::previewSize() const -{ - Q_D(const JCamera); - return d->m_previewSize; -} - -void JCamera::setPreviewSize(const QSize &size) -{ - Q_D(JCamera); - d->m_parametersMutex.lock(); - bool areParametersValid = d->m_parameters.isValid(); - d->m_parametersMutex.unlock(); - if (!areParametersValid) - return; - - d->m_previewSize = size; - QMetaObject::invokeMethod(d, "updatePreviewSize"); -} - -void JCamera::setPreviewTexture(jobject surfaceTexture) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setPreviewTexture", Qt::BlockingQueuedConnection, Q_ARG(void *, surfaceTexture)); -} - -bool JCamera::isZoomSupported() -{ - Q_D(JCamera); - return d->isZoomSupported(); -} - -int JCamera::getMaxZoom() -{ - Q_D(JCamera); - return d->getMaxZoom(); -} - -QList JCamera::getZoomRatios() -{ - Q_D(JCamera); - return d->getZoomRatios(); -} - -int JCamera::getZoom() -{ - Q_D(JCamera); - return d->getZoom(); -} - -void JCamera::setZoom(int value) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setZoom", Q_ARG(int, value)); -} - -QStringList JCamera::getSupportedFlashModes() -{ - Q_D(JCamera); - return d->callParametersStringListMethod("getSupportedFlashModes"); -} - -QString JCamera::getFlashMode() -{ - Q_D(JCamera); - return d->getFlashMode(); -} - -void JCamera::setFlashMode(const QString &value) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setFlashMode", Q_ARG(QString, value)); -} - -QStringList JCamera::getSupportedFocusModes() -{ - Q_D(JCamera); - return d->callParametersStringListMethod("getSupportedFocusModes"); -} - -QString JCamera::getFocusMode() -{ - Q_D(JCamera); - return d->getFocusMode(); -} - -void JCamera::setFocusMode(const QString &value) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setFocusMode", Q_ARG(QString, value)); -} - -int JCamera::getMaxNumFocusAreas() -{ - Q_D(JCamera); - return d->getMaxNumFocusAreas(); -} - -QList JCamera::getFocusAreas() -{ - Q_D(JCamera); - return d->getFocusAreas(); -} - -void JCamera::setFocusAreas(const QList &areas) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setFocusAreas", Q_ARG(QList, areas)); -} - -void JCamera::autoFocus() -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "autoFocus"); -} - -void JCamera::cancelAutoFocus() -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "cancelAutoFocus", Qt::QueuedConnection); -} - -bool JCamera::isAutoExposureLockSupported() -{ - Q_D(JCamera); - return d->isAutoExposureLockSupported(); -} - -bool JCamera::getAutoExposureLock() -{ - Q_D(JCamera); - return d->getAutoExposureLock(); -} - -void JCamera::setAutoExposureLock(bool toggle) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setAutoExposureLock", Q_ARG(bool, toggle)); -} - -bool JCamera::isAutoWhiteBalanceLockSupported() -{ - Q_D(JCamera); - return d->isAutoWhiteBalanceLockSupported(); -} - -bool JCamera::getAutoWhiteBalanceLock() -{ - Q_D(JCamera); - return d->getAutoWhiteBalanceLock(); -} - -void JCamera::setAutoWhiteBalanceLock(bool toggle) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setAutoWhiteBalanceLock", Q_ARG(bool, toggle)); -} - -int JCamera::getExposureCompensation() -{ - Q_D(JCamera); - return d->getExposureCompensation(); -} - -void JCamera::setExposureCompensation(int value) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setExposureCompensation", Q_ARG(int, value)); -} - -float JCamera::getExposureCompensationStep() -{ - Q_D(JCamera); - return d->getExposureCompensationStep(); -} - -int JCamera::getMinExposureCompensation() -{ - Q_D(JCamera); - return d->getMinExposureCompensation(); -} - -int JCamera::getMaxExposureCompensation() -{ - Q_D(JCamera); - return d->getMaxExposureCompensation(); -} - -QStringList JCamera::getSupportedSceneModes() -{ - Q_D(JCamera); - return d->callParametersStringListMethod("getSupportedSceneModes"); -} - -QString JCamera::getSceneMode() -{ - Q_D(JCamera); - return d->getSceneMode(); -} - -void JCamera::setSceneMode(const QString &value) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setSceneMode", Q_ARG(QString, value)); -} - -QStringList JCamera::getSupportedWhiteBalance() -{ - Q_D(JCamera); - return d->callParametersStringListMethod("getSupportedWhiteBalance"); -} - -QString JCamera::getWhiteBalance() -{ - Q_D(JCamera); - return d->getWhiteBalance(); -} - -void JCamera::setWhiteBalance(const QString &value) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setWhiteBalance", Q_ARG(QString, value)); -} - -void JCamera::setRotation(int rotation) -{ - Q_D(JCamera); - //We need to do it here and not in worker class because we cache rotation - d->m_parametersMutex.lock(); - bool areParametersValid = d->m_parameters.isValid(); - d->m_parametersMutex.unlock(); - if (!areParametersValid) - return; - - d->m_rotation = rotation; - QMetaObject::invokeMethod(d, "updateRotation"); -} - -int JCamera::getRotation() const -{ - Q_D(const JCamera); - return d->m_rotation; -} - -QList JCamera::getSupportedPictureSizes() -{ - Q_D(JCamera); - return d->getSupportedPictureSizes(); -} - -void JCamera::setPictureSize(const QSize &size) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setPictureSize", Q_ARG(QSize, size)); -} - -void JCamera::setJpegQuality(int quality) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "setJpegQuality", Q_ARG(int, quality)); -} - -void JCamera::takePicture() -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "takePicture", Qt::BlockingQueuedConnection); -} - -void JCamera::fetchEachFrame(bool fetch) -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "fetchEachFrame", Q_ARG(bool, fetch)); -} - -void JCamera::fetchLastPreviewFrame() -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "fetchLastPreviewFrame"); -} - -QJNIObjectPrivate JCamera::getCameraObject() -{ - Q_D(JCamera); - return d->m_camera; -} - -void JCamera::startPreview() -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "startPreview"); -} - -void JCamera::stopPreview() -{ - Q_D(JCamera); - QMetaObject::invokeMethod(d, "stopPreview"); -} - -JCameraPrivate::JCameraPrivate() - : QObject(), - m_parametersMutex(QMutex::Recursive) -{ -} - -JCameraPrivate::~JCameraPrivate() -{ -} - -bool JCameraPrivate::init(int cameraId) -{ - m_cameraId = cameraId; - m_camera = QJNIObjectPrivate::callStaticObjectMethod("android/hardware/Camera", - "open", - "(I)Landroid/hardware/Camera;", - cameraId); - - if (!m_camera.isValid()) - return false; - - m_cameraListener = QJNIObjectPrivate(g_qtCameraListenerClass, "(I)V", m_cameraId); - m_info = QJNIObjectPrivate("android/hardware/Camera$CameraInfo"); - m_camera.callStaticMethod("android/hardware/Camera", - "getCameraInfo", - "(ILandroid/hardware/Camera$CameraInfo;)V", - cameraId, - m_info.object()); - - QJNIObjectPrivate params = m_camera.callObjectMethod("getParameters", - "()Landroid/hardware/Camera$Parameters;"); - m_parameters = QJNIObjectPrivate(params); - - return true; -} - -void JCameraPrivate::release() -{ - m_previewSize = QSize(); - m_parametersMutex.lock(); - m_parameters = QJNIObjectPrivate(); - m_parametersMutex.unlock(); - if (m_camera.isValid()) - m_camera.callMethod("release"); -} - -void JCameraPrivate::lock() -{ - m_camera.callMethod("lock"); -} - -void JCameraPrivate::unlock() -{ - m_camera.callMethod("unlock"); -} - -void JCameraPrivate::reconnect() -{ - QJNIEnvironmentPrivate env; - m_camera.callMethod("reconnect"); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionDescribe(); - } -} - -JCamera::CameraFacing JCameraPrivate::getFacing() -{ - return JCamera::CameraFacing(m_info.getField("facing")); -} - -int JCameraPrivate::getNativeOrientation() -{ - return m_info.getField("orientation"); -} - -QSize JCameraPrivate::getPreferredPreviewSizeForVideo() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return QSize(); - - QJNIObjectPrivate size = m_parameters.callObjectMethod("getPreferredPreviewSizeForVideo", - "()Landroid/hardware/Camera$Size;"); - - return QSize(size.getField("width"), size.getField("height")); -} - -QList JCameraPrivate::getSupportedPreviewSizes() -{ - QList list; - - QMutexLocker parametersLocker(&m_parametersMutex); - - if (m_parameters.isValid()) { - QJNIObjectPrivate sizeList = m_parameters.callObjectMethod("getSupportedPreviewSizes", - "()Ljava/util/List;"); - int count = sizeList.callMethod("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate size = sizeList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - list.append(QSize(size.getField("width"), size.getField("height"))); - } - - qSort(list.begin(), list.end(), qt_sizeLessThan); - } - - return list; -} - -JCamera::ImageFormat JCameraPrivate::getPreviewFormat() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return JCamera::Unknown; - - return JCamera::ImageFormat(m_parameters.callMethod("getPreviewFormat")); -} - -void JCameraPrivate::setPreviewFormat(JCamera::ImageFormat fmt) -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setPreviewFormat", "(I)V", jint(fmt)); - applyParameters(); -} - -void JCameraPrivate::updatePreviewSize() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (m_previewSize.isValid()) { - m_parameters.callMethod("setPreviewSize", "(II)V", m_previewSize.width(), m_previewSize.height()); - applyParameters(); - } - - emit previewSizeChanged(); -} - -void JCameraPrivate::setPreviewTexture(void *surfaceTexture) -{ - m_camera.callMethod("setPreviewTexture", - "(Landroid/graphics/SurfaceTexture;)V", - static_cast(surfaceTexture)); -} - -bool JCameraPrivate::isZoomSupported() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod("isZoomSupported"); -} - -int JCameraPrivate::getMaxZoom() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod("getMaxZoom"); -} - -QList JCameraPrivate::getZoomRatios() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - QList ratios; - - if (m_parameters.isValid()) { - QJNIObjectPrivate ratioList = m_parameters.callObjectMethod("getZoomRatios", - "()Ljava/util/List;"); - int count = ratioList.callMethod("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate zoomRatio = ratioList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - - ratios.append(zoomRatio.callMethod("intValue")); - } - } - - return ratios; -} - -int JCameraPrivate::getZoom() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod("getZoom"); -} - -void JCameraPrivate::setZoom(int value) -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setZoom", "(I)V", value); - applyParameters(); -} - -QString JCameraPrivate::getFlashMode() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate flashMode = m_parameters.callObjectMethod("getFlashMode", - "()Ljava/lang/String;"); - if (flashMode.isValid()) - value = flashMode.toString(); - } - - return value; -} - -void JCameraPrivate::setFlashMode(const QString &value) -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setFlashMode", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); -} - -QString JCameraPrivate::getFocusMode() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate focusMode = m_parameters.callObjectMethod("getFocusMode", - "()Ljava/lang/String;"); - if (focusMode.isValid()) - value = focusMode.toString(); - } - - return value; -} - -void JCameraPrivate::setFocusMode(const QString &value) -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setFocusMode", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); -} - -int JCameraPrivate::getMaxNumFocusAreas() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return 0; - - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod("getMaxNumFocusAreas"); -} - -QList JCameraPrivate::getFocusAreas() -{ - QList areas; - - if (QtAndroidPrivate::androidSdkVersion() < 14) - return areas; - - QMutexLocker parametersLocker(&m_parametersMutex); - - if (m_parameters.isValid()) { - QJNIObjectPrivate list = m_parameters.callObjectMethod("getFocusAreas", - "()Ljava/util/List;"); - - if (list.isValid()) { - int count = list.callMethod("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate area = list.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - - areas.append(areaToRect(area.object())); - } - } - } - - return areas; -} - -void JCameraPrivate::setFocusAreas(const QList &areas) -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - QJNIObjectPrivate list; - - if (!areas.isEmpty()) { - QJNIEnvironmentPrivate env; - QJNIObjectPrivate 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 = arrayList; - } - - m_parameters.callMethod("setFocusAreas", "(Ljava/util/List;)V", list.object()); - - applyParameters(); -} - -void JCameraPrivate::autoFocus() -{ - m_camera.callMethod("autoFocus", - "(Landroid/hardware/Camera$AutoFocusCallback;)V", - m_cameraListener.object()); - emit autoFocusStarted(); -} - -void JCameraPrivate::cancelAutoFocus() -{ - m_camera.callMethod("cancelAutoFocus"); -} - -bool JCameraPrivate::isAutoExposureLockSupported() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod("isAutoExposureLockSupported"); -} - -bool JCameraPrivate::getAutoExposureLock() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod("getAutoExposureLock"); -} - -void JCameraPrivate::setAutoExposureLock(bool toggle) -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setAutoExposureLock", "(Z)V", toggle); - applyParameters(); -} - -bool JCameraPrivate::isAutoWhiteBalanceLockSupported() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod("isAutoWhiteBalanceLockSupported"); -} - -bool JCameraPrivate::getAutoWhiteBalanceLock() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return false; - - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return false; - - return m_parameters.callMethod("getAutoWhiteBalanceLock"); -} - -void JCameraPrivate::setAutoWhiteBalanceLock(bool toggle) -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setAutoWhiteBalanceLock", "(Z)V", toggle); - applyParameters(); -} - -int JCameraPrivate::getExposureCompensation() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod("getExposureCompensation"); -} - -void JCameraPrivate::setExposureCompensation(int value) -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setExposureCompensation", "(I)V", value); - applyParameters(); -} - -float JCameraPrivate::getExposureCompensationStep() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod("getExposureCompensationStep"); -} - -int JCameraPrivate::getMinExposureCompensation() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod("getMinExposureCompensation"); -} - -int JCameraPrivate::getMaxExposureCompensation() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return 0; - - return m_parameters.callMethod("getMaxExposureCompensation"); -} - -QString JCameraPrivate::getSceneMode() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate sceneMode = m_parameters.callObjectMethod("getSceneMode", - "()Ljava/lang/String;"); - if (sceneMode.isValid()) - value = sceneMode.toString(); - } - - return value; -} - -void JCameraPrivate::setSceneMode(const QString &value) -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setSceneMode", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); -} - -QString JCameraPrivate::getWhiteBalance() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - QString value; - - if (m_parameters.isValid()) { - QJNIObjectPrivate wb = m_parameters.callObjectMethod("getWhiteBalance", - "()Ljava/lang/String;"); - if (wb.isValid()) - value = wb.toString(); - } - - return value; -} - -void JCameraPrivate::setWhiteBalance(const QString &value) -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setWhiteBalance", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(value).object()); - applyParameters(); - - emit whiteBalanceChanged(); -} - -void JCameraPrivate::updateRotation() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - m_parameters.callMethod("setRotation", "(I)V", m_rotation); - applyParameters(); -} - -QList JCameraPrivate::getSupportedPictureSizes() -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - QList list; - - if (m_parameters.isValid()) { - QJNIObjectPrivate sizeList = m_parameters.callObjectMethod("getSupportedPictureSizes", - "()Ljava/util/List;"); - int count = sizeList.callMethod("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate size = sizeList.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - list.append(QSize(size.getField("width"), size.getField("height"))); - } - - qSort(list.begin(), list.end(), qt_sizeLessThan); - } - - return list; -} - -void JCameraPrivate::setPictureSize(const QSize &size) -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setPictureSize", "(II)V", size.width(), size.height()); - applyParameters(); -} - -void JCameraPrivate::setJpegQuality(int quality) -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - if (!m_parameters.isValid()) - return; - - m_parameters.callMethod("setJpegQuality", "(I)V", quality); - applyParameters(); -} - -void JCameraPrivate::startPreview() -{ - //We need to clear preview buffers queue here, but there is no method to do it - //Though just resetting preview callback do the trick - m_camera.callMethod("setPreviewCallbackWithBuffer", - "(Landroid/hardware/Camera$PreviewCallback;)V", - jobject(0)); - m_cameraListener.callMethod("preparePreviewBuffer", "(Landroid/hardware/Camera;)V", m_camera.object()); - QJNIObjectPrivate buffer = m_cameraListener.callObjectMethod("callbackBuffer"); - m_camera.callMethod("addCallbackBuffer", "([B)V", buffer.object()); - m_camera.callMethod("setPreviewCallbackWithBuffer", - "(Landroid/hardware/Camera$PreviewCallback;)V", - m_cameraListener.object()); - m_camera.callMethod("startPreview"); - emit previewStarted(); -} - -void JCameraPrivate::stopPreview() -{ - m_camera.callMethod("stopPreview"); - emit previewStopped(); -} - -void JCameraPrivate::takePicture() -{ - m_camera.callMethod("takePicture", "(Landroid/hardware/Camera$ShutterCallback;" - "Landroid/hardware/Camera$PictureCallback;" - "Landroid/hardware/Camera$PictureCallback;)V", - m_cameraListener.object(), - jobject(0), - m_cameraListener.object()); -} - -void JCameraPrivate::fetchEachFrame(bool fetch) -{ - m_cameraListener.callMethod("fetchEachFrame", "(Z)V", fetch); -} - -void JCameraPrivate::fetchLastPreviewFrame() -{ - QJNIEnvironmentPrivate env; - QJNIObjectPrivate data = m_cameraListener.callObjectMethod("lockAndFetchPreviewBuffer", "()[B"); - if (!data.isValid()) { - m_cameraListener.callMethod("unlockPreviewBuffer"); - return; - } - const int arrayLength = env->GetArrayLength(static_cast(data.object())); - QByteArray bytes(arrayLength, Qt::Uninitialized); - env->GetByteArrayRegion(static_cast(data.object()), - 0, - arrayLength, - reinterpret_cast(bytes.data())); - m_cameraListener.callMethod("unlockPreviewBuffer"); - - emit previewFetched(bytes); -} - -void JCameraPrivate::applyParameters() -{ - m_camera.callMethod("setParameters", - "(Landroid/hardware/Camera$Parameters;)V", - m_parameters.object()); -} - -QStringList JCameraPrivate::callParametersStringListMethod(const QByteArray &methodName) -{ - QMutexLocker parametersLocker(&m_parametersMutex); - - QStringList stringList; - - if (m_parameters.isValid()) { - QJNIObjectPrivate list = m_parameters.callObjectMethod(methodName.constData(), - "()Ljava/util/List;"); - - if (list.isValid()) { - int count = list.callMethod("size"); - for (int i = 0; i < count; ++i) { - QJNIObjectPrivate string = list.callObjectMethod("get", - "(I)Ljava/lang/Object;", - i); - stringList.append(string.toString()); - } - } - } - - return stringList; -} - -static JNINativeMethod methods[] = { - {"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete}, - {"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed}, - {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured}, - {"notifyFrameFetched", "(I[B)V", (void *)notifyFrameFetched} -}; - -bool JCamera::initJNI(JNIEnv *env) -{ - jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtCameraListener"); - if (env->ExceptionCheck()) - env->ExceptionClear(); - - if (clazz) { - g_qtCameraListenerClass = static_cast(env->NewGlobalRef(clazz)); - if (env->RegisterNatives(g_qtCameraListenerClass, - methods, - sizeof(methods) / sizeof(methods[0])) < 0) { - return false; - } - } - - return true; -} - -QT_END_NAMESPACE - -#include "jcamera.moc" diff --git a/src/plugins/android/src/wrappers/jcamera.h b/src/plugins/android/src/wrappers/jcamera.h deleted file mode 100644 index ec5bcc3c7..000000000 --- a/src/plugins/android/src/wrappers/jcamera.h +++ /dev/null @@ -1,187 +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 JCAMERA_H -#define JCAMERA_H - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QThread; - -class JCameraPrivate; - -class JCamera : public QObject -{ - Q_OBJECT - Q_ENUMS(CameraFacing) - Q_ENUMS(ImageFormat) -public: - enum CameraFacing { - CameraFacingBack = 0, - CameraFacingFront = 1 - }; - - enum ImageFormat { // same values as in android.graphics.ImageFormat Java class - Unknown = 0, - RGB565 = 4, - NV16 = 16, - NV21 = 17, - YUY2 = 20, - JPEG = 256, - YV12 = 842094169 - }; - - ~JCamera(); - - static JCamera *open(int cameraId); - - int cameraId() const; - - void lock(); - void unlock(); - void reconnect(); - void release(); - - CameraFacing getFacing(); - int getNativeOrientation(); - - QSize getPreferredPreviewSizeForVideo(); - QList getSupportedPreviewSizes(); - - ImageFormat getPreviewFormat(); - void setPreviewFormat(ImageFormat fmt); - - QSize previewSize() const; - 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); - int getRotation() const; - - QList getSupportedPictureSizes(); - void setPictureSize(const QSize &size); - void setJpegQuality(int quality); - - void startPreview(); - void stopPreview(); - - void takePicture(); - - void fetchEachFrame(bool fetch); - void fetchLastPreviewFrame(); - QJNIObjectPrivate getCameraObject(); - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void previewSizeChanged(); - void previewStarted(); - void previewStopped(); - - void autoFocusStarted(); - void autoFocusComplete(bool success); - - void whiteBalanceChanged(); - - void pictureExposed(); - void pictureCaptured(const QByteArray &data); - void previewFetched(const QByteArray &preview); - void frameFetched(const QByteArray &frame); - -private: - JCamera(JCameraPrivate *d, QThread *worker); - - Q_DECLARE_PRIVATE(JCamera) - JCameraPrivate *d_ptr; - QScopedPointer m_worker; -}; - -QT_END_NAMESPACE - -#endif // JCAMERA_H diff --git a/src/plugins/android/src/wrappers/jmediametadataretriever.cpp b/src/plugins/android/src/wrappers/jmediametadataretriever.cpp deleted file mode 100644 index 93b77ecb1..000000000 --- a/src/plugins/android/src/wrappers/jmediametadataretriever.cpp +++ /dev/null @@ -1,130 +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 - -QT_BEGIN_NAMESPACE - -JMediaMetadataRetriever::JMediaMetadataRetriever() -{ - m_metadataRetriever = QJNIObjectPrivate("android/media/MediaMetadataRetriever"); -} - -JMediaMetadataRetriever::~JMediaMetadataRetriever() -{ -} - -QString JMediaMetadataRetriever::extractMetadata(MetadataKey key) -{ - QString value; - - QJNIObjectPrivate metadata = m_metadataRetriever.callObjectMethod("extractMetadata", - "(I)Ljava/lang/String;", - jint(key)); - if (metadata.isValid()) - value = metadata.toString(); - - return value; -} - -void JMediaMetadataRetriever::release() -{ - if (!m_metadataRetriever.isValid()) - return; - - m_metadataRetriever.callMethod("release"); -} - -bool JMediaMetadataRetriever::setDataSource(const QUrl &url) -{ - if (!m_metadataRetriever.isValid()) - return false; - - QJNIEnvironmentPrivate env; - - bool loaded = false; - - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.toString()); - - QJNIObjectPrivate uri = m_metadataRetriever.callStaticObjectMethod("android/net/Uri", - "parse", - "(Ljava/lang/String;)Landroid/net/Uri;", - string.object()); - if (env->ExceptionCheck()) { - env->ExceptionClear(); - } else { - m_metadataRetriever.callMethod("setDataSource", - "(Landroid/content/Context;Landroid/net/Uri;)V", - QtAndroidPrivate::activity(), - uri.object()); - if (env->ExceptionCheck()) - env->ExceptionClear(); - else - loaded = true; - } - - return loaded; -} - -bool JMediaMetadataRetriever::setDataSource(const QString &path) -{ - if (!m_metadataRetriever.isValid()) - return false; - - QJNIEnvironmentPrivate env; - - bool loaded = false; - - m_metadataRetriever.callMethod("setDataSource", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(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 deleted file mode 100644 index 7b0340c0d..000000000 --- a/src/plugins/android/src/wrappers/jmediametadataretriever.h +++ /dev/null @@ -1,93 +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: - 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); - -private: - QJNIObjectPrivate m_metadataRetriever; -}; - -QT_END_NAMESPACE - -#endif // JMEDIAMETADATARETRIEVER_H diff --git a/src/plugins/android/src/wrappers/jmediaplayer.cpp b/src/plugins/android/src/wrappers/jmediaplayer.cpp deleted file mode 100644 index 98ccbfd5a..000000000 --- a/src/plugins/android/src/wrappers/jmediaplayer.cpp +++ /dev/null @@ -1,266 +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 - -static jclass mediaPlayerClass = Q_NULLPTR; -typedef QMap MediaPlayerMap; -Q_GLOBAL_STATIC(MediaPlayerMap, mediaPlayers) - -QT_BEGIN_NAMESPACE - -JMediaPlayer::JMediaPlayer() - : QObject() -{ - - const jlong id = reinterpret_cast(this); - mMediaPlayer = QJNIObjectPrivate(mediaPlayerClass, - "(Landroid/app/Activity;J)V", - QtAndroidPrivate::activity(), - id); - (*mediaPlayers)[id] = this; -} - -JMediaPlayer::~JMediaPlayer() -{ - mediaPlayers->remove(reinterpret_cast(this)); -} - -void JMediaPlayer::release() -{ - mMediaPlayer.callMethod("release"); -} - -void JMediaPlayer::reset() -{ - mMediaPlayer.callMethod("reset"); -} - -int JMediaPlayer::getCurrentPosition() -{ - return mMediaPlayer.callMethod("getCurrentPosition"); -} - -int JMediaPlayer::getDuration() -{ - return mMediaPlayer.callMethod("getDuration"); -} - -bool JMediaPlayer::isPlaying() -{ - return mMediaPlayer.callMethod("isPlaying"); -} - -int JMediaPlayer::volume() -{ - return mMediaPlayer.callMethod("getVolume"); -} - -bool JMediaPlayer::isMuted() -{ - return mMediaPlayer.callMethod("isMuted"); -} - -jobject JMediaPlayer::display() -{ - return mMediaPlayer.callObjectMethod("display", "()Landroid/view/SurfaceHolder;").object(); -} - -void JMediaPlayer::play() -{ - mMediaPlayer.callMethod("start"); -} - -void JMediaPlayer::pause() -{ - mMediaPlayer.callMethod("pause"); -} - -void JMediaPlayer::stop() -{ - mMediaPlayer.callMethod("stop"); -} - -void JMediaPlayer::seekTo(qint32 msec) -{ - mMediaPlayer.callMethod("seekTo", "(I)V", jint(msec)); -} - -void JMediaPlayer::setMuted(bool mute) -{ - mMediaPlayer.callMethod("mute", "(Z)V", jboolean(mute)); -} - -void JMediaPlayer::setDataSource(const QString &path) -{ - QJNIObjectPrivate string = QJNIObjectPrivate::fromString(path); - mMediaPlayer.callMethod("setDataSource", "(Ljava/lang/String;)V", string.object()); -} - -void JMediaPlayer::prepareAsync() -{ - mMediaPlayer.callMethod("prepareAsync"); -} - -void JMediaPlayer::setVolume(int volume) -{ - mMediaPlayer.callMethod("setVolume", "(I)V", jint(volume)); -} - -void JMediaPlayer::setDisplay(jobject surfaceHolder) -{ - mMediaPlayer.callMethod("setDisplay", "(Landroid/view/SurfaceHolder;)V", surfaceHolder); -} - -static void onErrorNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - JMediaPlayer *const mp = (*mediaPlayers)[id]; - if (!mp) - return; - - Q_EMIT mp->error(what, extra); -} - -static void onBufferingUpdateNative(JNIEnv *env, jobject thiz, jint percent, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - JMediaPlayer *const mp = (*mediaPlayers)[id]; - if (!mp) - return; - - Q_EMIT mp->bufferingChanged(percent); -} - -static void onProgressUpdateNative(JNIEnv *env, jobject thiz, jint progress, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - JMediaPlayer *const mp = (*mediaPlayers)[id]; - if (!mp) - return; - - Q_EMIT mp->progressChanged(progress); -} - -static void onDurationChangedNative(JNIEnv *env, jobject thiz, jint duration, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - JMediaPlayer *const mp = (*mediaPlayers)[id]; - if (!mp) - return; - - Q_EMIT mp->durationChanged(duration); -} - -static void onInfoNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - JMediaPlayer *const mp = (*mediaPlayers)[id]; - if (!mp) - return; - - Q_EMIT mp->info(what, extra); -} - -static void onStateChangedNative(JNIEnv *env, jobject thiz, jint state, jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - JMediaPlayer *const mp = (*mediaPlayers)[id]; - if (!mp) - return; - - Q_EMIT mp->stateChanged(state); -} - -static void onVideoSizeChangedNative(JNIEnv *env, - jobject thiz, - jint width, - jint height, - jlong id) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - JMediaPlayer *const mp = (*mediaPlayers)[id]; - if (!mp) - return; - - Q_EMIT mp->videoSizeChanged(width, height); -} - -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)}, - {"onProgressUpdateNative", "(IJ)V", reinterpret_cast(onProgressUpdateNative)}, - {"onDurationChangedNative", "(IJ)V", reinterpret_cast(onDurationChangedNative)}, - {"onInfoNative", "(IIJ)V", reinterpret_cast(onInfoNative)}, - {"onVideoSizeChangedNative", "(IIJ)V", reinterpret_cast(onVideoSizeChangedNative)}, - {"onStateChangedNative", "(IJ)V", reinterpret_cast(onStateChangedNative)} - }; - - 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 deleted file mode 100644 index cd469e677..000000000 --- a/src/plugins/android/src/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 -{ - Q_OBJECT -public: - JMediaPlayer(); - ~JMediaPlayer(); - - enum MediaError - { - // What - MEDIA_ERROR_UNKNOWN = 1, - MEDIA_ERROR_SERVER_DIED = 100, - MEDIA_ERROR_INVALID_STATE = -38, // Undocumented - // 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, - MEDIA_ERROR_BAD_THINGS_ARE_GOING_TO_HAPPEN = -2147483648 // Undocumented - }; - - 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 MediaPlayerState - { - Uninitialized = 0x1, /* End */ - Idle = 0x2, - Preparing = 0x4, - Prepared = 0x8, - Initialized = 0x10, - Started = 0x20, - Stopped = 0x40, - Paused = 0x80, - PlaybackCompleted = 0x100, - Error = 0x200 - }; - - void release(); - void reset(); - - int getCurrentPosition(); - int getDuration(); - bool isPlaying(); - int volume(); - bool isMuted(); - jobject display(); - - void play(); - void pause(); - void stop(); - void seekTo(qint32 msec); - void setMuted(bool mute); - void setDataSource(const QString &path); - void prepareAsync(); - void setVolume(int volume); - void setDisplay(jobject surfaceHolder); - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void error(qint32 what, qint32 extra); - void bufferingChanged(qint32 percent); - void durationChanged(qint64 duration); - void progressChanged(qint64 progress); - void stateChanged(qint32 state); - void info(qint32 what, qint32 extra); - void videoSizeChanged(qint32 width, qint32 height); - -private: - QJNIObjectPrivate mMediaPlayer; -}; - -QT_END_NAMESPACE - -#endif // QANDROIDMEDIAPLAYER_H diff --git a/src/plugins/android/src/wrappers/jmediarecorder.cpp b/src/plugins/android/src/wrappers/jmediarecorder.cpp deleted file mode 100644 index 0b1498d99..000000000 --- a/src/plugins/android/src/wrappers/jmediarecorder.cpp +++ /dev/null @@ -1,299 +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 "jmediarecorder.h" - -#include "jcamera.h" -#include -#include - -QT_BEGIN_NAMESPACE - -static jclass g_qtMediaRecorderListenerClass = 0; -typedef QMap MediaRecorderMap; -Q_GLOBAL_STATIC(MediaRecorderMap, mediaRecorders) - -static void notifyError(JNIEnv* , jobject, jlong id, jint what, jint extra) -{ - JMediaRecorder *obj = mediaRecorders->value(id, 0); - if (obj) - emit obj->error(what, extra); -} - -static void notifyInfo(JNIEnv* , jobject, jlong id, jint what, jint extra) -{ - JMediaRecorder *obj = mediaRecorders->value(id, 0); - if (obj) - emit obj->info(what, extra); -} - -JMediaRecorder::JMediaRecorder() - : QObject() - , m_id(reinterpret_cast(this)) -{ - m_mediaRecorder = QJNIObjectPrivate("android/media/MediaRecorder"); - if (m_mediaRecorder.isValid()) { - QJNIObjectPrivate listener(g_qtMediaRecorderListenerClass, "(J)V", m_id); - m_mediaRecorder.callMethod("setOnErrorListener", - "(Landroid/media/MediaRecorder$OnErrorListener;)V", - listener.object()); - m_mediaRecorder.callMethod("setOnInfoListener", - "(Landroid/media/MediaRecorder$OnInfoListener;)V", - listener.object()); - mediaRecorders->insert(m_id, this); - } -} - -JMediaRecorder::~JMediaRecorder() -{ - mediaRecorders->remove(m_id); -} - -void JMediaRecorder::release() -{ - m_mediaRecorder.callMethod("release"); -} - -bool JMediaRecorder::prepare() -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("prepare"); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - return false; - } - return true; -} - -void JMediaRecorder::reset() -{ - m_mediaRecorder.callMethod("reset"); -} - -bool JMediaRecorder::start() -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("start"); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - return false; - } - return true; -} - -void JMediaRecorder::stop() -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("stop"); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void JMediaRecorder::setAudioChannels(int numChannels) -{ - m_mediaRecorder.callMethod("setAudioChannels", "(I)V", numChannels); -} - -void JMediaRecorder::setAudioEncoder(AudioEncoder encoder) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("setAudioEncoder", "(I)V", int(encoder)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void JMediaRecorder::setAudioEncodingBitRate(int bitRate) -{ - m_mediaRecorder.callMethod("setAudioEncodingBitRate", "(I)V", bitRate); -} - -void JMediaRecorder::setAudioSamplingRate(int samplingRate) -{ - m_mediaRecorder.callMethod("setAudioSamplingRate", "(I)V", samplingRate); -} - -void JMediaRecorder::setAudioSource(AudioSource source) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("setAudioSource", "(I)V", int(source)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void JMediaRecorder::setCamera(JCamera *camera) -{ - QJNIObjectPrivate cam = camera->getCameraObject(); - m_mediaRecorder.callMethod("setCamera", "(Landroid/hardware/Camera;)V", cam.object()); -} - -void JMediaRecorder::setVideoEncoder(VideoEncoder encoder) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("setVideoEncoder", "(I)V", int(encoder)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void JMediaRecorder::setVideoEncodingBitRate(int bitRate) -{ - m_mediaRecorder.callMethod("setVideoEncodingBitRate", "(I)V", bitRate); -} - -void JMediaRecorder::setVideoFrameRate(int rate) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("setVideoFrameRate", "(I)V", rate); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void JMediaRecorder::setVideoSize(const QSize &size) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("setVideoSize", "(II)V", size.width(), size.height()); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void JMediaRecorder::setVideoSource(VideoSource source) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("setVideoSource", "(I)V", int(source)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void JMediaRecorder::setOrientationHint(int degrees) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("setOrientationHint", "(I)V", degrees); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void JMediaRecorder::setOutputFormat(OutputFormat format) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("setOutputFormat", "(I)V", int(format)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - env->ExceptionClear(); - } -} - -void JMediaRecorder::setOutputFile(const QString &path) -{ - QJNIEnvironmentPrivate env; - m_mediaRecorder.callMethod("setOutputFile", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(path).object()); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif - 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/QtMediaRecorderListener"); - if (env->ExceptionCheck()) - env->ExceptionClear(); - - if (clazz) { - g_qtMediaRecorderListenerClass = static_cast(env->NewGlobalRef(clazz)); - if (env->RegisterNatives(g_qtMediaRecorderListenerClass, - 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 deleted file mode 100644 index 3a83e7e16..000000000 --- a/src/plugins/android/src/wrappers/jmediarecorder.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 JMEDIARECORDER_H -#define JMEDIARECORDER_H - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class JCamera; - -class JMediaRecorder : public QObject -{ - 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; - QJNIObjectPrivate m_mediaRecorder; -}; - -QT_END_NAMESPACE - -#endif // JMEDIARECORDER_H diff --git a/src/plugins/android/src/wrappers/jmultimediautils.cpp b/src/plugins/android/src/wrappers/jmultimediautils.cpp deleted file mode 100644 index d1b0830c7..000000000 --- a/src/plugins/android/src/wrappers/jmultimediautils.cpp +++ /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$ -** -****************************************************************************/ - -#include "jmultimediautils.h" - -#include - -QT_BEGIN_NAMESPACE - - -void JMultimediaUtils::enableOrientationListener(bool enable) -{ - QJNIObjectPrivate::callStaticMethod("org/qtproject/qt5/android/multimedia/QtMultimediaUtils", - "enableOrientationListener", - "(Z)V", - enable); -} - -int JMultimediaUtils::getDeviceOrientation() -{ - return QJNIObjectPrivate::callStaticMethod("org/qtproject/qt5/android/multimedia/QtMultimediaUtils", - "getDeviceOrientation"); -} - -QString JMultimediaUtils::getDefaultMediaDirectory(MediaType type) -{ - QJNIObjectPrivate path = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt5/android/multimedia/QtMultimediaUtils", - "getDefaultMediaDirectory", - "(I)Ljava/lang/String;", - jint(type)); - return path.toString(); -} - -void JMultimediaUtils::registerMediaFile(const QString &file) -{ - QJNIObjectPrivate::callStaticMethod("org/qtproject/qt5/android/multimedia/QtMultimediaUtils", - "registerMediaFile", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(file).object()); -} - -QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jmultimediautils.h b/src/plugins/android/src/wrappers/jmultimediautils.h deleted file mode 100644 index b80ef4236..000000000 --- a/src/plugins/android/src/wrappers/jmultimediautils.h +++ /dev/null @@ -1,68 +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 JMULTIMEDIAUTILS_H -#define JMULTIMEDIAUTILS_H - -#include -#include - -QT_BEGIN_NAMESPACE - -class JMultimediaUtils -{ -public: - enum MediaType { - Music = 0, - Movies = 1, - DCIM = 2, - Sounds = 3 - }; - - static void enableOrientationListener(bool enable); - static int getDeviceOrientation(); - static QString getDefaultMediaDirectory(MediaType type); - static void registerMediaFile(const QString &file); -}; - -QT_END_NAMESPACE - -#endif // JMULTIMEDIAUTILS_H diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp new file mode 100644 index 000000000..af017c392 --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp @@ -0,0 +1,1366 @@ +/**************************************************************************** +** +** 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 "androidcamera.h" + +#include +#include +#include "qandroidmultimediautils.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +static jclass g_qtCameraListenerClass = 0; +static QMutex g_cameraMapMutex; +typedef QMap CameraMap; +Q_GLOBAL_STATIC(CameraMap, g_cameraMap) + +static QRect areaToRect(jobject areaObj) +{ + QJNIObjectPrivate area(areaObj); + QJNIObjectPrivate rect = area.getObjectField("rect", "Landroid/graphics/Rect;"); + + return QRect(rect.getField("left"), + rect.getField("top"), + rect.callMethod("width"), + rect.callMethod("height")); +} + +static QJNIObjectPrivate rectToArea(const QRect &rect) +{ + QJNIObjectPrivate jrect("android/graphics/Rect", + "(IIII)V", + rect.left(), rect.top(), rect.right(), rect.bottom()); + + QJNIObjectPrivate area("android/hardware/Camera$Area", + "(Landroid/graphics/Rect;I)V", + jrect.object(), 500); + + return area; +} + +// native method for QtCameraLisener.java +static void notifyAutoFocusComplete(JNIEnv* , jobject, int id, jboolean success) +{ + QMutexLocker locker(&g_cameraMapMutex); + AndroidCamera *obj = g_cameraMap->value(id, 0); + if (obj) + Q_EMIT obj->autoFocusComplete(success); +} + +static void notifyPictureExposed(JNIEnv* , jobject, int id) +{ + QMutexLocker locker(&g_cameraMapMutex); + AndroidCamera *obj = g_cameraMap->value(id, 0); + if (obj) + Q_EMIT obj->pictureExposed(); +} + +static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data) +{ + QMutexLocker locker(&g_cameraMapMutex); + AndroidCamera *obj = g_cameraMap->value(id, 0); + if (obj) { + const int arrayLength = env->GetArrayLength(data); + QByteArray bytes(arrayLength, Qt::Uninitialized); + env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); + Q_EMIT obj->pictureCaptured(bytes); + } +} + +static void notifyFrameFetched(JNIEnv *env, jobject, int id, jbyteArray data) +{ + QMutexLocker locker(&g_cameraMapMutex); + AndroidCamera *obj = g_cameraMap->value(id, 0); + if (obj) { + const int arrayLength = env->GetArrayLength(data); + QByteArray bytes(arrayLength, Qt::Uninitialized); + env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data()); + + Q_EMIT obj->frameFetched(bytes); + } +} + +class AndroidCameraPrivate : public QObject +{ + Q_OBJECT +public: + AndroidCameraPrivate(); + ~AndroidCameraPrivate(); + + Q_INVOKABLE bool init(int cameraId); + + Q_INVOKABLE void release(); + Q_INVOKABLE void lock(); + Q_INVOKABLE void unlock(); + Q_INVOKABLE void reconnect(); + + Q_INVOKABLE AndroidCamera::CameraFacing getFacing(); + Q_INVOKABLE int getNativeOrientation(); + + Q_INVOKABLE QSize getPreferredPreviewSizeForVideo(); + Q_INVOKABLE QList getSupportedPreviewSizes(); + + Q_INVOKABLE AndroidCamera::ImageFormat getPreviewFormat(); + Q_INVOKABLE void setPreviewFormat(AndroidCamera::ImageFormat fmt); + + Q_INVOKABLE QSize previewSize() const { return m_previewSize; } + Q_INVOKABLE void updatePreviewSize(); + Q_INVOKABLE void setPreviewTexture(void *surfaceTexture); + + Q_INVOKABLE bool isZoomSupported(); + Q_INVOKABLE int getMaxZoom(); + Q_INVOKABLE QList getZoomRatios(); + Q_INVOKABLE int getZoom(); + Q_INVOKABLE void setZoom(int value); + + Q_INVOKABLE QString getFlashMode(); + Q_INVOKABLE void setFlashMode(const QString &value); + + Q_INVOKABLE QString getFocusMode(); + Q_INVOKABLE void setFocusMode(const QString &value); + + Q_INVOKABLE int getMaxNumFocusAreas(); + Q_INVOKABLE QList getFocusAreas(); + Q_INVOKABLE void setFocusAreas(const QList &areas); + + Q_INVOKABLE void autoFocus(); + Q_INVOKABLE void cancelAutoFocus(); + + Q_INVOKABLE bool isAutoExposureLockSupported(); + Q_INVOKABLE bool getAutoExposureLock(); + Q_INVOKABLE void setAutoExposureLock(bool toggle); + + Q_INVOKABLE bool isAutoWhiteBalanceLockSupported(); + Q_INVOKABLE bool getAutoWhiteBalanceLock(); + Q_INVOKABLE void setAutoWhiteBalanceLock(bool toggle); + + Q_INVOKABLE int getExposureCompensation(); + Q_INVOKABLE void setExposureCompensation(int value); + Q_INVOKABLE float getExposureCompensationStep(); + Q_INVOKABLE int getMinExposureCompensation(); + Q_INVOKABLE int getMaxExposureCompensation(); + + Q_INVOKABLE QString getSceneMode(); + Q_INVOKABLE void setSceneMode(const QString &value); + + Q_INVOKABLE QString getWhiteBalance(); + Q_INVOKABLE void setWhiteBalance(const QString &value); + + Q_INVOKABLE void updateRotation(); + + Q_INVOKABLE QList getSupportedPictureSizes(); + Q_INVOKABLE void setPictureSize(const QSize &size); + Q_INVOKABLE void setJpegQuality(int quality); + + Q_INVOKABLE void startPreview(); + Q_INVOKABLE void stopPreview(); + + Q_INVOKABLE void takePicture(); + + Q_INVOKABLE void fetchEachFrame(bool fetch); + Q_INVOKABLE void fetchLastPreviewFrame(); + + Q_INVOKABLE void applyParameters(); + + Q_INVOKABLE QStringList callParametersStringListMethod(const QByteArray &methodName); + + int m_cameraId; + QMutex m_parametersMutex; + QSize m_previewSize; + int m_rotation; + QJNIObjectPrivate m_info; + QJNIObjectPrivate m_parameters; + QJNIObjectPrivate m_camera; + QJNIObjectPrivate m_cameraListener; + +Q_SIGNALS: + void previewSizeChanged(); + void previewStarted(); + void previewStopped(); + + void autoFocusStarted(); + + void whiteBalanceChanged(); + + void previewFetched(const QByteArray &preview); +}; + +AndroidCamera::AndroidCamera(AndroidCameraPrivate *d, QThread *worker) + : QObject(), + d_ptr(d), + m_worker(worker) + +{ + qRegisterMetaType >(); + qRegisterMetaType >(); + qRegisterMetaType >(); + + connect(d, &AndroidCameraPrivate::previewSizeChanged, this, &AndroidCamera::previewSizeChanged); + connect(d, &AndroidCameraPrivate::previewStarted, this, &AndroidCamera::previewStarted); + connect(d, &AndroidCameraPrivate::previewStopped, this, &AndroidCamera::previewStopped); + connect(d, &AndroidCameraPrivate::autoFocusStarted, this, &AndroidCamera::autoFocusStarted); + connect(d, &AndroidCameraPrivate::whiteBalanceChanged, this, &AndroidCamera::whiteBalanceChanged); + connect(d, &AndroidCameraPrivate::previewFetched, this, &AndroidCamera::previewFetched); +} + +AndroidCamera::~AndroidCamera() +{ + Q_D(AndroidCamera); + if (d->m_camera.isValid()) { + g_cameraMapMutex.lock(); + g_cameraMap->remove(d->m_cameraId); + g_cameraMapMutex.unlock(); + } + + release(); + m_worker->exit(); + m_worker->wait(5000); +} + +AndroidCamera *AndroidCamera::open(int cameraId) +{ + AndroidCameraPrivate *d = new AndroidCameraPrivate(); + QThread *worker = new QThread; + worker->start(); + d->moveToThread(worker); + connect(worker, &QThread::finished, d, &AndroidCameraPrivate::deleteLater); + bool ok = false; + QMetaObject::invokeMethod(d, "init", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, ok), Q_ARG(int, cameraId)); + if (!ok) { + worker->quit(); + worker->wait(5000); + delete d; + delete worker; + return 0; + } + + AndroidCamera *q = new AndroidCamera(d, worker); + g_cameraMapMutex.lock(); + g_cameraMap->insert(cameraId, q); + g_cameraMapMutex.unlock(); + return q; +} + +int AndroidCamera::cameraId() const +{ + Q_D(const AndroidCamera); + return d->m_cameraId; +} + +void AndroidCamera::lock() +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "lock", Qt::BlockingQueuedConnection); +} + +void AndroidCamera::unlock() +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "unlock", Qt::BlockingQueuedConnection); +} + +void AndroidCamera::reconnect() +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "reconnect"); +} + +void AndroidCamera::release() +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "release", Qt::BlockingQueuedConnection); +} + +AndroidCamera::CameraFacing AndroidCamera::getFacing() +{ + Q_D(AndroidCamera); + return d->getFacing(); +} + +int AndroidCamera::getNativeOrientation() +{ + Q_D(AndroidCamera); + return d->getNativeOrientation(); +} + +QSize AndroidCamera::getPreferredPreviewSizeForVideo() +{ + Q_D(AndroidCamera); + return d->getPreferredPreviewSizeForVideo(); +} + +QList AndroidCamera::getSupportedPreviewSizes() +{ + Q_D(AndroidCamera); + return d->getSupportedPreviewSizes(); +} + +AndroidCamera::ImageFormat AndroidCamera::getPreviewFormat() +{ + Q_D(AndroidCamera); + return d->getPreviewFormat(); +} + +void AndroidCamera::setPreviewFormat(ImageFormat fmt) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setPreviewFormat", Q_ARG(AndroidCamera::ImageFormat, fmt)); +} + +QSize AndroidCamera::previewSize() const +{ + Q_D(const AndroidCamera); + return d->m_previewSize; +} + +void AndroidCamera::setPreviewSize(const QSize &size) +{ + Q_D(AndroidCamera); + d->m_parametersMutex.lock(); + bool areParametersValid = d->m_parameters.isValid(); + d->m_parametersMutex.unlock(); + if (!areParametersValid) + return; + + d->m_previewSize = size; + QMetaObject::invokeMethod(d, "updatePreviewSize"); +} + +void AndroidCamera::setPreviewTexture(jobject surfaceTexture) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setPreviewTexture", Qt::BlockingQueuedConnection, Q_ARG(void *, surfaceTexture)); +} + +bool AndroidCamera::isZoomSupported() +{ + Q_D(AndroidCamera); + return d->isZoomSupported(); +} + +int AndroidCamera::getMaxZoom() +{ + Q_D(AndroidCamera); + return d->getMaxZoom(); +} + +QList AndroidCamera::getZoomRatios() +{ + Q_D(AndroidCamera); + return d->getZoomRatios(); +} + +int AndroidCamera::getZoom() +{ + Q_D(AndroidCamera); + return d->getZoom(); +} + +void AndroidCamera::setZoom(int value) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setZoom", Q_ARG(int, value)); +} + +QStringList AndroidCamera::getSupportedFlashModes() +{ + Q_D(AndroidCamera); + return d->callParametersStringListMethod("getSupportedFlashModes"); +} + +QString AndroidCamera::getFlashMode() +{ + Q_D(AndroidCamera); + return d->getFlashMode(); +} + +void AndroidCamera::setFlashMode(const QString &value) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setFlashMode", Q_ARG(QString, value)); +} + +QStringList AndroidCamera::getSupportedFocusModes() +{ + Q_D(AndroidCamera); + return d->callParametersStringListMethod("getSupportedFocusModes"); +} + +QString AndroidCamera::getFocusMode() +{ + Q_D(AndroidCamera); + return d->getFocusMode(); +} + +void AndroidCamera::setFocusMode(const QString &value) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setFocusMode", Q_ARG(QString, value)); +} + +int AndroidCamera::getMaxNumFocusAreas() +{ + Q_D(AndroidCamera); + return d->getMaxNumFocusAreas(); +} + +QList AndroidCamera::getFocusAreas() +{ + Q_D(AndroidCamera); + return d->getFocusAreas(); +} + +void AndroidCamera::setFocusAreas(const QList &areas) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setFocusAreas", Q_ARG(QList, areas)); +} + +void AndroidCamera::autoFocus() +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "autoFocus"); +} + +void AndroidCamera::cancelAutoFocus() +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "cancelAutoFocus", Qt::QueuedConnection); +} + +bool AndroidCamera::isAutoExposureLockSupported() +{ + Q_D(AndroidCamera); + return d->isAutoExposureLockSupported(); +} + +bool AndroidCamera::getAutoExposureLock() +{ + Q_D(AndroidCamera); + return d->getAutoExposureLock(); +} + +void AndroidCamera::setAutoExposureLock(bool toggle) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setAutoExposureLock", Q_ARG(bool, toggle)); +} + +bool AndroidCamera::isAutoWhiteBalanceLockSupported() +{ + Q_D(AndroidCamera); + return d->isAutoWhiteBalanceLockSupported(); +} + +bool AndroidCamera::getAutoWhiteBalanceLock() +{ + Q_D(AndroidCamera); + return d->getAutoWhiteBalanceLock(); +} + +void AndroidCamera::setAutoWhiteBalanceLock(bool toggle) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setAutoWhiteBalanceLock", Q_ARG(bool, toggle)); +} + +int AndroidCamera::getExposureCompensation() +{ + Q_D(AndroidCamera); + return d->getExposureCompensation(); +} + +void AndroidCamera::setExposureCompensation(int value) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setExposureCompensation", Q_ARG(int, value)); +} + +float AndroidCamera::getExposureCompensationStep() +{ + Q_D(AndroidCamera); + return d->getExposureCompensationStep(); +} + +int AndroidCamera::getMinExposureCompensation() +{ + Q_D(AndroidCamera); + return d->getMinExposureCompensation(); +} + +int AndroidCamera::getMaxExposureCompensation() +{ + Q_D(AndroidCamera); + return d->getMaxExposureCompensation(); +} + +QStringList AndroidCamera::getSupportedSceneModes() +{ + Q_D(AndroidCamera); + return d->callParametersStringListMethod("getSupportedSceneModes"); +} + +QString AndroidCamera::getSceneMode() +{ + Q_D(AndroidCamera); + return d->getSceneMode(); +} + +void AndroidCamera::setSceneMode(const QString &value) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setSceneMode", Q_ARG(QString, value)); +} + +QStringList AndroidCamera::getSupportedWhiteBalance() +{ + Q_D(AndroidCamera); + return d->callParametersStringListMethod("getSupportedWhiteBalance"); +} + +QString AndroidCamera::getWhiteBalance() +{ + Q_D(AndroidCamera); + return d->getWhiteBalance(); +} + +void AndroidCamera::setWhiteBalance(const QString &value) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setWhiteBalance", Q_ARG(QString, value)); +} + +void AndroidCamera::setRotation(int rotation) +{ + Q_D(AndroidCamera); + //We need to do it here and not in worker class because we cache rotation + d->m_parametersMutex.lock(); + bool areParametersValid = d->m_parameters.isValid(); + d->m_parametersMutex.unlock(); + if (!areParametersValid) + return; + + d->m_rotation = rotation; + QMetaObject::invokeMethod(d, "updateRotation"); +} + +int AndroidCamera::getRotation() const +{ + Q_D(const AndroidCamera); + return d->m_rotation; +} + +QList AndroidCamera::getSupportedPictureSizes() +{ + Q_D(AndroidCamera); + return d->getSupportedPictureSizes(); +} + +void AndroidCamera::setPictureSize(const QSize &size) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setPictureSize", Q_ARG(QSize, size)); +} + +void AndroidCamera::setJpegQuality(int quality) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "setJpegQuality", Q_ARG(int, quality)); +} + +void AndroidCamera::takePicture() +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "takePicture", Qt::BlockingQueuedConnection); +} + +void AndroidCamera::fetchEachFrame(bool fetch) +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "fetchEachFrame", Q_ARG(bool, fetch)); +} + +void AndroidCamera::fetchLastPreviewFrame() +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "fetchLastPreviewFrame"); +} + +QJNIObjectPrivate AndroidCamera::getCameraObject() +{ + Q_D(AndroidCamera); + return d->m_camera; +} + +void AndroidCamera::startPreview() +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "startPreview"); +} + +void AndroidCamera::stopPreview() +{ + Q_D(AndroidCamera); + QMetaObject::invokeMethod(d, "stopPreview"); +} + +AndroidCameraPrivate::AndroidCameraPrivate() + : QObject(), + m_parametersMutex(QMutex::Recursive) +{ +} + +AndroidCameraPrivate::~AndroidCameraPrivate() +{ +} + +bool AndroidCameraPrivate::init(int cameraId) +{ + m_cameraId = cameraId; + m_camera = QJNIObjectPrivate::callStaticObjectMethod("android/hardware/Camera", + "open", + "(I)Landroid/hardware/Camera;", + cameraId); + + if (!m_camera.isValid()) + return false; + + m_cameraListener = QJNIObjectPrivate(g_qtCameraListenerClass, "(I)V", m_cameraId); + m_info = QJNIObjectPrivate("android/hardware/Camera$CameraInfo"); + m_camera.callStaticMethod("android/hardware/Camera", + "getCameraInfo", + "(ILandroid/hardware/Camera$CameraInfo;)V", + cameraId, + m_info.object()); + + QJNIObjectPrivate params = m_camera.callObjectMethod("getParameters", + "()Landroid/hardware/Camera$Parameters;"); + m_parameters = QJNIObjectPrivate(params); + + return true; +} + +void AndroidCameraPrivate::release() +{ + m_previewSize = QSize(); + m_parametersMutex.lock(); + m_parameters = QJNIObjectPrivate(); + m_parametersMutex.unlock(); + if (m_camera.isValid()) + m_camera.callMethod("release"); +} + +void AndroidCameraPrivate::lock() +{ + m_camera.callMethod("lock"); +} + +void AndroidCameraPrivate::unlock() +{ + m_camera.callMethod("unlock"); +} + +void AndroidCameraPrivate::reconnect() +{ + QJNIEnvironmentPrivate env; + m_camera.callMethod("reconnect"); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif // QT_DEBUG + env->ExceptionDescribe(); + } +} + +AndroidCamera::CameraFacing AndroidCameraPrivate::getFacing() +{ + return AndroidCamera::CameraFacing(m_info.getField("facing")); +} + +int AndroidCameraPrivate::getNativeOrientation() +{ + return m_info.getField("orientation"); +} + +QSize AndroidCameraPrivate::getPreferredPreviewSizeForVideo() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return QSize(); + + QJNIObjectPrivate size = m_parameters.callObjectMethod("getPreferredPreviewSizeForVideo", + "()Landroid/hardware/Camera$Size;"); + + return QSize(size.getField("width"), size.getField("height")); +} + +QList AndroidCameraPrivate::getSupportedPreviewSizes() +{ + QList list; + + QMutexLocker parametersLocker(&m_parametersMutex); + + if (m_parameters.isValid()) { + QJNIObjectPrivate sizeList = m_parameters.callObjectMethod("getSupportedPreviewSizes", + "()Ljava/util/List;"); + int count = sizeList.callMethod("size"); + for (int i = 0; i < count; ++i) { + QJNIObjectPrivate size = sizeList.callObjectMethod("get", + "(I)Ljava/lang/Object;", + i); + list.append(QSize(size.getField("width"), size.getField("height"))); + } + + qSort(list.begin(), list.end(), qt_sizeLessThan); + } + + return list; +} + +AndroidCamera::ImageFormat AndroidCameraPrivate::getPreviewFormat() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return AndroidCamera::Unknown; + + return AndroidCamera::ImageFormat(m_parameters.callMethod("getPreviewFormat")); +} + +void AndroidCameraPrivate::setPreviewFormat(AndroidCamera::ImageFormat fmt) +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setPreviewFormat", "(I)V", jint(fmt)); + applyParameters(); +} + +void AndroidCameraPrivate::updatePreviewSize() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (m_previewSize.isValid()) { + m_parameters.callMethod("setPreviewSize", "(II)V", m_previewSize.width(), m_previewSize.height()); + applyParameters(); + } + + emit previewSizeChanged(); +} + +void AndroidCameraPrivate::setPreviewTexture(void *surfaceTexture) +{ + m_camera.callMethod("setPreviewTexture", + "(Landroid/graphics/SurfaceTexture;)V", + static_cast(surfaceTexture)); +} + +bool AndroidCameraPrivate::isZoomSupported() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return false; + + return m_parameters.callMethod("isZoomSupported"); +} + +int AndroidCameraPrivate::getMaxZoom() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return 0; + + return m_parameters.callMethod("getMaxZoom"); +} + +QList AndroidCameraPrivate::getZoomRatios() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + QList ratios; + + if (m_parameters.isValid()) { + QJNIObjectPrivate ratioList = m_parameters.callObjectMethod("getZoomRatios", + "()Ljava/util/List;"); + int count = ratioList.callMethod("size"); + for (int i = 0; i < count; ++i) { + QJNIObjectPrivate zoomRatio = ratioList.callObjectMethod("get", + "(I)Ljava/lang/Object;", + i); + + ratios.append(zoomRatio.callMethod("intValue")); + } + } + + return ratios; +} + +int AndroidCameraPrivate::getZoom() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return 0; + + return m_parameters.callMethod("getZoom"); +} + +void AndroidCameraPrivate::setZoom(int value) +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setZoom", "(I)V", value); + applyParameters(); +} + +QString AndroidCameraPrivate::getFlashMode() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + QString value; + + if (m_parameters.isValid()) { + QJNIObjectPrivate flashMode = m_parameters.callObjectMethod("getFlashMode", + "()Ljava/lang/String;"); + if (flashMode.isValid()) + value = flashMode.toString(); + } + + return value; +} + +void AndroidCameraPrivate::setFlashMode(const QString &value) +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setFlashMode", + "(Ljava/lang/String;)V", + QJNIObjectPrivate::fromString(value).object()); + applyParameters(); +} + +QString AndroidCameraPrivate::getFocusMode() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + QString value; + + if (m_parameters.isValid()) { + QJNIObjectPrivate focusMode = m_parameters.callObjectMethod("getFocusMode", + "()Ljava/lang/String;"); + if (focusMode.isValid()) + value = focusMode.toString(); + } + + return value; +} + +void AndroidCameraPrivate::setFocusMode(const QString &value) +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setFocusMode", + "(Ljava/lang/String;)V", + QJNIObjectPrivate::fromString(value).object()); + applyParameters(); +} + +int AndroidCameraPrivate::getMaxNumFocusAreas() +{ + if (QtAndroidPrivate::androidSdkVersion() < 14) + return 0; + + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return 0; + + return m_parameters.callMethod("getMaxNumFocusAreas"); +} + +QList AndroidCameraPrivate::getFocusAreas() +{ + QList areas; + + if (QtAndroidPrivate::androidSdkVersion() < 14) + return areas; + + QMutexLocker parametersLocker(&m_parametersMutex); + + if (m_parameters.isValid()) { + QJNIObjectPrivate list = m_parameters.callObjectMethod("getFocusAreas", + "()Ljava/util/List;"); + + if (list.isValid()) { + int count = list.callMethod("size"); + for (int i = 0; i < count; ++i) { + QJNIObjectPrivate area = list.callObjectMethod("get", + "(I)Ljava/lang/Object;", + i); + + areas.append(areaToRect(area.object())); + } + } + } + + return areas; +} + +void AndroidCameraPrivate::setFocusAreas(const QList &areas) +{ + if (QtAndroidPrivate::androidSdkVersion() < 14) + return; + + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + QJNIObjectPrivate list; + + if (!areas.isEmpty()) { + QJNIEnvironmentPrivate env; + QJNIObjectPrivate 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 = arrayList; + } + + m_parameters.callMethod("setFocusAreas", "(Ljava/util/List;)V", list.object()); + + applyParameters(); +} + +void AndroidCameraPrivate::autoFocus() +{ + m_camera.callMethod("autoFocus", + "(Landroid/hardware/Camera$AutoFocusCallback;)V", + m_cameraListener.object()); + emit autoFocusStarted(); +} + +void AndroidCameraPrivate::cancelAutoFocus() +{ + m_camera.callMethod("cancelAutoFocus"); +} + +bool AndroidCameraPrivate::isAutoExposureLockSupported() +{ + if (QtAndroidPrivate::androidSdkVersion() < 14) + return false; + + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return false; + + return m_parameters.callMethod("isAutoExposureLockSupported"); +} + +bool AndroidCameraPrivate::getAutoExposureLock() +{ + if (QtAndroidPrivate::androidSdkVersion() < 14) + return false; + + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return false; + + return m_parameters.callMethod("getAutoExposureLock"); +} + +void AndroidCameraPrivate::setAutoExposureLock(bool toggle) +{ + if (QtAndroidPrivate::androidSdkVersion() < 14) + return; + + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setAutoExposureLock", "(Z)V", toggle); + applyParameters(); +} + +bool AndroidCameraPrivate::isAutoWhiteBalanceLockSupported() +{ + if (QtAndroidPrivate::androidSdkVersion() < 14) + return false; + + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return false; + + return m_parameters.callMethod("isAutoWhiteBalanceLockSupported"); +} + +bool AndroidCameraPrivate::getAutoWhiteBalanceLock() +{ + if (QtAndroidPrivate::androidSdkVersion() < 14) + return false; + + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return false; + + return m_parameters.callMethod("getAutoWhiteBalanceLock"); +} + +void AndroidCameraPrivate::setAutoWhiteBalanceLock(bool toggle) +{ + if (QtAndroidPrivate::androidSdkVersion() < 14) + return; + + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setAutoWhiteBalanceLock", "(Z)V", toggle); + applyParameters(); +} + +int AndroidCameraPrivate::getExposureCompensation() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return 0; + + return m_parameters.callMethod("getExposureCompensation"); +} + +void AndroidCameraPrivate::setExposureCompensation(int value) +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setExposureCompensation", "(I)V", value); + applyParameters(); +} + +float AndroidCameraPrivate::getExposureCompensationStep() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return 0; + + return m_parameters.callMethod("getExposureCompensationStep"); +} + +int AndroidCameraPrivate::getMinExposureCompensation() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return 0; + + return m_parameters.callMethod("getMinExposureCompensation"); +} + +int AndroidCameraPrivate::getMaxExposureCompensation() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return 0; + + return m_parameters.callMethod("getMaxExposureCompensation"); +} + +QString AndroidCameraPrivate::getSceneMode() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + QString value; + + if (m_parameters.isValid()) { + QJNIObjectPrivate sceneMode = m_parameters.callObjectMethod("getSceneMode", + "()Ljava/lang/String;"); + if (sceneMode.isValid()) + value = sceneMode.toString(); + } + + return value; +} + +void AndroidCameraPrivate::setSceneMode(const QString &value) +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setSceneMode", + "(Ljava/lang/String;)V", + QJNIObjectPrivate::fromString(value).object()); + applyParameters(); +} + +QString AndroidCameraPrivate::getWhiteBalance() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + QString value; + + if (m_parameters.isValid()) { + QJNIObjectPrivate wb = m_parameters.callObjectMethod("getWhiteBalance", + "()Ljava/lang/String;"); + if (wb.isValid()) + value = wb.toString(); + } + + return value; +} + +void AndroidCameraPrivate::setWhiteBalance(const QString &value) +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setWhiteBalance", + "(Ljava/lang/String;)V", + QJNIObjectPrivate::fromString(value).object()); + applyParameters(); + + emit whiteBalanceChanged(); +} + +void AndroidCameraPrivate::updateRotation() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + m_parameters.callMethod("setRotation", "(I)V", m_rotation); + applyParameters(); +} + +QList AndroidCameraPrivate::getSupportedPictureSizes() +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + QList list; + + if (m_parameters.isValid()) { + QJNIObjectPrivate sizeList = m_parameters.callObjectMethod("getSupportedPictureSizes", + "()Ljava/util/List;"); + int count = sizeList.callMethod("size"); + for (int i = 0; i < count; ++i) { + QJNIObjectPrivate size = sizeList.callObjectMethod("get", + "(I)Ljava/lang/Object;", + i); + list.append(QSize(size.getField("width"), size.getField("height"))); + } + + qSort(list.begin(), list.end(), qt_sizeLessThan); + } + + return list; +} + +void AndroidCameraPrivate::setPictureSize(const QSize &size) +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setPictureSize", "(II)V", size.width(), size.height()); + applyParameters(); +} + +void AndroidCameraPrivate::setJpegQuality(int quality) +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + if (!m_parameters.isValid()) + return; + + m_parameters.callMethod("setJpegQuality", "(I)V", quality); + applyParameters(); +} + +void AndroidCameraPrivate::startPreview() +{ + //We need to clear preview buffers queue here, but there is no method to do it + //Though just resetting preview callback do the trick + m_camera.callMethod("setPreviewCallbackWithBuffer", + "(Landroid/hardware/Camera$PreviewCallback;)V", + jobject(0)); + m_cameraListener.callMethod("preparePreviewBuffer", "(Landroid/hardware/Camera;)V", m_camera.object()); + QJNIObjectPrivate buffer = m_cameraListener.callObjectMethod("callbackBuffer"); + m_camera.callMethod("addCallbackBuffer", "([B)V", buffer.object()); + m_camera.callMethod("setPreviewCallbackWithBuffer", + "(Landroid/hardware/Camera$PreviewCallback;)V", + m_cameraListener.object()); + m_camera.callMethod("startPreview"); + emit previewStarted(); +} + +void AndroidCameraPrivate::stopPreview() +{ + m_camera.callMethod("stopPreview"); + emit previewStopped(); +} + +void AndroidCameraPrivate::takePicture() +{ + m_camera.callMethod("takePicture", "(Landroid/hardware/Camera$ShutterCallback;" + "Landroid/hardware/Camera$PictureCallback;" + "Landroid/hardware/Camera$PictureCallback;)V", + m_cameraListener.object(), + jobject(0), + m_cameraListener.object()); +} + +void AndroidCameraPrivate::fetchEachFrame(bool fetch) +{ + m_cameraListener.callMethod("fetchEachFrame", "(Z)V", fetch); +} + +void AndroidCameraPrivate::fetchLastPreviewFrame() +{ + QJNIEnvironmentPrivate env; + QJNIObjectPrivate data = m_cameraListener.callObjectMethod("lockAndFetchPreviewBuffer", "()[B"); + if (!data.isValid()) { + m_cameraListener.callMethod("unlockPreviewBuffer"); + return; + } + const int arrayLength = env->GetArrayLength(static_cast(data.object())); + QByteArray bytes(arrayLength, Qt::Uninitialized); + env->GetByteArrayRegion(static_cast(data.object()), + 0, + arrayLength, + reinterpret_cast(bytes.data())); + m_cameraListener.callMethod("unlockPreviewBuffer"); + + emit previewFetched(bytes); +} + +void AndroidCameraPrivate::applyParameters() +{ + m_camera.callMethod("setParameters", + "(Landroid/hardware/Camera$Parameters;)V", + m_parameters.object()); +} + +QStringList AndroidCameraPrivate::callParametersStringListMethod(const QByteArray &methodName) +{ + QMutexLocker parametersLocker(&m_parametersMutex); + + QStringList stringList; + + if (m_parameters.isValid()) { + QJNIObjectPrivate list = m_parameters.callObjectMethod(methodName.constData(), + "()Ljava/util/List;"); + + if (list.isValid()) { + int count = list.callMethod("size"); + for (int i = 0; i < count; ++i) { + QJNIObjectPrivate string = list.callObjectMethod("get", + "(I)Ljava/lang/Object;", + i); + stringList.append(string.toString()); + } + } + } + + return stringList; +} + +static JNINativeMethod methods[] = { + {"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete}, + {"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed}, + {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured}, + {"notifyFrameFetched", "(I[B)V", (void *)notifyFrameFetched} +}; + +bool AndroidCamera::initJNI(JNIEnv *env) +{ + jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtCameraListener"); + if (env->ExceptionCheck()) + env->ExceptionClear(); + + if (clazz) { + g_qtCameraListenerClass = static_cast(env->NewGlobalRef(clazz)); + if (env->RegisterNatives(g_qtCameraListenerClass, + methods, + sizeof(methods) / sizeof(methods[0])) < 0) { + return false; + } + } + + return true; +} + +QT_END_NAMESPACE + +#include "androidcamera.moc" diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.h b/src/plugins/android/src/wrappers/jni/androidcamera.h new file mode 100644 index 000000000..de97f5767 --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidcamera.h @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** 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 ANDROIDCAMERA_H +#define ANDROIDCAMERA_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QThread; + +class AndroidCameraPrivate; + +class AndroidCamera : public QObject +{ + Q_OBJECT + Q_ENUMS(CameraFacing) + Q_ENUMS(ImageFormat) +public: + enum CameraFacing { + CameraFacingBack = 0, + CameraFacingFront = 1 + }; + + enum ImageFormat { // same values as in android.graphics.ImageFormat Java class + Unknown = 0, + RGB565 = 4, + NV16 = 16, + NV21 = 17, + YUY2 = 20, + JPEG = 256, + YV12 = 842094169 + }; + + ~AndroidCamera(); + + static AndroidCamera *open(int cameraId); + + int cameraId() const; + + void lock(); + void unlock(); + void reconnect(); + void release(); + + CameraFacing getFacing(); + int getNativeOrientation(); + + QSize getPreferredPreviewSizeForVideo(); + QList getSupportedPreviewSizes(); + + ImageFormat getPreviewFormat(); + void setPreviewFormat(ImageFormat fmt); + + QSize previewSize() const; + 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); + int getRotation() const; + + QList getSupportedPictureSizes(); + void setPictureSize(const QSize &size); + void setJpegQuality(int quality); + + void startPreview(); + void stopPreview(); + + void takePicture(); + + void fetchEachFrame(bool fetch); + void fetchLastPreviewFrame(); + QJNIObjectPrivate getCameraObject(); + + static bool initJNI(JNIEnv *env); + +Q_SIGNALS: + void previewSizeChanged(); + void previewStarted(); + void previewStopped(); + + void autoFocusStarted(); + void autoFocusComplete(bool success); + + void whiteBalanceChanged(); + + void pictureExposed(); + void pictureCaptured(const QByteArray &data); + void previewFetched(const QByteArray &preview); + void frameFetched(const QByteArray &frame); + +private: + AndroidCamera(AndroidCameraPrivate *d, QThread *worker); + + Q_DECLARE_PRIVATE(AndroidCamera) + AndroidCameraPrivate *d_ptr; + QScopedPointer m_worker; +}; + +QT_END_NAMESPACE + +#endif // ANDROIDCAMERA_H diff --git a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.cpp new file mode 100644 index 000000000..7dfc6a6e3 --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.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 "androidmediametadataretriever.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +AndroidMediaMetadataRetriever::AndroidMediaMetadataRetriever() +{ + m_metadataRetriever = QJNIObjectPrivate("android/media/MediaMetadataRetriever"); +} + +AndroidMediaMetadataRetriever::~AndroidMediaMetadataRetriever() +{ +} + +QString AndroidMediaMetadataRetriever::extractMetadata(MetadataKey key) +{ + QString value; + + QJNIObjectPrivate metadata = m_metadataRetriever.callObjectMethod("extractMetadata", + "(I)Ljava/lang/String;", + jint(key)); + if (metadata.isValid()) + value = metadata.toString(); + + return value; +} + +void AndroidMediaMetadataRetriever::release() +{ + if (!m_metadataRetriever.isValid()) + return; + + m_metadataRetriever.callMethod("release"); +} + +bool AndroidMediaMetadataRetriever::setDataSource(const QUrl &url) +{ + if (!m_metadataRetriever.isValid()) + return false; + + QJNIEnvironmentPrivate env; + + bool loaded = false; + + QJNIObjectPrivate string = QJNIObjectPrivate::fromString(url.toString()); + + QJNIObjectPrivate uri = m_metadataRetriever.callStaticObjectMethod("android/net/Uri", + "parse", + "(Ljava/lang/String;)Landroid/net/Uri;", + string.object()); + if (env->ExceptionCheck()) { + env->ExceptionClear(); + } else { + m_metadataRetriever.callMethod("setDataSource", + "(Landroid/content/Context;Landroid/net/Uri;)V", + QtAndroidPrivate::activity(), + uri.object()); + if (env->ExceptionCheck()) + env->ExceptionClear(); + else + loaded = true; + } + + return loaded; +} + +bool AndroidMediaMetadataRetriever::setDataSource(const QString &path) +{ + if (!m_metadataRetriever.isValid()) + return false; + + QJNIEnvironmentPrivate env; + + bool loaded = false; + + m_metadataRetriever.callMethod("setDataSource", + "(Ljava/lang/String;)V", + QJNIObjectPrivate::fromString(path).object()); + if (env->ExceptionCheck()) + env->ExceptionClear(); + else + loaded = true; + + return loaded; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h new file mode 100644 index 000000000..f18cec11d --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidmediametadataretriever.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** 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 ANDROIDMEDIAMETADATARETRIEVER_H +#define ANDROIDMEDIAMETADATARETRIEVER_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class AndroidMediaMetadataRetriever +{ +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 + }; + + AndroidMediaMetadataRetriever(); + ~AndroidMediaMetadataRetriever(); + + QString extractMetadata(MetadataKey key); + void release(); + bool setDataSource(const QUrl &url); + bool setDataSource(const QString &path); + +private: + QJNIObjectPrivate m_metadataRetriever; +}; + +QT_END_NAMESPACE + +#endif // ANDROIDMEDIAMETADATARETRIEVER_H diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp new file mode 100644 index 000000000..9c9f685cb --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** 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 "androidmediaplayer.h" + +#include +#include +#include +#include + +static jclass mediaPlayerClass = Q_NULLPTR; +typedef QMap MediaPlayerMap; +Q_GLOBAL_STATIC(MediaPlayerMap, mediaPlayers) + +QT_BEGIN_NAMESPACE + +AndroidMediaPlayer::AndroidMediaPlayer() + : QObject() +{ + + const jlong id = reinterpret_cast(this); + mMediaPlayer = QJNIObjectPrivate(mediaPlayerClass, + "(Landroid/app/Activity;J)V", + QtAndroidPrivate::activity(), + id); + (*mediaPlayers)[id] = this; +} + +AndroidMediaPlayer::~AndroidMediaPlayer() +{ + mediaPlayers->remove(reinterpret_cast(this)); +} + +void AndroidMediaPlayer::release() +{ + mMediaPlayer.callMethod("release"); +} + +void AndroidMediaPlayer::reset() +{ + mMediaPlayer.callMethod("reset"); +} + +int AndroidMediaPlayer::getCurrentPosition() +{ + return mMediaPlayer.callMethod("getCurrentPosition"); +} + +int AndroidMediaPlayer::getDuration() +{ + return mMediaPlayer.callMethod("getDuration"); +} + +bool AndroidMediaPlayer::isPlaying() +{ + return mMediaPlayer.callMethod("isPlaying"); +} + +int AndroidMediaPlayer::volume() +{ + return mMediaPlayer.callMethod("getVolume"); +} + +bool AndroidMediaPlayer::isMuted() +{ + return mMediaPlayer.callMethod("isMuted"); +} + +jobject AndroidMediaPlayer::display() +{ + return mMediaPlayer.callObjectMethod("display", "()Landroid/view/SurfaceHolder;").object(); +} + +void AndroidMediaPlayer::play() +{ + mMediaPlayer.callMethod("start"); +} + +void AndroidMediaPlayer::pause() +{ + mMediaPlayer.callMethod("pause"); +} + +void AndroidMediaPlayer::stop() +{ + mMediaPlayer.callMethod("stop"); +} + +void AndroidMediaPlayer::seekTo(qint32 msec) +{ + mMediaPlayer.callMethod("seekTo", "(I)V", jint(msec)); +} + +void AndroidMediaPlayer::setMuted(bool mute) +{ + mMediaPlayer.callMethod("mute", "(Z)V", jboolean(mute)); +} + +void AndroidMediaPlayer::setDataSource(const QString &path) +{ + QJNIObjectPrivate string = QJNIObjectPrivate::fromString(path); + mMediaPlayer.callMethod("setDataSource", "(Ljava/lang/String;)V", string.object()); +} + +void AndroidMediaPlayer::prepareAsync() +{ + mMediaPlayer.callMethod("prepareAsync"); +} + +void AndroidMediaPlayer::setVolume(int volume) +{ + mMediaPlayer.callMethod("setVolume", "(I)V", jint(volume)); +} + +void AndroidMediaPlayer::setDisplay(jobject surfaceHolder) +{ + mMediaPlayer.callMethod("setDisplay", "(Landroid/view/SurfaceHolder;)V", surfaceHolder); +} + +static void onErrorNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + AndroidMediaPlayer *const mp = (*mediaPlayers)[id]; + if (!mp) + return; + + Q_EMIT mp->error(what, extra); +} + +static void onBufferingUpdateNative(JNIEnv *env, jobject thiz, jint percent, jlong id) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + AndroidMediaPlayer *const mp = (*mediaPlayers)[id]; + if (!mp) + return; + + Q_EMIT mp->bufferingChanged(percent); +} + +static void onProgressUpdateNative(JNIEnv *env, jobject thiz, jint progress, jlong id) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + AndroidMediaPlayer *const mp = (*mediaPlayers)[id]; + if (!mp) + return; + + Q_EMIT mp->progressChanged(progress); +} + +static void onDurationChangedNative(JNIEnv *env, jobject thiz, jint duration, jlong id) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + AndroidMediaPlayer *const mp = (*mediaPlayers)[id]; + if (!mp) + return; + + Q_EMIT mp->durationChanged(duration); +} + +static void onInfoNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + AndroidMediaPlayer *const mp = (*mediaPlayers)[id]; + if (!mp) + return; + + Q_EMIT mp->info(what, extra); +} + +static void onStateChangedNative(JNIEnv *env, jobject thiz, jint state, jlong id) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + AndroidMediaPlayer *const mp = (*mediaPlayers)[id]; + if (!mp) + return; + + Q_EMIT mp->stateChanged(state); +} + +static void onVideoSizeChangedNative(JNIEnv *env, + jobject thiz, + jint width, + jint height, + jlong id) +{ + Q_UNUSED(env); + Q_UNUSED(thiz); + AndroidMediaPlayer *const mp = (*mediaPlayers)[id]; + if (!mp) + return; + + Q_EMIT mp->videoSizeChanged(width, height); +} + +bool AndroidMediaPlayer::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)}, + {"onProgressUpdateNative", "(IJ)V", reinterpret_cast(onProgressUpdateNative)}, + {"onDurationChangedNative", "(IJ)V", reinterpret_cast(onDurationChangedNative)}, + {"onInfoNative", "(IIJ)V", reinterpret_cast(onInfoNative)}, + {"onVideoSizeChangedNative", "(IIJ)V", reinterpret_cast(onVideoSizeChangedNative)}, + {"onStateChangedNative", "(IJ)V", reinterpret_cast(onStateChangedNative)} + }; + + 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/jni/androidmediaplayer.h b/src/plugins/android/src/wrappers/jni/androidmediaplayer.h new file mode 100644 index 000000000..b2cab805e --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidmediaplayer.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 ANDROIDMEDIAPLAYER_H +#define ANDROIDMEDIAPLAYER_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class AndroidMediaPlayer : public QObject +{ + Q_OBJECT +public: + AndroidMediaPlayer(); + ~AndroidMediaPlayer(); + + enum MediaError + { + // What + MEDIA_ERROR_UNKNOWN = 1, + MEDIA_ERROR_SERVER_DIED = 100, + MEDIA_ERROR_INVALID_STATE = -38, // Undocumented + // 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, + MEDIA_ERROR_BAD_THINGS_ARE_GOING_TO_HAPPEN = -2147483648 // Undocumented + }; + + 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 MediaPlayerState + { + Uninitialized = 0x1, /* End */ + Idle = 0x2, + Preparing = 0x4, + Prepared = 0x8, + Initialized = 0x10, + Started = 0x20, + Stopped = 0x40, + Paused = 0x80, + PlaybackCompleted = 0x100, + Error = 0x200 + }; + + void release(); + void reset(); + + int getCurrentPosition(); + int getDuration(); + bool isPlaying(); + int volume(); + bool isMuted(); + jobject display(); + + void play(); + void pause(); + void stop(); + void seekTo(qint32 msec); + void setMuted(bool mute); + void setDataSource(const QString &path); + void prepareAsync(); + void setVolume(int volume); + void setDisplay(jobject surfaceHolder); + + static bool initJNI(JNIEnv *env); + +Q_SIGNALS: + void error(qint32 what, qint32 extra); + void bufferingChanged(qint32 percent); + void durationChanged(qint64 duration); + void progressChanged(qint64 progress); + void stateChanged(qint32 state); + void info(qint32 what, qint32 extra); + void videoSizeChanged(qint32 width, qint32 height); + +private: + QJNIObjectPrivate mMediaPlayer; +}; + +QT_END_NAMESPACE + +#endif // ANDROIDMEDIAPLAYER_H diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp new file mode 100644 index 000000000..3683c9aa5 --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp @@ -0,0 +1,299 @@ +/**************************************************************************** +** +** 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 "androidmediarecorder.h" + +#include "androidcamera.h" +#include +#include + +QT_BEGIN_NAMESPACE + +static jclass g_qtMediaRecorderListenerClass = 0; +typedef QMap MediaRecorderMap; +Q_GLOBAL_STATIC(MediaRecorderMap, mediaRecorders) + +static void notifyError(JNIEnv* , jobject, jlong id, jint what, jint extra) +{ + AndroidMediaRecorder *obj = mediaRecorders->value(id, 0); + if (obj) + emit obj->error(what, extra); +} + +static void notifyInfo(JNIEnv* , jobject, jlong id, jint what, jint extra) +{ + AndroidMediaRecorder *obj = mediaRecorders->value(id, 0); + if (obj) + emit obj->info(what, extra); +} + +AndroidMediaRecorder::AndroidMediaRecorder() + : QObject() + , m_id(reinterpret_cast(this)) +{ + m_mediaRecorder = QJNIObjectPrivate("android/media/MediaRecorder"); + if (m_mediaRecorder.isValid()) { + QJNIObjectPrivate listener(g_qtMediaRecorderListenerClass, "(J)V", m_id); + m_mediaRecorder.callMethod("setOnErrorListener", + "(Landroid/media/MediaRecorder$OnErrorListener;)V", + listener.object()); + m_mediaRecorder.callMethod("setOnInfoListener", + "(Landroid/media/MediaRecorder$OnInfoListener;)V", + listener.object()); + mediaRecorders->insert(m_id, this); + } +} + +AndroidMediaRecorder::~AndroidMediaRecorder() +{ + mediaRecorders->remove(m_id); +} + +void AndroidMediaRecorder::release() +{ + m_mediaRecorder.callMethod("release"); +} + +bool AndroidMediaRecorder::prepare() +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("prepare"); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + return false; + } + return true; +} + +void AndroidMediaRecorder::reset() +{ + m_mediaRecorder.callMethod("reset"); +} + +bool AndroidMediaRecorder::start() +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("start"); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + return false; + } + return true; +} + +void AndroidMediaRecorder::stop() +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("stop"); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +void AndroidMediaRecorder::setAudioChannels(int numChannels) +{ + m_mediaRecorder.callMethod("setAudioChannels", "(I)V", numChannels); +} + +void AndroidMediaRecorder::setAudioEncoder(AudioEncoder encoder) +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("setAudioEncoder", "(I)V", int(encoder)); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +void AndroidMediaRecorder::setAudioEncodingBitRate(int bitRate) +{ + m_mediaRecorder.callMethod("setAudioEncodingBitRate", "(I)V", bitRate); +} + +void AndroidMediaRecorder::setAudioSamplingRate(int samplingRate) +{ + m_mediaRecorder.callMethod("setAudioSamplingRate", "(I)V", samplingRate); +} + +void AndroidMediaRecorder::setAudioSource(AudioSource source) +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("setAudioSource", "(I)V", int(source)); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +void AndroidMediaRecorder::setCamera(AndroidCamera *camera) +{ + QJNIObjectPrivate cam = camera->getCameraObject(); + m_mediaRecorder.callMethod("setCamera", "(Landroid/hardware/Camera;)V", cam.object()); +} + +void AndroidMediaRecorder::setVideoEncoder(VideoEncoder encoder) +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("setVideoEncoder", "(I)V", int(encoder)); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +void AndroidMediaRecorder::setVideoEncodingBitRate(int bitRate) +{ + m_mediaRecorder.callMethod("setVideoEncodingBitRate", "(I)V", bitRate); +} + +void AndroidMediaRecorder::setVideoFrameRate(int rate) +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("setVideoFrameRate", "(I)V", rate); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +void AndroidMediaRecorder::setVideoSize(const QSize &size) +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("setVideoSize", "(II)V", size.width(), size.height()); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +void AndroidMediaRecorder::setVideoSource(VideoSource source) +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("setVideoSource", "(I)V", int(source)); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +void AndroidMediaRecorder::setOrientationHint(int degrees) +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("setOrientationHint", "(I)V", degrees); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +void AndroidMediaRecorder::setOutputFormat(OutputFormat format) +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("setOutputFormat", "(I)V", int(format)); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +void AndroidMediaRecorder::setOutputFile(const QString &path) +{ + QJNIEnvironmentPrivate env; + m_mediaRecorder.callMethod("setOutputFile", + "(Ljava/lang/String;)V", + QJNIObjectPrivate::fromString(path).object()); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif + env->ExceptionClear(); + } +} + +static JNINativeMethod methods[] = { + {"notifyError", "(JII)V", (void *)notifyError}, + {"notifyInfo", "(JII)V", (void *)notifyInfo} +}; + +bool AndroidMediaRecorder::initJNI(JNIEnv *env) +{ + jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtMediaRecorderListener"); + if (env->ExceptionCheck()) + env->ExceptionClear(); + + if (clazz) { + g_qtMediaRecorderListenerClass = static_cast(env->NewGlobalRef(clazz)); + if (env->RegisterNatives(g_qtMediaRecorderListenerClass, + methods, + sizeof(methods) / sizeof(methods[0])) < 0) { + return false; + } + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h new file mode 100644 index 000000000..1ab1b9026 --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.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 ANDROIDMEDIARECORDER_H +#define ANDROIDMEDIARECORDER_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class AndroidCamera; + +class AndroidMediaRecorder : public QObject +{ + 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 + }; + + AndroidMediaRecorder(); + ~AndroidMediaRecorder(); + + 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(AndroidCamera *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; + QJNIObjectPrivate m_mediaRecorder; +}; + +QT_END_NAMESPACE + +#endif // ANDROIDMEDIARECORDER_H diff --git a/src/plugins/android/src/wrappers/jni/androidmultimediautils.cpp b/src/plugins/android/src/wrappers/jni/androidmultimediautils.cpp new file mode 100644 index 000000000..5c2f19a06 --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidmultimediautils.cpp @@ -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$ +** +****************************************************************************/ + +#include "androidmultimediautils.h" + +#include + +QT_BEGIN_NAMESPACE + + +void AndroidMultimediaUtils::enableOrientationListener(bool enable) +{ + QJNIObjectPrivate::callStaticMethod("org/qtproject/qt5/android/multimedia/QtMultimediaUtils", + "enableOrientationListener", + "(Z)V", + enable); +} + +int AndroidMultimediaUtils::getDeviceOrientation() +{ + return QJNIObjectPrivate::callStaticMethod("org/qtproject/qt5/android/multimedia/QtMultimediaUtils", + "getDeviceOrientation"); +} + +QString AndroidMultimediaUtils::getDefaultMediaDirectory(MediaType type) +{ + QJNIObjectPrivate path = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt5/android/multimedia/QtMultimediaUtils", + "getDefaultMediaDirectory", + "(I)Ljava/lang/String;", + jint(type)); + return path.toString(); +} + +void AndroidMultimediaUtils::registerMediaFile(const QString &file) +{ + QJNIObjectPrivate::callStaticMethod("org/qtproject/qt5/android/multimedia/QtMultimediaUtils", + "registerMediaFile", + "(Ljava/lang/String;)V", + QJNIObjectPrivate::fromString(file).object()); +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidmultimediautils.h b/src/plugins/android/src/wrappers/jni/androidmultimediautils.h new file mode 100644 index 000000000..4617b08f8 --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidmultimediautils.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 ANDROIDMULTIMEDIAUTILS_H +#define ANDROIDMULTIMEDIAUTILS_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class AndroidMultimediaUtils +{ +public: + enum MediaType { + Music = 0, + Movies = 1, + DCIM = 2, + Sounds = 3 + }; + + static void enableOrientationListener(bool enable); + static int getDeviceOrientation(); + static QString getDefaultMediaDirectory(MediaType type); + static void registerMediaFile(const QString &file); +}; + +QT_END_NAMESPACE + +#endif // ANDROIDMULTIMEDIAUTILS_H diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp new file mode 100644 index 000000000..8c334a060 --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp @@ -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$ +** +****************************************************************************/ + +#include "androidsurfacetexture.h" +#include +#include + +QT_BEGIN_NAMESPACE + +static jclass g_qtSurfaceTextureListenerClass = 0; +static QMap g_objectMap; + +// native method for QtSurfaceTexture.java +static void notifyFrameAvailable(JNIEnv* , jobject, int id) +{ + AndroidSurfaceTexture *obj = g_objectMap.value(id, 0); + if (obj) + Q_EMIT obj->frameAvailable(); +} + +AndroidSurfaceTexture::AndroidSurfaceTexture(unsigned int texName) + : QObject() + , m_texID(int(texName)) +{ + // API level 11 or higher is required + if (QtAndroidPrivate::androidSdkVersion() < 11) { + qWarning("Camera preview and video playback require Android 3.0 (API level 11) or later."); + return; + } + + QJNIEnvironmentPrivate env; + m_surfaceTexture = QJNIObjectPrivate("android/graphics/SurfaceTexture", "(I)V", jint(texName)); + if (env->ExceptionCheck()) { +#ifdef QT_DEBUG + env->ExceptionDescribe(); +#endif // QT_DEBUG + env->ExceptionClear(); + } + + if (m_surfaceTexture.isValid()) + g_objectMap.insert(int(texName), this); + + QJNIObjectPrivate listener(g_qtSurfaceTextureListenerClass, "(I)V", jint(texName)); + m_surfaceTexture.callMethod("setOnFrameAvailableListener", + "(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V", + listener.object()); +} + +AndroidSurfaceTexture::~AndroidSurfaceTexture() +{ + if (m_surfaceTexture.isValid()) { + release(); + g_objectMap.remove(m_texID); + } +} + +QMatrix4x4 AndroidSurfaceTexture::getTransformMatrix() +{ + QMatrix4x4 matrix; + if (!m_surfaceTexture.isValid()) + return matrix; + + QJNIEnvironmentPrivate env; + + jfloatArray array = env->NewFloatArray(16); + m_surfaceTexture.callMethod("getTransformMatrix", "([F)V", array); + env->GetFloatArrayRegion(array, 0, 16, matrix.data()); + env->DeleteLocalRef(array); + + return matrix; +} + +void AndroidSurfaceTexture::release() +{ + if (QtAndroidPrivate::androidSdkVersion() < 14) + return; + + m_surfaceTexture.callMethod("release"); +} + +void AndroidSurfaceTexture::updateTexImage() +{ + if (!m_surfaceTexture.isValid()) + return; + + m_surfaceTexture.callMethod("updateTexImage"); +} + +jobject AndroidSurfaceTexture::object() +{ + return m_surfaceTexture.object(); +} + +static JNINativeMethod methods[] = { + {"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable} +}; + +bool AndroidSurfaceTexture::initJNI(JNIEnv *env) +{ + // SurfaceTexture is available since API 11. + if (QtAndroidPrivate::androidSdkVersion() < 11) + return false; + + jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener"); + if (env->ExceptionCheck()) + env->ExceptionClear(); + + if (clazz) { + g_qtSurfaceTextureListenerClass = static_cast(env->NewGlobalRef(clazz)); + if (env->RegisterNatives(g_qtSurfaceTextureListenerClass, + methods, + sizeof(methods) / sizeof(methods[0])) < 0) { + return false; + } + } + + return true; +} + +QT_END_NAMESPACE diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h new file mode 100644 index 000000000..5898096fc --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** 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 ANDROIDSURFACETEXTURE_H +#define ANDROIDSURFACETEXTURE_H + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class AndroidSurfaceTexture : public QObject +{ + Q_OBJECT +public: + explicit AndroidSurfaceTexture(unsigned int texName); + ~AndroidSurfaceTexture(); + + int textureID() const { return m_texID; } + jobject object(); + + QMatrix4x4 getTransformMatrix(); + void release(); // API level 14 + void updateTexImage(); + + static bool initJNI(JNIEnv *env); + +Q_SIGNALS: + void frameAvailable(); + +private: + int m_texID; + QJNIObjectPrivate m_surfaceTexture; +}; + +QT_END_NAMESPACE + +#endif // ANDROIDSURFACETEXTURE_H diff --git a/src/plugins/android/src/wrappers/jni/jni.pri b/src/plugins/android/src/wrappers/jni/jni.pri new file mode 100644 index 000000000..ba2ad0801 --- /dev/null +++ b/src/plugins/android/src/wrappers/jni/jni.pri @@ -0,0 +1,19 @@ +QT += platformsupport-private + +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/androidmediaplayer.h \ + $$PWD/androidsurfacetexture.h \ + $$PWD/androidmediametadataretriever.h \ + $$PWD/androidcamera.h \ + $$PWD/androidmultimediautils.h \ + $$PWD/androidmediarecorder.h + +SOURCES += \ + $$PWD/androidmediaplayer.cpp \ + $$PWD/androidsurfacetexture.cpp \ + $$PWD/androidmediametadataretriever.cpp \ + $$PWD/androidcamera.cpp \ + $$PWD/androidmultimediautils.cpp \ + $$PWD/androidmediarecorder.cpp diff --git a/src/plugins/android/src/wrappers/jsurfacetexture.cpp b/src/plugins/android/src/wrappers/jsurfacetexture.cpp deleted file mode 100644 index 2b16ebd66..000000000 --- a/src/plugins/android/src/wrappers/jsurfacetexture.cpp +++ /dev/null @@ -1,158 +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 -#include - -QT_BEGIN_NAMESPACE - -static jclass g_qtSurfaceTextureListenerClass = 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() - , m_texID(int(texName)) -{ - // API level 11 or higher is required - if (QtAndroidPrivate::androidSdkVersion() < 11) { - qWarning("Camera preview and video playback require Android 3.0 (API level 11) or later."); - return; - } - - QJNIEnvironmentPrivate env; - m_surfaceTexture = QJNIObjectPrivate("android/graphics/SurfaceTexture", "(I)V", jint(texName)); - if (env->ExceptionCheck()) { -#ifdef QT_DEBUG - env->ExceptionDescribe(); -#endif // QT_DEBUG - env->ExceptionClear(); - } - - if (m_surfaceTexture.isValid()) - g_objectMap.insert(int(texName), this); - - QJNIObjectPrivate listener(g_qtSurfaceTextureListenerClass, "(I)V", jint(texName)); - m_surfaceTexture.callMethod("setOnFrameAvailableListener", - "(Landroid/graphics/SurfaceTexture$OnFrameAvailableListener;)V", - listener.object()); -} - -JSurfaceTexture::~JSurfaceTexture() -{ - if (m_surfaceTexture.isValid()) { - release(); - g_objectMap.remove(m_texID); - } -} - -QMatrix4x4 JSurfaceTexture::getTransformMatrix() -{ - QMatrix4x4 matrix; - if (!m_surfaceTexture.isValid()) - return matrix; - - QJNIEnvironmentPrivate env; - - jfloatArray array = env->NewFloatArray(16); - m_surfaceTexture.callMethod("getTransformMatrix", "([F)V", array); - env->GetFloatArrayRegion(array, 0, 16, matrix.data()); - env->DeleteLocalRef(array); - - return matrix; -} - -void JSurfaceTexture::release() -{ - if (QtAndroidPrivate::androidSdkVersion() < 14) - return; - - m_surfaceTexture.callMethod("release"); -} - -void JSurfaceTexture::updateTexImage() -{ - if (!m_surfaceTexture.isValid()) - return; - - m_surfaceTexture.callMethod("updateTexImage"); -} - -jobject JSurfaceTexture::object() -{ - return m_surfaceTexture.object(); -} - -static JNINativeMethod methods[] = { - {"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable} -}; - -bool JSurfaceTexture::initJNI(JNIEnv *env) -{ - // SurfaceTexture is available since API 11. - if (QtAndroidPrivate::androidSdkVersion() < 11) - return false; - - jclass clazz = env->FindClass("org/qtproject/qt5/android/multimedia/QtSurfaceTextureListener"); - if (env->ExceptionCheck()) - env->ExceptionClear(); - - if (clazz) { - g_qtSurfaceTextureListenerClass = static_cast(env->NewGlobalRef(clazz)); - if (env->RegisterNatives(g_qtSurfaceTextureListenerClass, - 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 deleted file mode 100644 index d53290a71..000000000 --- a/src/plugins/android/src/wrappers/jsurfacetexture.h +++ /dev/null @@ -1,78 +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 -{ - Q_OBJECT -public: - explicit JSurfaceTexture(unsigned int texName); - ~JSurfaceTexture(); - - int textureID() const { return m_texID; } - jobject object(); - - QMatrix4x4 getTransformMatrix(); - void release(); // API level 14 - void updateTexImage(); - - static bool initJNI(JNIEnv *env); - -Q_SIGNALS: - void frameAvailable(); - -private: - int m_texID; - QJNIObjectPrivate m_surfaceTexture; -}; - -QT_END_NAMESPACE - -#endif // JSURFACETEXTURE_H diff --git a/src/plugins/android/src/wrappers/wrappers.pri b/src/plugins/android/src/wrappers/wrappers.pri deleted file mode 100644 index 126cfd0c1..000000000 --- a/src/plugins/android/src/wrappers/wrappers.pri +++ /dev/null @@ -1,19 +0,0 @@ -QT += platformsupport-private - -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/jmediaplayer.h \ - $$PWD/jsurfacetexture.h \ - $$PWD/jmediametadataretriever.h \ - $$PWD/jcamera.h \ - $$PWD/jmultimediautils.h \ - $$PWD/jmediarecorder.h - -SOURCES += \ - $$PWD/jmediaplayer.cpp \ - $$PWD/jsurfacetexture.cpp \ - $$PWD/jmediametadataretriever.cpp \ - $$PWD/jcamera.cpp \ - $$PWD/jmultimediautils.cpp \ - $$PWD/jmediarecorder.cpp -- cgit v1.2.3 From 1ef3ef6a30e6cb38e332da6cc62aea18248e9eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Thu, 15 May 2014 13:57:34 +0200 Subject: Make it possible to build multimedia for embedded Android Change-Id: I3400b18379242ea4d1b4f94f5da6b60c64d551e4 Reviewed-by: Yoann Lopes --- qtmultimedia.pro | 2 +- src/plugins/android/android.pro | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qtmultimedia.pro b/qtmultimedia.pro index 1deaab2aa..c7f093ccc 100644 --- a/qtmultimedia.pro +++ b/qtmultimedia.pro @@ -12,7 +12,7 @@ win32 { qtCompileTest(evr) } else:mac { qtCompileTest(avfoundation) -} else:android { +} else:android:!android-no-sdk { SDK_ROOT = $$(ANDROID_SDK_ROOT) isEmpty(SDK_ROOT): SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT !exists($$SDK_ROOT/platforms/android-11/android.jar): error("QtMultimedia for Android requires API level 11") diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro index 807f8ece8..fa322942b 100644 --- a/src/plugins/android/android.pro +++ b/src/plugins/android/android.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs -SUBDIRS += src \ - jar +SUBDIRS += src +android:!android-no-sdk: SUBDIRS += jar qtHaveModule(quick) { SUBDIRS += videonode -- cgit v1.2.3 From b9b06defc76ae8c3bc6073cb81b4e31b94917a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Mon, 12 May 2014 14:38:09 +0200 Subject: Android: Don't expose java calls in the control classes. Makes the abstraction more clear. Change-Id: Ia9a7b0b157e1182158cd26b62775d13f6c5e1727 Reviewed-by: Yoann Lopes --- .../android/src/common/qandroidvideooutput.h | 6 +- .../src/common/qandroidvideorendercontrol.cpp | 36 +---------- .../src/common/qandroidvideorendercontrol.h | 5 +- .../src/mediacapture/qandroidcamerasession.cpp | 30 +-------- .../src/mediacapture/qandroidcamerasession.h | 10 +-- .../src/mediacapture/qandroidcapturesession.cpp | 39 +++++------- .../src/mediaplayer/qandroidmediaplayercontrol.cpp | 10 +-- .../android/src/wrappers/jni/androidcamera.cpp | 46 +++++++++++++- .../android/src/wrappers/jni/androidcamera.h | 15 ++++- .../src/wrappers/jni/androidmediaplayer.cpp | 7 +- .../android/src/wrappers/jni/androidmediaplayer.h | 4 +- .../src/wrappers/jni/androidmediarecorder.cpp | 74 ++++++++++++++++++++++ .../src/wrappers/jni/androidmediarecorder.h | 38 +++++++++++ .../src/wrappers/jni/androidsurfacetexture.cpp | 25 +++++++- .../src/wrappers/jni/androidsurfacetexture.h | 7 +- 15 files changed, 238 insertions(+), 114 deletions(-) diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h index 8bf6be6cb..e0335ec93 100644 --- a/src/plugins/android/src/common/qandroidvideooutput.h +++ b/src/plugins/android/src/common/qandroidvideooutput.h @@ -44,17 +44,17 @@ #include #include -#include QT_BEGIN_NAMESPACE +class AndroidSurfaceTexture; + class QAndroidVideoOutput { public: virtual ~QAndroidVideoOutput() { } - virtual jobject surfaceHolder() = 0; - virtual jobject surfaceTexture() { return 0; } + virtual AndroidSurfaceTexture *surfaceTexture() { return 0; } virtual bool isReady() { return true; } diff --git a/src/plugins/android/src/common/qandroidvideorendercontrol.cpp b/src/plugins/android/src/common/qandroidvideorendercontrol.cpp index dfeea33c1..5532661db 100644 --- a/src/plugins/android/src/common/qandroidvideorendercontrol.cpp +++ b/src/plugins/android/src/common/qandroidvideorendercontrol.cpp @@ -109,9 +109,7 @@ private: QAndroidVideoRendererControl::QAndroidVideoRendererControl(QObject *parent) : QVideoRendererControl(parent) , m_surface(0) - , m_androidSurface(0) , m_surfaceTexture(0) - , m_surfaceHolder(0) , m_externalTex(0) , m_fbo(0) , m_program(0) @@ -176,7 +174,7 @@ bool QAndroidVideoRendererControl::initSurfaceTexture() m_surfaceTexture = new AndroidSurfaceTexture(m_externalTex); - if (m_surfaceTexture->object()) { + if (m_surfaceTexture->surfaceTexture() != 0) { connect(m_surfaceTexture, SIGNAL(frameAvailable()), this, SLOT(onFrameAvailable())); } else { delete m_surfaceTexture; @@ -195,42 +193,14 @@ void QAndroidVideoRendererControl::clearSurfaceTexture() delete m_surfaceTexture; m_surfaceTexture = 0; } - if (m_androidSurface) { - if (QtAndroidPrivate::androidSdkVersion() > 13) - m_androidSurface->callMethod("release"); - delete m_androidSurface; - m_androidSurface = 0; - } - if (m_surfaceHolder) { - delete m_surfaceHolder; - m_surfaceHolder = 0; - } -} - -jobject QAndroidVideoRendererControl::surfaceHolder() -{ - if (!initSurfaceTexture()) - return 0; - - if (!m_surfaceHolder) { - m_androidSurface = new QJNIObjectPrivate("android/view/Surface", - "(Landroid/graphics/SurfaceTexture;)V", - m_surfaceTexture->object()); - - m_surfaceHolder = new QJNIObjectPrivate("org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder", - "(Landroid/view/Surface;)V", - m_androidSurface->object()); - } - - return m_surfaceHolder->object(); } -jobject QAndroidVideoRendererControl::surfaceTexture() +AndroidSurfaceTexture *QAndroidVideoRendererControl::surfaceTexture() { if (!initSurfaceTexture()) return 0; - return m_surfaceTexture->object(); + return m_surfaceTexture; } void QAndroidVideoRendererControl::setVideoSize(const QSize &size) diff --git a/src/plugins/android/src/common/qandroidvideorendercontrol.h b/src/plugins/android/src/common/qandroidvideorendercontrol.h index 83d57a437..6e70238c2 100644 --- a/src/plugins/android/src/common/qandroidvideorendercontrol.h +++ b/src/plugins/android/src/common/qandroidvideorendercontrol.h @@ -86,8 +86,7 @@ public: QAbstractVideoSurface *surface() const Q_DECL_OVERRIDE; void setSurface(QAbstractVideoSurface *surface) Q_DECL_OVERRIDE; - jobject surfaceHolder() Q_DECL_OVERRIDE; - jobject surfaceTexture() Q_DECL_OVERRIDE; + AndroidSurfaceTexture *surfaceTexture() Q_DECL_OVERRIDE; bool isReady() Q_DECL_OVERRIDE; void setVideoSize(const QSize &size) Q_DECL_OVERRIDE; void stop() Q_DECL_OVERRIDE; @@ -112,9 +111,7 @@ private: QAbstractVideoSurface *m_surface; QSize m_nativeSize; - QJNIObjectPrivate *m_androidSurface; AndroidSurfaceTexture *m_surfaceTexture; - QJNIObjectPrivate *m_surfaceHolder; quint32 m_externalTex; QOpenGLFramebufferObject *m_fbo; diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index f8633147d..a2eba13f3 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -183,36 +183,10 @@ void QAndroidCameraSession::updateAvailableCameras() { g_availableCameras->clear(); - const QJNIObjectPrivate cameraInfo("android/hardware/Camera$CameraInfo"); - const int numCameras = QJNIObjectPrivate::callStaticMethod("android/hardware/Camera", - "getNumberOfCameras"); - + const int numCameras = AndroidCamera::getNumberOfCameras(); for (int i = 0; i < numCameras; ++i) { AndroidCameraInfo info; - - QJNIObjectPrivate::callStaticMethod("android/hardware/Camera", - "getCameraInfo", - "(ILandroid/hardware/Camera$CameraInfo;)V", - i, cameraInfo.object()); - - AndroidCamera::CameraFacing facing = AndroidCamera::CameraFacing(cameraInfo.getField("facing")); - // The orientation provided by Android is counter-clockwise, we need it clockwise - info.orientation = (360 - cameraInfo.getField("orientation")) % 360; - - switch (facing) { - case AndroidCamera::CameraFacingBack: - info.name = QByteArray("back"); - info.description = QStringLiteral("Rear-facing camera"); - info.position = QCamera::BackFace; - break; - case AndroidCamera::CameraFacingFront: - info.name = QByteArray("front"); - info.description = QStringLiteral("Front-facing camera"); - info.position = QCamera::FrontFace; - break; - default: - break; - } + AndroidCamera::getCameraInfo(i, &info); if (!info.name.isNull()) g_availableCameras->append(info); diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h index 51aba4a9b..05765aa82 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.h +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.h @@ -48,21 +48,13 @@ #include #include #include +#include "androidcamera.h" QT_BEGIN_NAMESPACE -class AndroidCamera; class QAndroidVideoOutput; class QAndroidMediaVideoProbeControl; -struct AndroidCameraInfo -{ - QByteArray name; - QString description; - QCamera::Position position; - int orientation; -}; - class QAndroidCameraSession : public QObject { Q_OBJECT diff --git a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp index f8641073e..383af812a 100644 --- a/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcapturesession.cpp @@ -455,7 +455,7 @@ void QAndroidCaptureSession::onCameraOpened() for (int i = 0; i < 8; ++i) { CaptureProfile profile = getProfile(i); if (!profile.isNull) { - if (i == 1) // QUALITY_HIGH + if (i == AndroidCamcorderProfile::QUALITY_HIGH) m_defaultSettings = profile; if (!m_supportedResolutions.contains(profile.videoResolution)) @@ -474,30 +474,23 @@ void QAndroidCaptureSession::onCameraOpened() QAndroidCaptureSession::CaptureProfile QAndroidCaptureSession::getProfile(int id) { CaptureProfile profile; - bool hasProfile = QJNIObjectPrivate::callStaticMethod("android/media/CamcorderProfile", - "hasProfile", - "(II)Z", - m_cameraSession->camera()->cameraId(), - id); + const bool hasProfile = AndroidCamcorderProfile::hasProfile(m_cameraSession->camera()->cameraId(), + AndroidCamcorderProfile::Quality(id)); if (hasProfile) { - QJNIObjectPrivate obj = QJNIObjectPrivate::callStaticObjectMethod("android/media/CamcorderProfile", - "get", - "(II)Landroid/media/CamcorderProfile;", - m_cameraSession->camera()->cameraId(), - id); - - - profile.outputFormat = AndroidMediaRecorder::OutputFormat(obj.getField("fileFormat")); - profile.audioEncoder = AndroidMediaRecorder::AudioEncoder(obj.getField("audioCodec")); - profile.audioBitRate = obj.getField("audioBitRate"); - profile.audioChannels = obj.getField("audioChannels"); - profile.audioSampleRate = obj.getField("audioSampleRate"); - profile.videoEncoder = AndroidMediaRecorder::VideoEncoder(obj.getField("videoCodec")); - profile.videoBitRate = obj.getField("videoBitRate"); - profile.videoFrameRate = obj.getField("videoFrameRate"); - profile.videoResolution = QSize(obj.getField("videoFrameWidth"), - obj.getField("videoFrameHeight")); + AndroidCamcorderProfile camProfile = AndroidCamcorderProfile::get(m_cameraSession->camera()->cameraId(), + AndroidCamcorderProfile::Quality(id)); + + profile.outputFormat = AndroidMediaRecorder::OutputFormat(camProfile.getValue(AndroidCamcorderProfile::fileFormat)); + profile.audioEncoder = AndroidMediaRecorder::AudioEncoder(camProfile.getValue(AndroidCamcorderProfile::audioCodec)); + profile.audioBitRate = camProfile.getValue(AndroidCamcorderProfile::audioBitRate); + profile.audioChannels = camProfile.getValue(AndroidCamcorderProfile::audioChannels); + profile.audioSampleRate = camProfile.getValue(AndroidCamcorderProfile::audioSampleRate); + profile.videoEncoder = AndroidMediaRecorder::VideoEncoder(camProfile.getValue(AndroidCamcorderProfile::videoCodec)); + profile.videoBitRate = camProfile.getValue(AndroidCamcorderProfile::videoBitRate); + profile.videoFrameRate = camProfile.getValue(AndroidCamcorderProfile::videoFrameRate); + profile.videoResolution = QSize(camProfile.getValue(AndroidCamcorderProfile::videoFrameWidth), + camProfile.getValue(AndroidCamcorderProfile::videoFrameHeight)); if (profile.outputFormat == AndroidMediaRecorder::MPEG_4) profile.outputFileExtension = QStringLiteral("mp4"); diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp index 2d49e78b1..6565b0545 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp @@ -320,8 +320,8 @@ void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent, if (mVideoSize.isValid() && mVideoOutput) mVideoOutput->setVideoSize(mVideoSize); - if (!mMediaPlayer->display() && mVideoOutput) - mMediaPlayer->setDisplay(mVideoOutput->surfaceHolder()); + if ((mMediaPlayer->display() == 0) && mVideoOutput) + mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture()); mMediaPlayer->setDataSource(mediaPath); mMediaPlayer->prepareAsync(); @@ -345,7 +345,7 @@ void QAndroidMediaPlayerControl::setVideoOutput(QObject *videoOutput) return; if (mVideoOutput->isReady()) - mMediaPlayer->setDisplay(mVideoOutput->surfaceHolder()); + mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture()); connect(videoOutput, SIGNAL(readyChanged(bool)), this, SLOT(onVideoOutputReady(bool))); } @@ -590,8 +590,8 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state) void QAndroidMediaPlayerControl::onVideoOutputReady(bool ready) { - if (!mMediaPlayer->display() && mVideoOutput && ready) - mMediaPlayer->setDisplay(mVideoOutput->surfaceHolder()); + if ((mMediaPlayer->display() == 0) && mVideoOutput && ready) + mMediaPlayer->setDisplay(mVideoOutput->surfaceTexture()); flushPendingStates(); } diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp index af017c392..c917bf2b7 100644 --- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp +++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp @@ -40,10 +40,11 @@ ****************************************************************************/ #include "androidcamera.h" +#include "androidsurfacetexture.h" +#include "qandroidmultimediautils.h" #include #include -#include "qandroidmultimediautils.h" #include #include #include @@ -367,10 +368,13 @@ void AndroidCamera::setPreviewSize(const QSize &size) QMetaObject::invokeMethod(d, "updatePreviewSize"); } -void AndroidCamera::setPreviewTexture(jobject surfaceTexture) +void AndroidCamera::setPreviewTexture(AndroidSurfaceTexture *surfaceTexture) { Q_D(AndroidCamera); - QMetaObject::invokeMethod(d, "setPreviewTexture", Qt::BlockingQueuedConnection, Q_ARG(void *, surfaceTexture)); + QMetaObject::invokeMethod(d, + "setPreviewTexture", + Qt::BlockingQueuedConnection, + Q_ARG(void *, surfaceTexture ? surfaceTexture->surfaceTexture() : 0)); } bool AndroidCamera::isZoomSupported() @@ -633,6 +637,42 @@ QJNIObjectPrivate AndroidCamera::getCameraObject() return d->m_camera; } +int AndroidCamera::getNumberOfCameras() +{ + return QJNIObjectPrivate::callStaticMethod("android/hardware/Camera", + "getNumberOfCameras"); +} + +void AndroidCamera::getCameraInfo(int id, AndroidCameraInfo *info) +{ + Q_ASSERT(info); + + QJNIObjectPrivate cameraInfo("android/hardware/Camera$CameraInfo"); + QJNIObjectPrivate::callStaticMethod("android/hardware/Camera", + "getCameraInfo", + "(ILandroid/hardware/Camera$CameraInfo;)V", + id, cameraInfo.object()); + + AndroidCamera::CameraFacing facing = AndroidCamera::CameraFacing(cameraInfo.getField("facing")); + // The orientation provided by Android is counter-clockwise, we need it clockwise + info->orientation = (360 - cameraInfo.getField("orientation")) % 360; + + switch (facing) { + case AndroidCamera::CameraFacingBack: + info->name = QByteArray("back"); + info->description = QStringLiteral("Rear-facing camera"); + info->position = QCamera::BackFace; + break; + case AndroidCamera::CameraFacingFront: + info->name = QByteArray("front"); + info->description = QStringLiteral("Front-facing camera"); + info->position = QCamera::FrontFace; + break; + default: + break; + } +} + void AndroidCamera::startPreview() { Q_D(AndroidCamera); diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.h b/src/plugins/android/src/wrappers/jni/androidcamera.h index de97f5767..2ea69b7e3 100644 --- a/src/plugins/android/src/wrappers/jni/androidcamera.h +++ b/src/plugins/android/src/wrappers/jni/androidcamera.h @@ -46,12 +46,22 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QThread; class AndroidCameraPrivate; +class AndroidSurfaceTexture; + +struct AndroidCameraInfo +{ + QByteArray name; + QString description; + QCamera::Position position; + int orientation; +}; class AndroidCamera : public QObject { @@ -96,7 +106,7 @@ public: QSize previewSize() const; void setPreviewSize(const QSize &size); - void setPreviewTexture(jobject surfaceTexture); + void setPreviewTexture(AndroidSurfaceTexture *surfaceTexture); bool isZoomSupported(); int getMaxZoom(); @@ -157,6 +167,9 @@ public: void fetchLastPreviewFrame(); QJNIObjectPrivate getCameraObject(); + static int getNumberOfCameras(); + static void getCameraInfo(int id, AndroidCameraInfo *info); + static bool initJNI(JNIEnv *env); Q_SIGNALS: diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp index 9c9f685cb..5aee7a857 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp +++ b/src/plugins/android/src/wrappers/jni/androidmediaplayer.cpp @@ -44,6 +44,7 @@ #include #include #include +#include "androidsurfacetexture.h" #include static jclass mediaPlayerClass = Q_NULLPTR; @@ -150,9 +151,11 @@ void AndroidMediaPlayer::setVolume(int volume) mMediaPlayer.callMethod("setVolume", "(I)V", jint(volume)); } -void AndroidMediaPlayer::setDisplay(jobject surfaceHolder) +void AndroidMediaPlayer::setDisplay(AndroidSurfaceTexture *surfaceTexture) { - mMediaPlayer.callMethod("setDisplay", "(Landroid/view/SurfaceHolder;)V", surfaceHolder); + mMediaPlayer.callMethod("setDisplay", + "(Landroid/view/SurfaceHolder;)V", + surfaceTexture ? surfaceTexture->surfaceHolder() : 0); } static void onErrorNative(JNIEnv *env, jobject thiz, jint what, jint extra, jlong id) diff --git a/src/plugins/android/src/wrappers/jni/androidmediaplayer.h b/src/plugins/android/src/wrappers/jni/androidmediaplayer.h index b2cab805e..976d886f8 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediaplayer.h +++ b/src/plugins/android/src/wrappers/jni/androidmediaplayer.h @@ -47,6 +47,8 @@ QT_BEGIN_NAMESPACE +class AndroidSurfaceTexture; + class AndroidMediaPlayer : public QObject { Q_OBJECT @@ -113,7 +115,7 @@ public: void setDataSource(const QString &path); void prepareAsync(); void setVolume(int volume); - void setDisplay(jobject surfaceHolder); + void setDisplay(AndroidSurfaceTexture *surfaceTexture); static bool initJNI(JNIEnv *env); diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp index 3683c9aa5..71f88213f 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp +++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.cpp @@ -47,6 +47,80 @@ QT_BEGIN_NAMESPACE +typedef QMap CamcorderProfiles; +Q_GLOBAL_STATIC(CamcorderProfiles, g_camcorderProfiles) + +static QString profileKey() +{ + return QStringLiteral("%1-%2"); +} + +bool AndroidCamcorderProfile::hasProfile(jint cameraId, Quality quality) +{ + if (g_camcorderProfiles->contains(profileKey().arg(cameraId).arg(quality))) + return true; + + return QJNIObjectPrivate::callStaticMethod("android/media/CamcorderProfile", + "hasProfile", + "(II)Z", + cameraId, + quality); +} + +AndroidCamcorderProfile AndroidCamcorderProfile::get(jint cameraId, Quality quality) +{ + const QString key = profileKey().arg(cameraId).arg(quality); + QMap::const_iterator it = g_camcorderProfiles->constFind(key); + + if (it != g_camcorderProfiles->constEnd()) + return AndroidCamcorderProfile(*it); + + QJNIObjectPrivate camProfile = QJNIObjectPrivate::callStaticObjectMethod("android/media/CamcorderProfile", + "get", + "(II)Landroid/media/CamcorderProfile;", + cameraId, + quality); + + return AndroidCamcorderProfile((*g_camcorderProfiles)[key] = camProfile); +} + +int AndroidCamcorderProfile::getValue(AndroidCamcorderProfile::Field field) const +{ + switch (field) { + case audioBitRate: + return m_camcorderProfile.getField("audioBitRate"); + case audioChannels: + return m_camcorderProfile.getField("audioChannels"); + case audioCodec: + return m_camcorderProfile.getField("audioCodec"); + case audioSampleRate: + return m_camcorderProfile.getField("audioSampleRate"); + case duration: + return m_camcorderProfile.getField("duration"); + case fileFormat: + return m_camcorderProfile.getField("fileFormat"); + case quality: + return m_camcorderProfile.getField("quality"); + case videoBitRate: + return m_camcorderProfile.getField("videoBitRate"); + case videoCodec: + return m_camcorderProfile.getField("videoCodec"); + case videoFrameHeight: + return m_camcorderProfile.getField("videoFrameHeight"); + case videoFrameRate: + return m_camcorderProfile.getField("videoFrameRate"); + case videoFrameWidth: + return m_camcorderProfile.getField("videoFrameWidth"); + } + + return 0; +} + +AndroidCamcorderProfile::AndroidCamcorderProfile(const QJNIObjectPrivate &camcorderProfile) +{ + m_camcorderProfile = camcorderProfile; +} + static jclass g_qtMediaRecorderListenerClass = 0; typedef QMap MediaRecorderMap; Q_GLOBAL_STATIC(MediaRecorderMap, mediaRecorders) diff --git a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h index 1ab1b9026..686217dc8 100644 --- a/src/plugins/android/src/wrappers/jni/androidmediarecorder.h +++ b/src/plugins/android/src/wrappers/jni/androidmediarecorder.h @@ -50,6 +50,44 @@ QT_BEGIN_NAMESPACE class AndroidCamera; +class AndroidCamcorderProfile +{ +public: + enum Quality { // Needs to match CamcorderProfile + QUALITY_LOW, + QUALITY_HIGH, + QUALITY_QCIF, + QUALITY_CIF, + QUALITY_480P, + QUALITY_720P, + QUALITY_1080P, + QUALITY_QVGA + }; + + enum Field { + audioBitRate, + audioChannels, + audioCodec, + audioSampleRate, + duration, + fileFormat, + quality, + videoBitRate, + videoCodec, + videoFrameHeight, + videoFrameRate, + videoFrameWidth + }; + + static bool hasProfile(jint cameraId, Quality quality); + static AndroidCamcorderProfile get(jint cameraId, Quality quality); + int getValue(Field field) const; + +private: + AndroidCamcorderProfile(const QJNIObjectPrivate &camcorderProfile); + QJNIObjectPrivate m_camcorderProfile; +}; + class AndroidMediaRecorder : public QObject { Q_OBJECT diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp index 8c334a060..06dcd74ca 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.cpp @@ -86,6 +86,9 @@ AndroidSurfaceTexture::AndroidSurfaceTexture(unsigned int texName) AndroidSurfaceTexture::~AndroidSurfaceTexture() { + if (QtAndroidPrivate::androidSdkVersion() > 13 && m_surfaceView.isValid()) + m_surfaceView.callMethod("release"); + if (m_surfaceTexture.isValid()) { release(); g_objectMap.remove(m_texID); @@ -124,11 +127,31 @@ void AndroidSurfaceTexture::updateTexImage() m_surfaceTexture.callMethod("updateTexImage"); } -jobject AndroidSurfaceTexture::object() +jobject AndroidSurfaceTexture::surfaceTexture() { return m_surfaceTexture.object(); } +jobject AndroidSurfaceTexture::surfaceView() +{ + return m_surfaceView.object(); +} + +jobject AndroidSurfaceTexture::surfaceHolder() +{ + if (!m_surfaceHolder.isValid()) { + m_surfaceView = QJNIObjectPrivate("android/view/Surface", + "(Landroid/graphics/SurfaceTexture;)V", + m_surfaceTexture.object()); + + m_surfaceHolder = QJNIObjectPrivate("org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder", + "(Landroid/view/Surface;)V", + m_surfaceView.object()); + } + + return m_surfaceHolder.object(); +} + static JNINativeMethod methods[] = { {"notifyFrameAvailable", "(I)V", (void *)notifyFrameAvailable} }; diff --git a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h index 5898096fc..ee49244cd 100644 --- a/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h +++ b/src/plugins/android/src/wrappers/jni/androidsurfacetexture.h @@ -57,7 +57,10 @@ public: ~AndroidSurfaceTexture(); int textureID() const { return m_texID; } - jobject object(); + jobject surfaceTexture(); + jobject surfaceView(); + jobject surfaceHolder(); + inline bool isValid() const { return m_surfaceTexture.isValid(); } QMatrix4x4 getTransformMatrix(); void release(); // API level 14 @@ -71,6 +74,8 @@ Q_SIGNALS: private: int m_texID; QJNIObjectPrivate m_surfaceTexture; + QJNIObjectPrivate m_surfaceView; + QJNIObjectPrivate m_surfaceHolder; }; QT_END_NAMESPACE -- cgit v1.2.3 From cb6b4e2079d561bdb4e4e7d661c74c2f6ad15040 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 4 Jun 2014 11:08:13 +0200 Subject: Doc: Remove comment about preliminary API for Qt 5.0 Task-number: QTBUG-39195 Change-Id: I193321a29d06760e4ad5aa2eaca99d98b2e1f65a Reviewed-by: Jerome Pasion --- src/multimedia/doc/src/audiooverview.qdoc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/multimedia/doc/src/audiooverview.qdoc b/src/multimedia/doc/src/audiooverview.qdoc index 54735da6c..32556543b 100644 --- a/src/multimedia/doc/src/audiooverview.qdoc +++ b/src/multimedia/doc/src/audiooverview.qdoc @@ -116,18 +116,14 @@ code but more buffering, which may affect latency. \section2 Decoding Compressed Audio to Memory In some cases you may want to decode a compressed audio file and do further -processing yourself (like mix multiple samples, or some custom digital signal -processing algorithms). Qt Multimedia 5.0 offers a preliminary API for this -case - the \l QAudioDecoder class. QAudioDecoder supports decoding local files -or from a QIODevice instances. +processing yourself (for example, mixing multiple samples or using custom +digital signal processing algorithms). QAudioDecoder supports decoding local +files or data streams from QIODevice instances. Here's an example of decoding a local file: \snippet multimedia-snippets/audio.cpp Local audio decoding -Note: This API is preliminary at this time - the API may change or be -removed before the final 5.0 release. - \section1 Examples There are both C++ and QML examples available. -- cgit v1.2.3 From cf4aba93e4c67395c53bc758138c0c16658093c3 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 16 May 2014 16:47:41 +0200 Subject: Android: fix media player's volume. - Preserve the volume when changing the current media. - Don't actually set a new volume when the media player is muted. Intead, save the value to apply it when setMuted(false) is called. Change-Id: I829eb280406ea35ff82a0c2638b2d19cf1d90643 Reviewed-by: Christian Stromme --- .../android/multimedia/QtAndroidMediaPlayer.java | 29 ++++++++++++++-------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java index 01f260910..32d3496ee 100644 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java @@ -248,6 +248,8 @@ public class QtAndroidMediaPlayer if (mMediaPlayer == null) { mMediaPlayer = new MediaPlayer(); setState(State.Idle); + // Make sure the new media player has the volume that was set on the QMediaPlayer + setVolumeHelper(mMuted ? 0 : mVolume); } } @@ -476,6 +478,20 @@ public class QtAndroidMediaPlayer } public void setVolume(int volume) + { + if (volume < 0) + volume = 0; + + if (volume > 100) + volume = 100; + + mVolume = volume; + + if (!mMuted) + setVolumeHelper(mVolume); + } + + private void setVolumeHelper(int volume) { if ((mState & (State.Idle | State.Initialized @@ -487,18 +503,9 @@ public class QtAndroidMediaPlayer return; } - if (volume < 0) - volume = 0; - - if (volume > 100) - volume = 100; - - float newVolume = adjustVolume(volume); - try { + float newVolume = adjustVolume(volume); mMediaPlayer.setVolume(newVolume, newVolume); - if (!mMuted) - mVolume = volume; } catch (final IllegalStateException e) { Log.d(TAG, "" + e.getMessage()); } @@ -528,7 +535,7 @@ public class QtAndroidMediaPlayer public void mute(final boolean mute) { mMuted = mute; - setVolume(mute ? 0 : mVolume); + setVolumeHelper(mute ? 0 : mVolume); } public boolean isMuted() -- cgit v1.2.3 From a3a66701722c780457b26d3d446b7bf19cf50804 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Fri, 16 May 2014 14:17:03 +0200 Subject: Android: don't start camera preview until the viewfinder is ready. If no video output is set for a camera, don't try to start the camera and report an error. If the video output is not ready, delay starting until it is. Change-Id: Id08e31a4e795b71ac036a6532e9499ca5670d790 Reviewed-by: Christian Stromme --- .../src/mediacapture/qandroidcamerasession.cpp | 36 +++++++++++++++------- .../src/mediacapture/qandroidcamerasession.h | 2 +- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index a2eba13f3..963952294 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -168,10 +168,12 @@ void QAndroidCameraSession::setState(QCamera::State state) emit error(QCamera::CameraError, QStringLiteral("Failed to open camera")); return; } - if (state == QCamera::ActiveState) - startPreview(); - else if (state == QCamera::LoadedState) + if (state == QCamera::ActiveState) { + if (!startPreview()) + return; + } else if (state == QCamera::LoadedState) { stopPreview(); + } break; } @@ -316,10 +318,23 @@ void QAndroidCameraSession::adjustViewfinderSize(const QSize &captureSize, bool } } -void QAndroidCameraSession::startPreview() +bool QAndroidCameraSession::startPreview() { - if (!m_camera || m_previewStarted) - return; + if (!m_camera) + return false; + + if (!m_videoOutput) { + Q_EMIT error(QCamera::InvalidRequestError, tr("Camera cannot be started without a viewfinder.")); + return false; + } + + if (m_previewStarted) + return true; + + if (m_videoOutput->isReady()) + m_camera->setPreviewTexture(m_videoOutput->surfaceTexture()); + else + return true; // delay starting until the video output is ready m_status = QCamera::StartingStatus; emit statusChanged(m_status); @@ -327,13 +342,12 @@ void QAndroidCameraSession::startPreview() applyImageSettings(); adjustViewfinderSize(m_imageSettings.resolution()); - if (m_videoOutput && m_videoOutput->isReady()) - onVideoOutputReady(true); - AndroidMultimediaUtils::enableOrientationListener(true); m_camera->startPreview(); m_previewStarted = true; + + return true; } void QAndroidCameraSession::stopPreview() @@ -683,8 +697,8 @@ QImage QAndroidCameraSession::prepareImageFromPreviewData(const QByteArray &data void QAndroidCameraSession::onVideoOutputReady(bool ready) { - if (m_camera && m_videoOutput && ready) - m_camera->setPreviewTexture(m_videoOutput->surfaceTexture()); + if (ready && m_state == QCamera::ActiveState) + startPreview(); } void QAndroidCameraSession::onApplicationStateChanged(Qt::ApplicationState state) diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h index 05765aa82..04ba1605f 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.h +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.h @@ -133,7 +133,7 @@ private: bool open(); void close(); - void startPreview(); + bool startPreview(); void stopPreview(); void applyImageSettings(); -- cgit v1.2.3 From d71aaca893a27a8a9a6712a59313300b87226a4f Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 20 May 2014 15:52:54 +0200 Subject: Improve default audio plugin selection. When no audio plugin is marked as default, use the first plugin available. Change-Id: Ide8db0fe55f43c4881c24505c1e2821b0fc176f6 Reviewed-by: Dyami Caliri Reviewed-by: Christian Stromme --- src/multimedia/audio/qaudiodevicefactory.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/audio/qaudiodevicefactory.cpp index a36ab3932..50f4a7676 100644 --- a/src/multimedia/audio/qaudiodevicefactory.cpp +++ b/src/multimedia/audio/qaudiodevicefactory.cpp @@ -49,6 +49,11 @@ QT_BEGIN_NAMESPACE +static QString defaultKey() +{ + return QStringLiteral("default"); +} + #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) Q_GLOBAL_STATIC_WITH_ARGS(QMediaPluginLoader, audioLoader, (QAudioSystemFactoryInterface_iid, QLatin1String("audio"), Qt::CaseInsensitive)) @@ -137,13 +142,18 @@ QList QAudioDeviceFactory::availableDevices(QAudio::Mode mode) QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice() { #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) - QAudioSystemFactoryInterface* plugin = qobject_cast(audioLoader()->instance(QLatin1String("default"))); - + QAudioSystemFactoryInterface* plugin = qobject_cast(audioLoader()->instance(defaultKey())); if (plugin) { QList list = plugin->availableDevices(QAudio::AudioInput); if (list.size() > 0) - return QAudioDeviceInfo(QLatin1String("default"), list.at(0), QAudio::AudioInput); + return QAudioDeviceInfo(defaultKey(), list.at(0), QAudio::AudioInput); } + + // if no plugin is marked as default or if the default plugin doesn't have any input device, + // return the first input available from other plugins. + QList inputDevices = availableDevices(QAudio::AudioInput); + if (!inputDevices.isEmpty()) + return inputDevices.first(); #endif return QAudioDeviceInfo(); @@ -152,13 +162,18 @@ QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice() QAudioDeviceInfo QAudioDeviceFactory::defaultOutputDevice() { #if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) - QAudioSystemFactoryInterface* plugin = qobject_cast(audioLoader()->instance(QLatin1String("default"))); - + QAudioSystemFactoryInterface* plugin = qobject_cast(audioLoader()->instance(defaultKey())); if (plugin) { QList list = plugin->availableDevices(QAudio::AudioOutput); if (list.size() > 0) - return QAudioDeviceInfo(QLatin1String("default"), list.at(0), QAudio::AudioOutput); + return QAudioDeviceInfo(defaultKey(), list.at(0), QAudio::AudioOutput); } + + // if no plugin is marked as default or if the default plugin doesn't have any output device, + // return the first output available from other plugins. + QList outputDevices = availableDevices(QAudio::AudioOutput); + if (!outputDevices.isEmpty()) + return outputDevices.first(); #endif return QAudioDeviceInfo(); -- cgit v1.2.3 From 8a66559e0b7d94d6b2ffe613b61194407031730c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 4 Jun 2014 22:30:05 +0200 Subject: Android: Use a file descriptor for all local media files. Using a fd is more consistent across different Android versions and also works with files that are in the applications private storage. Task-number: QTBUG-39346 Change-Id: I462822459d12d7842d15f1cb7caafc75c18fe32c Reviewed-by: Yoann Lopes --- .../qt5/android/multimedia/QtAndroidMediaPlayer.java | 15 ++++++++++----- .../src/mediaplayer/qandroidmediaplayercontrol.cpp | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java index 32d3496ee..ff92af771 100644 --- a/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java +++ b/src/plugins/android/jar/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java @@ -379,6 +379,7 @@ public class QtAndroidMediaPlayer mMediaPlayer.setDisplay(mSurfaceHolder); AssetFileDescriptor afd = null; + FileInputStream fis = null; try { mUri = Uri.parse(path); final boolean inAssets = (mUri.getScheme().compareTo("assets") == 0); @@ -390,8 +391,8 @@ public class QtAndroidMediaPlayer final long length = afd.getLength(); FileDescriptor fd = afd.getFileDescriptor(); mMediaPlayer.setDataSource(fd, offset, length); - } else if (mUri.getScheme().compareTo("tempfile") == 0) { - FileInputStream fis = new FileInputStream(mUri.getPath()); + } else if (mUri.getScheme().compareTo("file") == 0) { + fis = new FileInputStream(mUri.getPath()); FileDescriptor fd = fis.getFD(); mMediaPlayer.setDataSource(fd); } else { @@ -409,9 +410,13 @@ public class QtAndroidMediaPlayer } catch (final NullPointerException e) { Log.d(TAG, "" + e.getMessage()); } finally { - if (afd !=null) { - try { afd.close(); } catch (final IOException ioe) { /* Ignore... */ } - } + try { + if (afd != null) + afd.close(); + if (fis != null) + fis.close(); + } catch (final IOException ioe) { /* Ignore... */ } + if ((mState & State.Initialized) == 0) { setState(State.Error); onErrorNative(MediaPlayer.MEDIA_ERROR_UNKNOWN, diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp index 6565b0545..6817d65b0 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp @@ -312,7 +312,7 @@ void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent, const QString path = url.toString().mid(3); mTempFile.reset(QTemporaryFile::createNativeFile(path)); if (!mTempFile.isNull()) - mediaPath = QLatin1String("tempfile://") + mTempFile->fileName(); + mediaPath = QStringLiteral("file://") + mTempFile->fileName(); } else { mediaPath = url.toString(); } -- cgit v1.2.3 From eadf1c8c41a41509a7c87b44d66b48cb8345acdb Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 3 Jun 2014 16:32:46 +0200 Subject: Fix static initialization order fiasco in some plugins. Some static variables were initialized using QMediaMetaData values, which are also statically initialized. Task-number: QTBUG-39202 Change-Id: Ibedc0a77d96cdfa575aad122c4ec654e6830e1f7 Reviewed-by: Andrew den Exter --- .../player/directshowmetadatacontrol.cpp | 153 ++++++++-------- .../gstreamer/camerabin/camerabinmetadata.cpp | 198 +++++++++++---------- .../qgstreamercapturemetadatacontrol.cpp | 182 +++++++++---------- .../mediaplayer/qgstreamermetadataprovider.cpp | 150 ++++++++-------- .../mediaplayer/qgstreamermetadataprovider.h | 1 - 5 files changed, 337 insertions(+), 347 deletions(-) diff --git a/src/plugins/directshow/player/directshowmetadatacontrol.cpp b/src/plugins/directshow/player/directshowmetadatacontrol.cpp index 51d9574ba..96c9fab8b 100644 --- a/src/plugins/directshow/player/directshowmetadatacontrol.cpp +++ b/src/plugins/directshow/player/directshowmetadatacontrol.cpp @@ -104,75 +104,85 @@ static q_SHCreateItemFromParsingName sHCreateItemFromParsingName = 0; #endif #ifndef QT_NO_WMSDK + namespace { - struct QWMMetaDataKeyLookup + struct QWMMetaDataKey { - QString key; - const wchar_t *token; + QString qtName; + const wchar_t *wmName; + + QWMMetaDataKey(const QString &qtn, const wchar_t *wmn) : qtName(qtn), wmName(wmn) { } }; } -static const QWMMetaDataKeyLookup qt_wmMetaDataKeys[] = +typedef QList QWMMetaDataKeys; +Q_GLOBAL_STATIC(QWMMetaDataKeys, metadataKeys) + +static const QWMMetaDataKeys *qt_wmMetaDataKeys() { - { QMediaMetaData::Title, L"Title" }, - { QMediaMetaData::SubTitle, L"WM/SubTitle" }, - { QMediaMetaData::Author, L"Author" }, - { QMediaMetaData::Comment, L"Comment" }, - { QMediaMetaData::Description, L"Description" }, - { QMediaMetaData::Category, L"WM/Category" }, - { QMediaMetaData::Genre, L"WM/Genre" }, - //{ QMediaMetaData::Date, 0 }, - { QMediaMetaData::Year, L"WM/Year" }, - { QMediaMetaData::UserRating, L"Rating" }, - //{ QMediaMetaData::MetaDatawords, 0 }, - { QMediaMetaData::Language, L"WM/Language" }, - { QMediaMetaData::Publisher, L"WM/Publisher" }, - { QMediaMetaData::Copyright, L"Copyright" }, - { QMediaMetaData::ParentalRating, L"WM/ParentalRating" }, - //{ QMediaMetaData::RatingOrganisation, L"RatingOrganisation" }, - - // Media - { QMediaMetaData::Size, L"FileSize" }, - { QMediaMetaData::MediaType, L"MediaType" }, - { QMediaMetaData::Duration, L"Duration" }, - - // Audio - { QMediaMetaData::AudioBitRate, L"AudioBitRate" }, - { QMediaMetaData::AudioCodec, L"AudioCodec" }, - { QMediaMetaData::ChannelCount, L"ChannelCount" }, - { QMediaMetaData::SampleRate, L"Frequency" }, - - // Music - { QMediaMetaData::AlbumTitle, L"WM/AlbumTitle" }, - { QMediaMetaData::AlbumArtist, L"WM/AlbumArtist" }, - { QMediaMetaData::ContributingArtist, L"Author" }, - { QMediaMetaData::Composer, L"WM/Composer" }, - { QMediaMetaData::Conductor, L"WM/Conductor" }, - { QMediaMetaData::Lyrics, L"WM/Lyrics" }, - { QMediaMetaData::Mood, L"WM/Mood" }, - { QMediaMetaData::TrackNumber, L"WM/TrackNumber" }, - //{ QMediaMetaData::TrackCount, 0 }, - //{ QMediaMetaData::CoverArtUriSmall, 0 }, - //{ QMediaMetaData::CoverArtUriLarge, 0 }, - - // Image/Video - { QMediaMetaData::Resolution, L"WM/VideoHeight" }, - { QMediaMetaData::PixelAspectRatio, L"AspectRatioX" }, - - // Video - { QMediaMetaData::VideoFrameRate, L"WM/VideoFrameRate" }, - { QMediaMetaData::VideoBitRate, L"VideoBitRate" }, - { QMediaMetaData::VideoCodec, L"VideoCodec" }, - - //{ QMediaMetaData::PosterUri, 0 }, - - // Movie - { QMediaMetaData::ChapterNumber, L"ChapterNumber" }, - { QMediaMetaData::Director, L"WM/Director" }, - { QMediaMetaData::LeadPerformer, L"LeadPerformer" }, - { QMediaMetaData::Writer, L"WM/Writer" }, -}; + if (metadataKeys->isEmpty()) { + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Title, L"Title")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::SubTitle, L"WM/SubTitle")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Author, L"Author")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Comment, L"Comment")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Description, L"Description")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Category, L"WM/Category")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Genre, L"WM/Genre")); + //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Date, 0)); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Year, L"WM/Year")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::UserRating, L"Rating")); + //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::MetaDatawords, 0)); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Language, L"WM/Language")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Publisher, L"WM/Publisher")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Copyright, L"Copyright")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::ParentalRating, L"WM/ParentalRating")); + //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::RatingOrganisation, L"RatingOrganisation")); + + // Media + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Size, L"FileSize")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::MediaType, L"MediaType")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Duration, L"Duration")); + + // Audio + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::AudioBitRate, L"AudioBitRate")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::AudioCodec, L"AudioCodec")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::ChannelCount, L"ChannelCount")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::SampleRate, L"Frequency")); + + // Music + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::AlbumTitle, L"WM/AlbumTitle")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::AlbumArtist, L"WM/AlbumArtist")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::ContributingArtist, L"Author")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Composer, L"WM/Composer")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Conductor, L"WM/Conductor")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Lyrics, L"WM/Lyrics")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Mood, L"WM/Mood")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::TrackNumber, L"WM/TrackNumber")); + //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::TrackCount, 0)); + //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::CoverArtUriSmall, 0)); + //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::CoverArtUriLarge, 0)); + + // Image/Video + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Resolution, L"WM/VideoHeight")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::PixelAspectRatio, L"AspectRatioX")); + + // Video + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::VideoFrameRate, L"WM/VideoFrameRate")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::VideoBitRate, L"VideoBitRate")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::VideoCodec, L"VideoCodec")); + + //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::PosterUri, 0)); + + // Movie + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::ChapterNumber, L"ChapterNumber")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Director, L"WM/Director")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::LeadPerformer, L"LeadPerformer")); + metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Writer, L"WM/Writer")); + } + + return metadataKeys; +} static QVariant getValue(IWMHeaderInfo *header, const wchar_t *key) { @@ -491,32 +501,29 @@ void DirectShowMetaDataControl::updateGraph(IFilterGraph2 *graph, IBaseFilter *s IWMHeaderInfo *info = com_cast(source, IID_IWMHeaderInfo); if (info) { - static const int count = sizeof(qt_wmMetaDataKeys) / sizeof(QWMMetaDataKeyLookup); - for (int i = 0; i < count; ++i) { - QVariant var = getValue(info, qt_wmMetaDataKeys[i].token); + Q_FOREACH (const QWMMetaDataKey &key, *qt_wmMetaDataKeys()) { + QVariant var = getValue(info, key.wmName); if (var.isValid()) { - QString key = qt_wmMetaDataKeys[i].key; - - if (key == QMediaMetaData::Duration) { + if (key.qtName == QMediaMetaData::Duration) { // duration is provided in 100-nanosecond units, convert to milliseconds var = (var.toLongLong() + 10000) / 10000; - } else if (key == QMediaMetaData::Resolution) { + } else if (key.qtName == QMediaMetaData::Resolution) { QSize res; res.setHeight(var.toUInt()); res.setWidth(getValue(info, L"WM/VideoWidth").toUInt()); var = res; - } else if (key == QMediaMetaData::VideoFrameRate) { + } else if (key.qtName == QMediaMetaData::VideoFrameRate) { var = var.toReal() / 1000.f; - } else if (key == QMediaMetaData::PixelAspectRatio) { + } else if (key.qtName == QMediaMetaData::PixelAspectRatio) { QSize aspectRatio; aspectRatio.setWidth(var.toUInt()); aspectRatio.setHeight(getValue(info, L"AspectRatioY").toUInt()); var = aspectRatio; - } else if (key == QMediaMetaData::UserRating) { + } else if (key.qtName == QMediaMetaData::UserRating) { var = (var.toUInt() - 1) / qreal(98) * 100; } - m_metadata.insert(key, var); + m_metadata.insert(key.qtName, var); } } diff --git a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp index c2b7c33c3..170d25a07 100644 --- a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp @@ -50,13 +50,6 @@ QT_BEGIN_NAMESPACE -struct QGstreamerMetaDataKeyLookup -{ - QString key; - const char *token; - QVariant::Type type; -}; - static QVariant fromGStreamerOrientation(const QVariant &value) { // Note gstreamer tokens either describe the counter clockwise rotation of the @@ -87,87 +80,109 @@ static QVariant toGStreamerOrientation(const QVariant &value) } } -static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] = +namespace { + struct QGStreamerMetaDataKey + { + QString qtName; + const char *gstName; + QVariant::Type type; + + QGStreamerMetaDataKey(const QString &qtn, const char *gstn, QVariant::Type t) + : qtName(qtn) + , gstName(gstn) + , type(t) + { } + }; +} + +typedef QList QGStreamerMetaDataKeys; +Q_GLOBAL_STATIC(QGStreamerMetaDataKeys, metadataKeys) + +static const QGStreamerMetaDataKeys *qt_gstreamerMetaDataKeys() { - { QMediaMetaData::Title, GST_TAG_TITLE, QVariant::String }, - //{ QMediaMetaData::SubTitle, 0, QVariant::String }, - //{ QMediaMetaData::Author, 0, QVariant::String }, - { QMediaMetaData::Comment, GST_TAG_COMMENT, QVariant::String }, - { QMediaMetaData::Date, GST_TAG_DATE_TIME, QVariant::DateTime }, - { QMediaMetaData::Description, GST_TAG_DESCRIPTION, QVariant::String }, - //{ QMediaMetaData::Category, 0, QVariant::String }, - { QMediaMetaData::Genre, GST_TAG_GENRE, QVariant::String }, - //{ QMediaMetaData::Year, 0, QVariant::Int }, - //{ QMediaMetaData::UserRating, , QVariant::Int }, - - { QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE, QVariant::String }, - - { QMediaMetaData::Publisher, GST_TAG_ORGANIZATION, QVariant::String }, - { QMediaMetaData::Copyright, GST_TAG_COPYRIGHT, QVariant::String }, - //{ QMediaMetaData::ParentalRating, 0, QVariant::String }, - //{ QMediaMetaData::RatingOrganisation, 0, QVariant::String }, - - // Media - //{ QMediaMetaData::Size, 0, QVariant::Int }, - //{ QMediaMetaData::MediaType, 0, QVariant::String }, - { QMediaMetaData::Duration, GST_TAG_DURATION, QVariant::Int }, - - // Audio - { QMediaMetaData::AudioBitRate, GST_TAG_BITRATE, QVariant::Int }, - { QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC, QVariant::String }, - //{ QMediaMetaData::ChannelCount, 0, QVariant::Int }, - //{ QMediaMetaData::SampleRate, 0, QVariant::Int }, - - // Music - { QMediaMetaData::AlbumTitle, GST_TAG_ALBUM, QVariant::String }, - { QMediaMetaData::AlbumArtist, GST_TAG_ARTIST, QVariant::String}, - { QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER, QVariant::String }, + if (metadataKeys->isEmpty()) { + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Title, GST_TAG_TITLE, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::SubTitle, 0, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Author, 0, QVariant::String)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Comment, GST_TAG_COMMENT, QVariant::String)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Date, GST_TAG_DATE_TIME, QVariant::DateTime)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Description, GST_TAG_DESCRIPTION, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Category, 0, QVariant::String)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Genre, GST_TAG_GENRE, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Year, 0, QVariant::Int)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::UserRating, , QVariant::Int)); + + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE, QVariant::String)); + + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Publisher, GST_TAG_ORGANIZATION, QVariant::String)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Copyright, GST_TAG_COPYRIGHT, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::ParentalRating, 0, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::RatingOrganisation, 0, QVariant::String)); + + // Media + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Size, 0, QVariant::Int)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::MediaType, 0, QVariant::String)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Duration, GST_TAG_DURATION, QVariant::Int)); + + // Audio + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::AudioBitRate, GST_TAG_BITRATE, QVariant::Int)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::ChannelCount, 0, QVariant::Int)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::SampleRate, 0, QVariant::Int)); + + // Music + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::AlbumTitle, GST_TAG_ALBUM, QVariant::String)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::AlbumArtist, GST_TAG_ARTIST, QVariant::String)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER, QVariant::String)); #if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19) - { QMediaMetaData::Composer, GST_TAG_COMPOSER, QVariant::String }, + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Composer, GST_TAG_COMPOSER, QVariant::String)); #endif - //{ QMediaMetaData::Conductor, 0, QVariant::String }, - //{ QMediaMetaData::Lyrics, 0, QVariant::String }, - //{ QMediaMetaData::Mood, 0, QVariant::String }, - { QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER, QVariant::Int }, + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Conductor, 0, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Lyrics, 0, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Mood, 0, QVariant::String)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER, QVariant::Int)); - //{ QMediaMetaData::CoverArtUrlSmall, 0, QVariant::String }, - //{ QMediaMetaData::CoverArtUrlLarge, 0, QVariant::String }, + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::CoverArtUrlSmall, 0, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::CoverArtUrlLarge, 0, QVariant::String)); - // Image/Video - //{ QMediaMetaData::Resolution, 0, QVariant::Size }, - //{ QMediaMetaData::PixelAspectRatio, 0, QVariant::Size }, + // Image/Video + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Resolution, 0, QVariant::Size)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::PixelAspectRatio, 0, QVariant::Size)); - // Video - //{ QMediaMetaData::VideoFrameRate, 0, QVariant::String }, - //{ QMediaMetaData::VideoBitRate, 0, QVariant::Double }, - { QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC, QVariant::String }, + // Video + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::VideoFrameRate, 0, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::VideoBitRate, 0, QVariant::Double)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC, QVariant::String)); - //{ QMediaMetaData::PosterUrl, 0, QVariant::String }, + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::PosterUrl, 0, QVariant::String)); - // Movie - //{ QMediaMetaData::ChapterNumber, 0, QVariant::Int }, - //{ QMediaMetaData::Director, 0, QVariant::String }, - { QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER, QVariant::String }, - //{ QMediaMetaData::Writer, 0, QVariant::String }, + // Movie + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::ChapterNumber, 0, QVariant::Int)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Director, 0, QVariant::String)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Writer, 0, QVariant::String)); #if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 30) - // Photos - { QMediaMetaData::CameraManufacturer, GST_TAG_DEVICE_MANUFACTURER, QVariant::String }, - { QMediaMetaData::CameraModel, GST_TAG_DEVICE_MODEL, QVariant::String }, - //{ QMediaMetaData::Event, 0, QVariant::String }, - //{ QMediaMetaData::Subject, 0, QVariant::String }, - - { QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION, QVariant::String }, - - // GPS - { QMediaMetaData::GPSLatitude, GST_TAG_GEO_LOCATION_LATITUDE, QVariant::Double }, - { QMediaMetaData::GPSLongitude, GST_TAG_GEO_LOCATION_LONGITUDE, QVariant::Double }, - { QMediaMetaData::GPSAltitude, GST_TAG_GEO_LOCATION_ELEVATION, QVariant::Double }, - { QMediaMetaData::GPSTrack, GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, QVariant::Double }, - { QMediaMetaData::GPSSpeed, GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, QVariant::Double }, - { QMediaMetaData::GPSImgDirection, GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, QVariant::Double } + // Photos + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::CameraManufacturer, GST_TAG_DEVICE_MANUFACTURER, QVariant::String)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::CameraModel, GST_TAG_DEVICE_MODEL, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Event, 0, QVariant::String)); + //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Subject, 0, QVariant::String)); + + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Orientation, GST_TAG_IMAGE_ORIENTATION, QVariant::String)); + + // GPS + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSLatitude, GST_TAG_GEO_LOCATION_LATITUDE, QVariant::Double)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSLongitude, GST_TAG_GEO_LOCATION_LONGITUDE, QVariant::Double)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSAltitude, GST_TAG_GEO_LOCATION_ELEVATION, QVariant::Double)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSTrack, GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, QVariant::Double)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSSpeed, GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, QVariant::Double)); + metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::GPSImgDirection, GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, QVariant::Double)); #endif -}; + } + + return metadataKeys; +} CameraBinMetaData::CameraBinMetaData(QObject *parent) :QMetaDataWriterControl(parent) @@ -183,14 +198,9 @@ QVariant CameraBinMetaData::metaData(const QString &key) const return (metersPerSec * 3600) / 1000; } - static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); - - for (int i = 0; i < count; ++i) { - if (qt_gstreamerMetaDataKeys[i].key == key) { - const char *name = qt_gstreamerMetaDataKeys[i].token; - - return m_values.value(QByteArray::fromRawData(name, qstrlen(name))); - } + Q_FOREACH (const QGStreamerMetaDataKey &metadataKey, *qt_gstreamerMetaDataKeys()) { + if (metadataKey.qtName == key) + return m_values.value(QByteArray::fromRawData(metadataKey.gstName, qstrlen(metadataKey.gstName))); } return QVariant(); } @@ -207,14 +217,12 @@ void CameraBinMetaData::setMetaData(const QString &key, const QVariant &value) } } - static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); - - for (int i = 0; i < count; ++i) { - if (qt_gstreamerMetaDataKeys[i].key == key) { - const char *name = qt_gstreamerMetaDataKeys[i].token; + Q_FOREACH (const QGStreamerMetaDataKey &metadataKey, *qt_gstreamerMetaDataKeys()) { + if (metadataKey.qtName == key) { + const char *name = metadataKey.gstName; if (correctedValue.isValid()) { - correctedValue.convert(qt_gstreamerMetaDataKeys[i].type); + correctedValue.convert(metadataKey.type); m_values.insert(QByteArray::fromRawData(name, qstrlen(name)), correctedValue); } else { m_values.remove(QByteArray::fromRawData(name, qstrlen(name))); @@ -232,14 +240,12 @@ QStringList CameraBinMetaData::availableMetaData() const { static QMap keysMap; if (keysMap.isEmpty()) { - const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); - for (int i = 0; i < count; ++i) { - keysMap[QByteArray(qt_gstreamerMetaDataKeys[i].token)] = qt_gstreamerMetaDataKeys[i].key; - } + Q_FOREACH (const QGStreamerMetaDataKey &metadataKey, *qt_gstreamerMetaDataKeys()) + keysMap[QByteArray(metadataKey.gstName)] = metadataKey.qtName; } QStringList res; - foreach (const QByteArray &key, m_values.keys()) { + Q_FOREACH (const QByteArray &key, m_values.keys()) { QString tag = keysMap.value(key); if (!tag.isEmpty()) res.append(tag); diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.cpp index fd7fb7d82..1080a5875 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamercapturemetadatacontrol.cpp @@ -46,80 +46,82 @@ #include #include -struct QGstreamerMetaDataKeyLookup -{ - QString key; - const char *token; -}; -static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] = +typedef QMap QGstreamerMetaDataKeyLookup; +Q_GLOBAL_STATIC(QGstreamerMetaDataKeyLookup, metadataKeys) + +static const QGstreamerMetaDataKeyLookup *qt_gstreamerMetaDataKeys() { - { QMediaMetaData::Title, GST_TAG_TITLE }, - //{ QMediaMetaData::SubTitle, 0 }, - //{ QMediaMetaData::Author, 0 }, - { QMediaMetaData::Comment, GST_TAG_COMMENT }, - { QMediaMetaData::Description, GST_TAG_DESCRIPTION }, - //{ QMediaMetaData::Category, 0 }, - { QMediaMetaData::Genre, GST_TAG_GENRE }, - //{ QMediaMetaData::Year, 0 }, - //{ QMediaMetaData::UserRating, 0 }, - - { QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE }, - - { QMediaMetaData::Publisher, GST_TAG_ORGANIZATION }, - { QMediaMetaData::Copyright, GST_TAG_COPYRIGHT }, - //{ QMediaMetaData::ParentalRating, 0 }, - //{ QMediaMetaData::RatingOrganisation, 0 }, - - // Media - //{ QMediaMetaData::Size, 0 }, - //{ QMediaMetaData::MediaType, 0 }, - { QMediaMetaData::Duration, GST_TAG_DURATION }, - - // Audio - { QMediaMetaData::AudioBitRate, GST_TAG_BITRATE }, - { QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC }, - //{ QMediaMetaData::ChannelCount, 0 }, - //{ QMediaMetaData::SampleRate, 0 }, - - // Music - { QMediaMetaData::AlbumTitle, GST_TAG_ALBUM }, - { QMediaMetaData::AlbumArtist, GST_TAG_ARTIST}, - { QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER }, + if (metadataKeys->isEmpty()) { + metadataKeys->insert(QMediaMetaData::Title, GST_TAG_TITLE); + metadataKeys->insert(QMediaMetaData::SubTitle, 0); + //metadataKeys->insert(QMediaMetaData::Author, 0); + metadataKeys->insert(QMediaMetaData::Comment, GST_TAG_COMMENT); + metadataKeys->insert(QMediaMetaData::Description, GST_TAG_DESCRIPTION); + //metadataKeys->insert(QMediaMetaData::Category, 0); + metadataKeys->insert(QMediaMetaData::Genre, GST_TAG_GENRE); + //metadataKeys->insert(QMediaMetaData::Year, 0); + //metadataKeys->insert(QMediaMetaData::UserRating, 0); + + metadataKeys->insert(QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE); + + metadataKeys->insert(QMediaMetaData::Publisher, GST_TAG_ORGANIZATION); + metadataKeys->insert(QMediaMetaData::Copyright, GST_TAG_COPYRIGHT); + //metadataKeys->insert(QMediaMetaData::ParentalRating, 0); + //metadataKeys->insert(QMediaMetaData::RatingOrganisation, 0); + + // Media + //metadataKeys->insert(QMediaMetaData::Size, 0); + //metadataKeys->insert(QMediaMetaData::MediaType, 0); + metadataKeys->insert(QMediaMetaData::Duration, GST_TAG_DURATION); + + // Audio + metadataKeys->insert(QMediaMetaData::AudioBitRate, GST_TAG_BITRATE); + metadataKeys->insert(QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC); + //metadataKeys->insert(QMediaMetaData::ChannelCount, 0); + //metadataKeys->insert(QMediaMetaData::SampleRate, 0); + + // Music + metadataKeys->insert(QMediaMetaData::AlbumTitle, GST_TAG_ALBUM); + metadataKeys->insert(QMediaMetaData::AlbumArtist, GST_TAG_ARTIST); + metadataKeys->insert(QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER); #if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19) - { QMediaMetaData::Composer, GST_TAG_COMPOSER }, + metadataKeys->insert(QMediaMetaData::Composer, GST_TAG_COMPOSER); #endif - //{ QMediaMetaData::Conductor, 0 }, - //{ QMediaMetaData::Lyrics, 0 }, - //{ QMediaMetaData::Mood, 0 }, - { QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER }, - - //{ QMediaMetaData::CoverArtUrlSmall, 0 }, - //{ QMediaMetaData::CoverArtUrlLarge, 0 }, - - // Image/Video - //{ QMediaMetaData::Resolution, 0 }, - //{ QMediaMetaData::PixelAspectRatio, 0 }, - - // Video - //{ QMediaMetaData::VideoFrameRate, 0 }, - //{ QMediaMetaData::VideoBitRate, 0 }, - { QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC }, - - //{ QMediaMetaData::PosterUrl, 0 }, - - // Movie - //{ QMediaMetaData::ChapterNumber, 0 }, - //{ QMediaMetaData::Director, 0 }, - { QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER }, - //{ QMediaMetaData::Writer, 0 }, - - // Photos - //{ QMediaMetaData::CameraManufacturer, 0 }, - //{ QMediaMetaData::CameraModel, 0 }, - //{ QMediaMetaData::Event, 0 }, - //{ QMediaMetaData::Subject, 0 } -}; + //metadataKeys->insert(QMediaMetaData::Conductor, 0); + //metadataKeys->insert(QMediaMetaData::Lyrics, 0); + //metadataKeys->insert(QMediaMetaData::Mood, 0); + metadataKeys->insert(QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER); + + //metadataKeys->insert(QMediaMetaData::CoverArtUrlSmall, 0); + //metadataKeys->insert(QMediaMetaData::CoverArtUrlLarge, 0); + + // Image/Video + //metadataKeys->insert(QMediaMetaData::Resolution, 0); + //metadataKeys->insert(QMediaMetaData::PixelAspectRatio, 0); + + // Video + //metadataKeys->insert(QMediaMetaData::VideoFrameRate, 0); + //metadataKeys->insert(QMediaMetaData::VideoBitRate, 0); + metadataKeys->insert(QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC); + + //metadataKeys->insert(QMediaMetaData::PosterUrl, 0); + + // Movie + //metadataKeys->insert(QMediaMetaData::ChapterNumber, 0); + //metadataKeys->insert(QMediaMetaData::Director, 0); + metadataKeys->insert(QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER); + //metadataKeys->insert(QMediaMetaData::Writer, 0); + + // Photos + //metadataKeys->insert(QMediaMetaData::CameraManufacturer, 0); + //metadataKeys->insert(QMediaMetaData::CameraModel, 0); + //metadataKeys->insert(QMediaMetaData::Event, 0); + //metadataKeys->insert(QMediaMetaData::Subject, 0 } + } + + return metadataKeys; +} QGstreamerCaptureMetaDataControl::QGstreamerCaptureMetaDataControl(QObject *parent) :QMetaDataWriterControl(parent) @@ -128,50 +130,30 @@ QGstreamerCaptureMetaDataControl::QGstreamerCaptureMetaDataControl(QObject *pare QVariant QGstreamerCaptureMetaDataControl::metaData(const QString &key) const { - static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); - - for (int i = 0; i < count; ++i) { - if (qt_gstreamerMetaDataKeys[i].key == key) { - const char *name = qt_gstreamerMetaDataKeys[i].token; + QGstreamerMetaDataKeyLookup::const_iterator it = qt_gstreamerMetaDataKeys()->find(key); + if (it != qt_gstreamerMetaDataKeys()->constEnd()) + return m_values.value(it.value()); - return m_values.value(QByteArray::fromRawData(name, qstrlen(name))); - } - } return QVariant(); } void QGstreamerCaptureMetaDataControl::setMetaData(const QString &key, const QVariant &value) { - static const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); - - for (int i = 0; i < count; ++i) { - if (qt_gstreamerMetaDataKeys[i].key == key) { - const char *name = qt_gstreamerMetaDataKeys[i].token; - - m_values.insert(QByteArray::fromRawData(name, qstrlen(name)), value); + QGstreamerMetaDataKeyLookup::const_iterator it = qt_gstreamerMetaDataKeys()->find(key); + if (it != qt_gstreamerMetaDataKeys()->constEnd()) { + m_values.insert(it.value(), value); - emit QMetaDataWriterControl::metaDataChanged(); - emit QMetaDataWriterControl::metaDataChanged(key, value); - emit metaDataChanged(m_values); - - return; - } + emit QMetaDataWriterControl::metaDataChanged(); + emit QMetaDataWriterControl::metaDataChanged(key, value); + emit metaDataChanged(m_values); } } QStringList QGstreamerCaptureMetaDataControl::availableMetaData() const { - static QMap keysMap; - if (keysMap.isEmpty()) { - const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); - for (int i = 0; i < count; ++i) { - keysMap[QByteArray(qt_gstreamerMetaDataKeys[i].token)] = qt_gstreamerMetaDataKeys[i].key; - } - } - QStringList res; foreach (const QByteArray &key, m_values.keys()) { - QString tag = keysMap.value(key); + QString tag = qt_gstreamerMetaDataKeys()->key(key); if (!tag.isEmpty()) res.append(tag); } diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp index fa837d3f4..88faf607c 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.cpp @@ -48,90 +48,86 @@ QT_BEGIN_NAMESPACE -struct QGstreamerMetaDataKeyLookup -{ - QString key; - const char *token; -}; +typedef QMap QGstreamerMetaDataKeyLookup; +Q_GLOBAL_STATIC(QGstreamerMetaDataKeyLookup, metadataKeys) -static const QGstreamerMetaDataKeyLookup qt_gstreamerMetaDataKeys[] = +static const QGstreamerMetaDataKeyLookup *qt_gstreamerMetaDataKeys() { - { QMediaMetaData::Title, GST_TAG_TITLE }, - //{ QMediaMetaData::SubTitle, 0 }, - //{ QMediaMetaData::Author, 0 }, - { QMediaMetaData::Comment, GST_TAG_COMMENT }, - { QMediaMetaData::Description, GST_TAG_DESCRIPTION }, - //{ QMediaMetaData::Category, 0 }, - { QMediaMetaData::Genre, GST_TAG_GENRE }, - { QMediaMetaData::Year, "year" }, - //{ QMediaMetaData::UserRating, 0 }, - - { QMediaMetaData::Language, GST_TAG_LANGUAGE_CODE }, - - { QMediaMetaData::Publisher, GST_TAG_ORGANIZATION }, - { QMediaMetaData::Copyright, GST_TAG_COPYRIGHT }, - //{ QMediaMetaData::ParentalRating, 0 }, - //{ QMediaMetaData::RatingOrganisation, 0 }, - - // Media - //{ QMediaMetaData::Size, 0 }, - //{ QMediaMetaData::MediaType, 0 }, - { QMediaMetaData::Duration, GST_TAG_DURATION }, - - // Audio - { QMediaMetaData::AudioBitRate, GST_TAG_BITRATE }, - { QMediaMetaData::AudioCodec, GST_TAG_AUDIO_CODEC }, - //{ QMediaMetaData::ChannelCount, 0 }, - //{ QMediaMetaData::SampleRate, 0 }, - - // Music - { QMediaMetaData::AlbumTitle, GST_TAG_ALBUM }, - { QMediaMetaData::AlbumArtist, GST_TAG_ARTIST}, - { QMediaMetaData::ContributingArtist, GST_TAG_PERFORMER }, + if (metadataKeys->isEmpty()) { + metadataKeys->insert(GST_TAG_TITLE, QMediaMetaData::Title); + //metadataKeys->insert(0, QMediaMetaData::SubTitle); + //metadataKeys->insert(0, QMediaMetaData::Author); + metadataKeys->insert(GST_TAG_COMMENT, QMediaMetaData::Comment); + metadataKeys->insert(GST_TAG_DESCRIPTION, QMediaMetaData::Description); + //metadataKeys->insert(0, QMediaMetaData::Category); + metadataKeys->insert(GST_TAG_GENRE, QMediaMetaData::Genre); + metadataKeys->insert("year", QMediaMetaData::Year); + //metadataKeys->insert(0, QMediaMetaData::UserRating); + + metadataKeys->insert(GST_TAG_LANGUAGE_CODE, QMediaMetaData::Language); + + metadataKeys->insert(GST_TAG_ORGANIZATION, QMediaMetaData::Publisher); + metadataKeys->insert(GST_TAG_COPYRIGHT, QMediaMetaData::Copyright); + //metadataKeys->insert(0, QMediaMetaData::ParentalRating); + //metadataKeys->insert(0, QMediaMetaData::RatingOrganisation); + + // Media + //metadataKeys->insert(0, QMediaMetaData::Size); + //metadataKeys->insert(0,QMediaMetaData::MediaType ); + metadataKeys->insert(GST_TAG_DURATION, QMediaMetaData::Duration); + + // Audio + metadataKeys->insert(GST_TAG_BITRATE, QMediaMetaData::AudioBitRate); + metadataKeys->insert(GST_TAG_AUDIO_CODEC, QMediaMetaData::AudioCodec); + //metadataKeys->insert(0, QMediaMetaData::ChannelCount); + //metadataKeys->insert(0, QMediaMetaData::SampleRate); + + // Music + metadataKeys->insert(GST_TAG_ALBUM, QMediaMetaData::AlbumTitle); + metadataKeys->insert(GST_TAG_ARTIST, QMediaMetaData::AlbumArtist); + metadataKeys->insert(GST_TAG_PERFORMER, QMediaMetaData::ContributingArtist); #if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 19) - { QMediaMetaData::Composer, GST_TAG_COMPOSER }, + metadataKeys->insert(GST_TAG_COMPOSER, QMediaMetaData::Composer); #endif - //{ QMediaMetaData::Conductor, 0 }, - //{ QMediaMetaData::Lyrics, 0 }, - //{ QMediaMetaData::Mood, 0 }, - { QMediaMetaData::TrackNumber, GST_TAG_TRACK_NUMBER }, - - //{ QMediaMetaData::CoverArtUrlSmall, 0 }, - //{ QMediaMetaData::CoverArtUrlLarge, 0 }, - - // Image/Video - { QMediaMetaData::Resolution, "resolution" }, - { QMediaMetaData::PixelAspectRatio, "pixel-aspect-ratio" }, - - // Video - //{ QMediaMetaData::VideoFrameRate, 0 }, - //{ QMediaMetaData::VideoBitRate, 0 }, - { QMediaMetaData::VideoCodec, GST_TAG_VIDEO_CODEC }, - - //{ QMediaMetaData::PosterUrl, 0 }, - - // Movie - //{ QMediaMetaData::ChapterNumber, 0 }, - //{ QMediaMetaData::Director, 0 }, - { QMediaMetaData::LeadPerformer, GST_TAG_PERFORMER }, - //{ QMediaMetaData::Writer, 0 }, - - // Photos - //{ QMediaMetaData::CameraManufacturer, 0 }, - //{ QMediaMetaData::CameraModel, 0 }, - //{ QMediaMetaData::Event, 0 }, - //{ QMediaMetaData::Subject, 0 } -}; + //metadataKeys->insert(0, QMediaMetaData::Conductor); + //metadataKeys->insert(0, QMediaMetaData::Lyrics); + //metadataKeys->insert(0, QMediaMetaData::Mood); + metadataKeys->insert(GST_TAG_TRACK_NUMBER, QMediaMetaData::TrackNumber); + + //metadataKeys->insert(0, QMediaMetaData::CoverArtUrlSmall); + //metadataKeys->insert(0, QMediaMetaData::CoverArtUrlLarge); + + // Image/Video + metadataKeys->insert("resolution", QMediaMetaData::Resolution); + metadataKeys->insert("pixel-aspect-ratio", QMediaMetaData::PixelAspectRatio); + + // Video + //metadataKeys->insert(0, QMediaMetaData::VideoFrameRate); + //metadataKeys->insert(0, QMediaMetaData::VideoBitRate); + metadataKeys->insert(GST_TAG_VIDEO_CODEC, QMediaMetaData::VideoCodec); + + //metadataKeys->insert(0, QMediaMetaData::PosterUrl); + + // Movie + //metadataKeys->insert(0, QMediaMetaData::ChapterNumber); + //metadataKeys->insert(0, QMediaMetaData::Director); + metadataKeys->insert(GST_TAG_PERFORMER, QMediaMetaData::LeadPerformer); + //metadataKeys->insert(0, QMediaMetaData::Writer); + + // Photos + //metadataKeys->insert(0, QMediaMetaData::CameraManufacturer); + //metadataKeys->insert(0, QMediaMetaData::CameraModel); + //metadataKeys->insert(0, QMediaMetaData::Event); + //metadataKeys->insert(0, QMediaMetaData::Subject); + } + + return metadataKeys; +} QGstreamerMetaDataProvider::QGstreamerMetaDataProvider(QGstreamerPlayerSession *session, QObject *parent) :QMetaDataReaderControl(parent), m_session(session) { connect(m_session, SIGNAL(tagsChanged()), SLOT(updateTags())); - - const int count = sizeof(qt_gstreamerMetaDataKeys) / sizeof(QGstreamerMetaDataKeyLookup); - for (int i = 0; i < count; ++i) { - m_keysMap[QByteArray(qt_gstreamerMetaDataKeys[i].token)] = qt_gstreamerMetaDataKeys[i].key; - } } QGstreamerMetaDataProvider::~QGstreamerMetaDataProvider() @@ -167,8 +163,8 @@ void QGstreamerMetaDataProvider::updateTags() QMapIterator i(m_session->tags()); while (i.hasNext()) { i.next(); - //use gstreamer native keys for elements not in m_keysMap - QString key = m_keysMap.value(i.key(), i.key()); + //use gstreamer native keys for elements not in our key map + QString key = qt_gstreamerMetaDataKeys()->value(i.key(), i.key()); m_tags.insert(key, i.value()); if (i.value() != oldTags.value(key)) { changed = true; diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.h b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.h index e36c127ad..7b3b266fa 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.h +++ b/src/plugins/gstreamer/mediaplayer/qgstreamermetadataprovider.h @@ -67,7 +67,6 @@ private slots: private: QGstreamerPlayerSession *m_session; QVariantMap m_tags; - QMap m_keysMap; }; QT_END_NAMESPACE -- cgit v1.2.3 From b99a4b3025f08df8f33efb02897397ae5e404acf Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 3 Jun 2014 16:50:56 +0200 Subject: Make multimedia QML types available for the 5.3 import version. At least one type needs to be registered with the 5.3 version number to make it known to the QML engine. Change-Id: Iacfe62650b4194fbb89135fef7cb148309227ce2 Reviewed-by: Alan Alpert (Personal) <416365416c@gmail.com> --- src/imports/multimedia/multimedia.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/imports/multimedia/multimedia.cpp b/src/imports/multimedia/multimedia.cpp index 94b697e85..5954db22c 100644 --- a/src/imports/multimedia/multimedia.cpp +++ b/src/imports/multimedia/multimedia.cpp @@ -95,6 +95,11 @@ public: qmlRegisterUncreatableType(uri, 5, 0, "CameraImageProcessing", trUtf8("CameraImageProcessing is provided by Camera")); + // Make types available for the 5.3 version + // Adding "import QtMultimedia 5.3" in QML will fail unless at least one type is registered + // for that version. + qmlRegisterType(uri, 5, 3, "SoundEffect"); + qmlRegisterType(); } -- cgit v1.2.3