summaryrefslogtreecommitdiffstats
path: root/src/plugins/android/src/wrappers
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@theqtcompany.com>2015-09-24 16:58:36 +0200
committerYoann Lopes <yoann.lopes@theqtcompany.com>2015-12-04 11:41:25 +0000
commit8debbfbc9b7fe035362afc3838e7cec595efb394 (patch)
tree8005f427792db96e33b8100fa72e27cdf1a3e26e /src/plugins/android/src/wrappers
parentece9005efe62b297ada062411d255200c7ff124e (diff)
Android: support non OpenGL video surfaces for the camera.
QCamera can now pass raw frame data to its QAbstractVideoSurface. The now deprecated Android camera API we're using doesn't allow to get frame data without also displaying the frames in a SurfaceView or a SurfaceTexture. To work around that, an invisible dummy SurfaceView is used. This allows to retrieve frames in the NV21, YV12, YUY2 or RGB565 formats, depending on the Android version and on the device. Task-number: QTBUG-35416 Change-Id: I77b4f50505c3b91efb4b2288a57f50398922c0db Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com> Reviewed-by: Yoann Lopes <yoann.lopes@theqtcompany.com>
Diffstat (limited to 'src/plugins/android/src/wrappers')
-rw-r--r--src/plugins/android/src/wrappers/jni/androidcamera.cpp87
-rw-r--r--src/plugins/android/src/wrappers/jni/androidcamera.h11
-rw-r--r--src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp204
-rw-r--r--src/plugins/android/src/wrappers/jni/androidsurfaceview.h101
-rw-r--r--src/plugins/android/src/wrappers/jni/jni.pri6
5 files changed, 396 insertions, 13 deletions
diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.cpp b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
index 1fe0e666e..083803e38 100644
--- a/src/plugins/android/src/wrappers/jni/androidcamera.cpp
+++ b/src/plugins/android/src/wrappers/jni/androidcamera.cpp
@@ -33,6 +33,7 @@
#include "androidcamera.h"
#include "androidsurfacetexture.h"
+#include "androidsurfaceview.h"
#include "qandroidmultimediautils.h"
#include <qstringlist.h>
@@ -41,6 +42,7 @@
#include <QtCore/qthread.h>
#include <QtCore/qreadwritelock.h>
#include <QtCore/qmutex.h>
+#include <QtMultimedia/private/qmemoryvideobuffer_p.h>
QT_BEGIN_NAMESPACE
@@ -121,7 +123,8 @@ static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data)
Q_EMIT (*it)->pictureCaptured(bytes);
}
-static void notifyNewPreviewFrame(JNIEnv *env, jobject, int id, jbyteArray data, int width, int height)
+static void notifyNewPreviewFrame(JNIEnv *env, jobject, int id, jbyteArray data,
+ int width, int height, int format, int bpl)
{
QReadLocker locker(rwLock);
const auto it = cameras->constFind(id);
@@ -129,10 +132,17 @@ static void notifyNewPreviewFrame(JNIEnv *env, jobject, int id, jbyteArray data,
return;
const int arrayLength = env->GetArrayLength(data);
+ if (arrayLength == 0)
+ return;
+
QByteArray bytes(arrayLength, Qt::Uninitialized);
env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data());
- Q_EMIT (*it)->newPreviewFrame(bytes, width, height);
+ QVideoFrame frame(new QMemoryVideoBuffer(bytes, bpl),
+ QSize(width, height),
+ qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat(format)));
+
+ Q_EMIT (*it)->newPreviewFrame(frame);
}
class AndroidCameraPrivate : public QObject
@@ -157,10 +167,12 @@ public:
Q_INVOKABLE AndroidCamera::ImageFormat getPreviewFormat();
Q_INVOKABLE void setPreviewFormat(AndroidCamera::ImageFormat fmt);
+ Q_INVOKABLE QList<AndroidCamera::ImageFormat> getSupportedPreviewFormats();
Q_INVOKABLE QSize previewSize() const { return m_previewSize; }
Q_INVOKABLE void updatePreviewSize();
Q_INVOKABLE bool setPreviewTexture(void *surfaceTexture);
+ Q_INVOKABLE bool setPreviewDisplay(void *surfaceHolder);
Q_INVOKABLE bool isZoomSupported();
Q_INVOKABLE int getMaxZoom();
@@ -238,7 +250,7 @@ Q_SIGNALS:
void whiteBalanceChanged();
- void lastPreviewFrameFetched(const QByteArray &preview, int width, int height);
+ void lastPreviewFrameFetched(const QVideoFrame &frame);
};
AndroidCamera::AndroidCamera(AndroidCameraPrivate *d, QThread *worker)
@@ -250,6 +262,7 @@ AndroidCamera::AndroidCamera(AndroidCameraPrivate *d, QThread *worker)
qRegisterMetaType<QList<int> >();
qRegisterMetaType<QList<QSize> >();
qRegisterMetaType<QList<QRect> >();
+ qRegisterMetaType<ImageFormat>();
connect(d, &AndroidCameraPrivate::previewSizeChanged, this, &AndroidCamera::previewSizeChanged);
connect(d, &AndroidCameraPrivate::previewStarted, this, &AndroidCamera::previewStarted);
@@ -368,6 +381,12 @@ void AndroidCamera::setPreviewFormat(ImageFormat fmt)
QMetaObject::invokeMethod(d, "setPreviewFormat", Q_ARG(AndroidCamera::ImageFormat, fmt));
}
+QList<AndroidCamera::ImageFormat> AndroidCamera::getSupportedPreviewFormats()
+{
+ Q_D(AndroidCamera);
+ return d->getSupportedPreviewFormats();
+}
+
QSize AndroidCamera::previewSize() const
{
Q_D(const AndroidCamera);
@@ -399,6 +418,18 @@ bool AndroidCamera::setPreviewTexture(AndroidSurfaceTexture *surfaceTexture)
return ok;
}
+bool AndroidCamera::setPreviewDisplay(AndroidSurfaceHolder *surfaceHolder)
+{
+ Q_D(AndroidCamera);
+ bool ok = true;
+ QMetaObject::invokeMethod(d,
+ "setPreviewDisplay",
+ Qt::BlockingQueuedConnection,
+ Q_RETURN_ARG(bool, ok),
+ Q_ARG(void *, surfaceHolder ? surfaceHolder->surfaceHolder() : 0));
+ return ok;
+}
+
bool AndroidCamera::isZoomSupported()
{
Q_D(AndroidCamera);
@@ -834,7 +865,7 @@ AndroidCamera::ImageFormat AndroidCameraPrivate::getPreviewFormat()
QMutexLocker parametersLocker(&m_parametersMutex);
if (!m_parameters.isValid())
- return AndroidCamera::Unknown;
+ return AndroidCamera::UnknownImageFormat;
return AndroidCamera::ImageFormat(m_parameters.callMethod<jint>("getPreviewFormat"));
}
@@ -850,6 +881,27 @@ void AndroidCameraPrivate::setPreviewFormat(AndroidCamera::ImageFormat fmt)
applyParameters();
}
+QList<AndroidCamera::ImageFormat> AndroidCameraPrivate::getSupportedPreviewFormats()
+{
+ QList<AndroidCamera::ImageFormat> list;
+
+ QMutexLocker parametersLocker(&m_parametersMutex);
+
+ if (m_parameters.isValid()) {
+ QJNIObjectPrivate formatList = m_parameters.callObjectMethod("getSupportedPreviewFormats",
+ "()Ljava/util/List;");
+ int count = formatList.callMethod<jint>("size");
+ for (int i = 0; i < count; ++i) {
+ QJNIObjectPrivate format = formatList.callObjectMethod("get",
+ "(I)Ljava/lang/Object;",
+ i);
+ list.append(AndroidCamera::ImageFormat(format.callMethod<jint>("intValue")));
+ }
+ }
+
+ return list;
+}
+
void AndroidCameraPrivate::updatePreviewSize()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -871,6 +923,15 @@ bool AndroidCameraPrivate::setPreviewTexture(void *surfaceTexture)
return !exceptionCheckAndClear(env);
}
+bool AndroidCameraPrivate::setPreviewDisplay(void *surfaceHolder)
+{
+ QJNIEnvironmentPrivate env;
+ m_camera.callMethod<void>("setPreviewDisplay",
+ "(Landroid/view/SurfaceHolder;)V",
+ static_cast<jobject>(surfaceHolder));
+ return !exceptionCheckAndClear(env);
+}
+
bool AndroidCameraPrivate::isZoomSupported()
{
QMutexLocker parametersLocker(&m_parametersMutex);
@@ -1361,15 +1422,25 @@ void AndroidCameraPrivate::fetchLastPreviewFrame()
return;
const int arrayLength = env->GetArrayLength(static_cast<jbyteArray>(data.object()));
+ if (arrayLength == 0)
+ return;
+
QByteArray bytes(arrayLength, Qt::Uninitialized);
env->GetByteArrayRegion(static_cast<jbyteArray>(data.object()),
0,
arrayLength,
reinterpret_cast<jbyte *>(bytes.data()));
- emit lastPreviewFrameFetched(bytes,
- m_cameraListener.callMethod<jint>("previewWidth"),
- m_cameraListener.callMethod<jint>("previewHeight"));
+ const int width = m_cameraListener.callMethod<jint>("previewWidth");
+ const int height = m_cameraListener.callMethod<jint>("previewHeight");
+ const int format = m_cameraListener.callMethod<jint>("previewFormat");
+ const int bpl = m_cameraListener.callMethod<jint>("previewBytesPerLine");
+
+ QVideoFrame frame(new QMemoryVideoBuffer(bytes, bpl),
+ QSize(width, height),
+ qt_pixelFormatFromAndroidImageFormat(AndroidCamera::ImageFormat(format)));
+
+ emit lastPreviewFrameFetched(frame);
}
void AndroidCameraPrivate::applyParameters()
@@ -1414,7 +1485,7 @@ bool AndroidCamera::initJNI(JNIEnv *env)
{"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete},
{"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed},
{"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured},
- {"notifyNewPreviewFrame", "(I[BII)V", (void *)notifyNewPreviewFrame}
+ {"notifyNewPreviewFrame", "(I[BIIII)V", (void *)notifyNewPreviewFrame}
};
if (clazz && env->RegisterNatives(clazz,
diff --git a/src/plugins/android/src/wrappers/jni/androidcamera.h b/src/plugins/android/src/wrappers/jni/androidcamera.h
index 7a8ae8b23..9e4c387c4 100644
--- a/src/plugins/android/src/wrappers/jni/androidcamera.h
+++ b/src/plugins/android/src/wrappers/jni/androidcamera.h
@@ -46,6 +46,7 @@ class QThread;
class AndroidCameraPrivate;
class AndroidSurfaceTexture;
+class AndroidSurfaceHolder;
struct AndroidCameraInfo
{
@@ -67,7 +68,7 @@ public:
};
enum ImageFormat { // same values as in android.graphics.ImageFormat Java class
- Unknown = 0,
+ UnknownImageFormat = 0,
RGB565 = 4,
NV16 = 16,
NV21 = 17,
@@ -95,10 +96,12 @@ public:
ImageFormat getPreviewFormat();
void setPreviewFormat(ImageFormat fmt);
+ QList<ImageFormat> getSupportedPreviewFormats();
QSize previewSize() const;
void setPreviewSize(const QSize &size);
bool setPreviewTexture(AndroidSurfaceTexture *surfaceTexture);
+ bool setPreviewDisplay(AndroidSurfaceHolder *surfaceHolder);
bool isZoomSupported();
int getMaxZoom();
@@ -177,8 +180,8 @@ Q_SIGNALS:
void pictureExposed();
void pictureCaptured(const QByteArray &data);
- void lastPreviewFrameFetched(const QByteArray &preview, int width, int height);
- void newPreviewFrame(const QByteArray &frame, int width, int height);
+ void lastPreviewFrameFetched(const QVideoFrame &frame);
+ void newPreviewFrame(const QVideoFrame &frame);
private:
AndroidCamera(AndroidCameraPrivate *d, QThread *worker);
@@ -188,6 +191,8 @@ private:
QScopedPointer<QThread> m_worker;
};
+Q_DECLARE_METATYPE(AndroidCamera::ImageFormat)
+
QT_END_NAMESPACE
#endif // ANDROIDCAMERA_H
diff --git a/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp b/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp
new file mode 100644
index 000000000..67560baf4
--- /dev/null
+++ b/src/plugins/android/src/wrappers/jni/androidsurfaceview.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "androidsurfaceview.h"
+
+#include <QtCore/private/qjnihelpers_p.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qmutex.h>
+#include <QtGui/qwindow.h>
+
+QT_BEGIN_NAMESPACE
+
+static const char QtSurfaceHolderCallbackClassName[] = "org/qtproject/qt5/android/multimedia/QtSurfaceHolderCallback";
+typedef QVector<AndroidSurfaceHolder *> SurfaceHolders;
+Q_GLOBAL_STATIC(SurfaceHolders, surfaceHolders)
+Q_GLOBAL_STATIC(QMutex, shLock)
+
+AndroidSurfaceHolder::AndroidSurfaceHolder(QJNIObjectPrivate object)
+ : m_surfaceHolder(object)
+ , m_surfaceCreated(false)
+{
+ if (!m_surfaceHolder.isValid())
+ return;
+
+ {
+ QMutexLocker locker(shLock);
+ surfaceHolders->append(this);
+ }
+
+ QJNIObjectPrivate callback(QtSurfaceHolderCallbackClassName, "(J)V", reinterpret_cast<jlong>(this));
+ m_surfaceHolder.callMethod<void>("addCallback",
+ "(Landroid/view/SurfaceHolder$Callback;)V",
+ callback.object());
+}
+
+AndroidSurfaceHolder::~AndroidSurfaceHolder()
+{
+ QMutexLocker locker(shLock);
+ const int i = surfaceHolders->indexOf(this);
+ if (Q_UNLIKELY(i == -1))
+ return;
+
+ surfaceHolders->remove(i);
+}
+
+jobject AndroidSurfaceHolder::surfaceHolder() const
+{
+ return m_surfaceHolder.object();
+}
+
+bool AndroidSurfaceHolder::isSurfaceCreated() const
+{
+ QMutexLocker locker(shLock);
+ return m_surfaceCreated;
+}
+
+void AndroidSurfaceHolder::handleSurfaceCreated(JNIEnv*, jobject, jlong id)
+{
+ QMutexLocker locker(shLock);
+ const int i = surfaceHolders->indexOf(reinterpret_cast<AndroidSurfaceHolder *>(id));
+ if (Q_UNLIKELY(i == -1))
+ return;
+
+ (*surfaceHolders)[i]->m_surfaceCreated = true;
+ Q_EMIT (*surfaceHolders)[i]->surfaceCreated();
+}
+
+void AndroidSurfaceHolder::handleSurfaceDestroyed(JNIEnv*, jobject, jlong id)
+{
+ QMutexLocker locker(shLock);
+ const int i = surfaceHolders->indexOf(reinterpret_cast<AndroidSurfaceHolder *>(id));
+ if (Q_UNLIKELY(i == -1))
+ return;
+
+ (*surfaceHolders)[i]->m_surfaceCreated = false;
+}
+
+bool AndroidSurfaceHolder::initJNI(JNIEnv *env)
+{
+ jclass clazz = QJNIEnvironmentPrivate::findClass(QtSurfaceHolderCallbackClassName,
+ env);
+
+ static const JNINativeMethod methods[] = {
+ {"notifySurfaceCreated", "(J)V", (void *)AndroidSurfaceHolder::handleSurfaceCreated},
+ {"notifySurfaceDestroyed", "(J)V", (void *)AndroidSurfaceHolder::handleSurfaceDestroyed}
+ };
+
+ if (clazz && env->RegisterNatives(clazz,
+ methods,
+ sizeof(methods) / sizeof(methods[0])) != JNI_OK) {
+ return false;
+ }
+
+ return true;
+}
+
+AndroidSurfaceView::AndroidSurfaceView()
+ : m_window(0)
+ , m_surfaceHolder(0)
+ , m_pendingVisible(-1)
+{
+ setAutoDelete(false);
+ QtAndroidPrivate::runOnUiThread(this, QJNIEnvironmentPrivate());
+}
+
+AndroidSurfaceView::~AndroidSurfaceView()
+{
+ delete m_surfaceHolder;
+ delete m_window;
+}
+
+AndroidSurfaceHolder *AndroidSurfaceView::holder() const
+{
+ return m_surfaceHolder;
+}
+
+void AndroidSurfaceView::setVisible(bool v)
+{
+ if (m_window)
+ m_window->setVisible(v);
+ else
+ m_pendingVisible = int(v);
+}
+
+void AndroidSurfaceView::setGeometry(int x, int y, int width, int height)
+{
+ if (m_window)
+ m_window->setGeometry(x, y, width, height);
+ else
+ m_pendingGeometry = QRect(x, y, width, height);
+}
+
+bool AndroidSurfaceView::event(QEvent *e)
+{
+ if (e->type() == QEvent::User) {
+ Q_ASSERT(m_surfaceView.isValid());
+
+ QJNIObjectPrivate holder = m_surfaceView.callObjectMethod("getHolder",
+ "()Landroid/view/SurfaceHolder;");
+ if (!holder.isValid()) {
+ m_surfaceView = QJNIObjectPrivate();
+ } else {
+ m_surfaceHolder = new AndroidSurfaceHolder(holder);
+ connect(m_surfaceHolder, &AndroidSurfaceHolder::surfaceCreated,
+ this, &AndroidSurfaceView::surfaceCreated);
+ { // Lock now to avoid a race with handleSurfaceCreated()
+ QMutexLocker locker(shLock);
+ m_window = QWindow::fromWinId(WId(m_surfaceView.object()));
+
+ if (m_pendingVisible != -1)
+ m_window->setVisible(m_pendingVisible);
+ if (m_pendingGeometry.isValid())
+ m_window->setGeometry(m_pendingGeometry);
+ }
+ }
+
+ return true;
+ }
+
+ return QObject::event(e);
+}
+
+// Called on the Android UI thread.
+void AndroidSurfaceView::run()
+{
+ m_surfaceView = QJNIObjectPrivate("android/view/SurfaceView",
+ "(Landroid/content/Context;)V",
+ QtAndroidPrivate::activity());
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/android/src/wrappers/jni/androidsurfaceview.h b/src/plugins/android/src/wrappers/jni/androidsurfaceview.h
new file mode 100644
index 000000000..661a5959f
--- /dev/null
+++ b/src/plugins/android/src/wrappers/jni/androidsurfaceview.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDSURFACEVIEW_H
+#define ANDROIDSURFACEVIEW_H
+
+#include <QtCore/private/qjni_p.h>
+#include <qrect.h>
+#include <QtCore/qrunnable.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindow;
+
+class AndroidSurfaceHolder : public QObject
+{
+ Q_OBJECT
+public:
+ ~AndroidSurfaceHolder();
+
+ jobject surfaceHolder() const;
+ bool isSurfaceCreated() const;
+
+ static bool initJNI(JNIEnv *env);
+
+Q_SIGNALS:
+ void surfaceCreated();
+
+private:
+ AndroidSurfaceHolder(QJNIObjectPrivate object);
+
+ static void handleSurfaceCreated(JNIEnv*, jobject, jlong id);
+ static void handleSurfaceDestroyed(JNIEnv*, jobject, jlong id);
+
+ QJNIObjectPrivate m_surfaceHolder;
+ bool m_surfaceCreated;
+
+ friend class AndroidSurfaceView;
+};
+
+class AndroidSurfaceView : public QObject, public QRunnable
+{
+ Q_OBJECT
+public:
+ AndroidSurfaceView();
+ ~AndroidSurfaceView();
+
+ AndroidSurfaceHolder *holder() const;
+
+ void setVisible(bool v);
+ void setGeometry(int x, int y, int width, int height);
+
+ bool event(QEvent *);
+
+Q_SIGNALS:
+ void surfaceCreated();
+
+protected:
+ void run() override;
+
+private:
+ QJNIObjectPrivate m_surfaceView;
+ QWindow *m_window;
+ AndroidSurfaceHolder *m_surfaceHolder;
+ int m_pendingVisible;
+ QRect m_pendingGeometry;
+};
+
+QT_END_NAMESPACE
+
+#endif // ANDROIDSURFACEVIEW_H
diff --git a/src/plugins/android/src/wrappers/jni/jni.pri b/src/plugins/android/src/wrappers/jni/jni.pri
index e96baff1c..930d7e922 100644
--- a/src/plugins/android/src/wrappers/jni/jni.pri
+++ b/src/plugins/android/src/wrappers/jni/jni.pri
@@ -8,7 +8,8 @@ HEADERS += \
$$PWD/androidmediametadataretriever.h \
$$PWD/androidcamera.h \
$$PWD/androidmultimediautils.h \
- $$PWD/androidmediarecorder.h
+ $$PWD/androidmediarecorder.h \
+ $$PWD/androidsurfaceview.h
SOURCES += \
$$PWD/androidmediaplayer.cpp \
@@ -16,4 +17,5 @@ SOURCES += \
$$PWD/androidmediametadataretriever.cpp \
$$PWD/androidcamera.cpp \
$$PWD/androidmultimediautils.cpp \
- $$PWD/androidmediarecorder.cpp
+ $$PWD/androidmediarecorder.cpp \
+ $$PWD/androidsurfaceview.cpp