summaryrefslogtreecommitdiffstats
path: root/src/plugins/android/src
diff options
context:
space:
mode:
authorDenis Kormalev <kormalev.denis@gmail.com>2013-12-05 17:09:07 +0400
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-11 18:25:57 +0100
commitecce937a054e4a96597cb13c40d216bddbd45891 (patch)
tree7d6702cc83ae3558e9be374bf740ff6a42353323 /src/plugins/android/src
parent29ded57cef22d0a6d92f813d0a77637623d7b670 (diff)
Android: fix camera preview
At some(?) devices we can't rely on one shot preview callback because it receives data only after we start new previewing session. And this cause situation when imageCaptured signal is never emitted. This fix applies preview callback with already allocated buffers and collects all preview images in these buffers. When we capture image - we can simply fetch last preview image (if there was any) from c++ part. Task-number: QTBUG-34993 Change-Id: I608750c344ca3c089f4673df4907e0f47e57e2ba Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
Diffstat (limited to 'src/plugins/android/src')
-rw-r--r--src/plugins/android/src/mediacapture/qandroidcamerasession.cpp20
-rw-r--r--src/plugins/android/src/mediacapture/qandroidcamerasession.h1
-rw-r--r--src/plugins/android/src/wrappers/jcamera.cpp35
-rw-r--r--src/plugins/android/src/wrappers/jcamera.h6
4 files changed, 26 insertions, 36 deletions
diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
index 5ff19d1c1..55065cb46 100644
--- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
+++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
@@ -183,7 +183,6 @@ bool QAndroidCameraSession::open()
if (m_camera) {
connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed()));
connect(m_camera, SIGNAL(pictureCaptured(QByteArray)), this, SLOT(onCameraPictureCaptured(QByteArray)));
- connect(m_camera, SIGNAL(previewFrameAvailable(QByteArray)), this, SLOT(onCameraPreviewFrameAvailable(QByteArray)));
m_nativeOrientation = m_camera->getNativeOrientation();
@@ -484,7 +483,6 @@ int QAndroidCameraSession::capture(const QString &fileName)
// adjust picture rotation depending on the device orientation
m_camera->setRotation(currentCameraRotation());
- m_camera->requestPreviewFrame();
m_camera->takePicture();
} else {
//: Drive mode is the camera's shutter mode, for example single shot, continuos exposure, etc.
@@ -509,6 +507,13 @@ void QAndroidCameraSession::onCameraPictureExposed()
return;
emit imageExposed(m_currentImageCaptureId);
+ QByteArray lastFrame = m_camera->fetchLastPreviewFrame();
+ if (lastFrame.size()) {
+ QtConcurrent::run(this, &QAndroidCameraSession::processPreviewImage,
+ m_currentImageCaptureId,
+ lastFrame,
+ m_camera->getRotation());
+ }
}
void QAndroidCameraSession::onCameraPictureCaptured(const QByteArray &data)
@@ -571,17 +576,6 @@ void QAndroidCameraSession::processCapturedImage(int id,
}
}
-void QAndroidCameraSession::onCameraPreviewFrameAvailable(const QByteArray &data)
-{
- if (m_captureCanceled || m_readyForCapture)
- return;
-
- QtConcurrent::run(this, &QAndroidCameraSession::processPreviewImage,
- m_currentImageCaptureId,
- data,
- m_camera->getRotation());
-}
-
void QAndroidCameraSession::processPreviewImage(int id, const QByteArray &data, int rotation)
{
QSize frameSize = m_camera->previewSize();
diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h
index 17ea4171f..61d8c1a17 100644
--- a/src/plugins/android/src/mediacapture/qandroidcamerasession.h
+++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.h
@@ -114,7 +114,6 @@ private Q_SLOTS:
void onCameraPictureExposed();
void onCameraPictureCaptured(const QByteArray &data);
- void onCameraPreviewFrameAvailable(const QByteArray &data);
private:
bool open();
diff --git a/src/plugins/android/src/wrappers/jcamera.cpp b/src/plugins/android/src/wrappers/jcamera.cpp
index e69cb554d..5712ae356 100644
--- a/src/plugins/android/src/wrappers/jcamera.cpp
+++ b/src/plugins/android/src/wrappers/jcamera.cpp
@@ -102,18 +102,6 @@ static void notifyPictureCaptured(JNIEnv *env, jobject, int id, jbyteArray data)
}
}
-static void notifyPreviewFrame(JNIEnv *env, jobject, int id, jbyteArray data)
-{
- JCamera *obj = g_objectMap.value(id, 0);
- if (obj) {
- QByteArray bytes;
- int arrayLength = env->GetArrayLength(data);
- bytes.resize(arrayLength);
- env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data());
- Q_EMIT obj->previewFrameAvailable(bytes);
- }
-}
-
JCamera::JCamera(int cameraId, jobject cam)
: QObject()
, QJNIObjectPrivate(cam)
@@ -667,14 +655,26 @@ void JCamera::setJpegQuality(int quality)
applyParameters();
}
-void JCamera::requestPreviewFrame()
+void JCamera::takePicture()
{
- callMethod<void>("requestPreviewFrame");
+ callMethod<void>("takePicture");
}
-void JCamera::takePicture()
+QByteArray JCamera::fetchLastPreviewFrame()
{
- callMethod<void>("takePicture");
+ QJNIEnvironmentPrivate env;
+ QJNIObjectPrivate dataObj = callObjectMethod("lockAndFetchPreviewBuffer", "()[B");
+ if (!dataObj.object()) {
+ callMethod<void>("unlockPreviewBuffer");
+ return QByteArray();
+ }
+ jbyteArray data = static_cast<jbyteArray>(dataObj.object());
+ QByteArray bytes;
+ int arrayLength = env->GetArrayLength(data);
+ bytes.resize(arrayLength);
+ env->GetByteArrayRegion(data, 0, arrayLength, (jbyte*)bytes.data());
+ callMethod<void>("unlockPreviewBuffer");
+ return bytes;
}
void JCamera::startPreview()
@@ -720,8 +720,7 @@ QStringList JCamera::callStringListMethod(const char *methodName)
static JNINativeMethod methods[] = {
{"notifyAutoFocusComplete", "(IZ)V", (void *)notifyAutoFocusComplete},
{"notifyPictureExposed", "(I)V", (void *)notifyPictureExposed},
- {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured},
- {"notifyPreviewFrame", "(I[B)V", (void *)notifyPreviewFrame}
+ {"notifyPictureCaptured", "(I[B)V", (void *)notifyPictureCaptured}
};
bool JCamera::initJNI(JNIEnv *env)
diff --git a/src/plugins/android/src/wrappers/jcamera.h b/src/plugins/android/src/wrappers/jcamera.h
index 7c47ec7a2..6bba98402 100644
--- a/src/plugins/android/src/wrappers/jcamera.h
+++ b/src/plugins/android/src/wrappers/jcamera.h
@@ -147,10 +147,10 @@ public:
void startPreview();
void stopPreview();
- void requestPreviewFrame();
-
void takePicture();
+ QByteArray fetchLastPreviewFrame();
+
static bool initJNI(JNIEnv *env);
Q_SIGNALS:
@@ -161,8 +161,6 @@ Q_SIGNALS:
void whiteBalanceChanged();
- void previewFrameAvailable(const QByteArray &data);
-
void pictureExposed();
void pictureCaptured(const QByteArray &data);