Android: camera moved to a dedicated thread
Actual camera work moved to JCameraWorker which lives in dedicated thread. JCamera now acts as proxy calling JCameraWorker methods with invokeMethod (when it is needed). [ChangeLog][QtMultimedia][Android] camera operations moved to a dedicated thread Task-number: QTBUG-35564 Change-Id: Ie4edcbf0869d56b0fef4ad0c820450cc77657fdd Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
This commit is contained in:
committed by
The Qt Project
parent
ecce937a05
commit
a0df6c3836
@@ -182,7 +182,10 @@ bool QAndroidCameraSession::open()
|
|||||||
|
|
||||||
if (m_camera) {
|
if (m_camera) {
|
||||||
connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed()));
|
connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed()));
|
||||||
|
connect(m_camera, SIGNAL(previewFetched(QByteArray)), this, SLOT(onCameraPreviewFetched(QByteArray)));
|
||||||
connect(m_camera, SIGNAL(pictureCaptured(QByteArray)), this, SLOT(onCameraPictureCaptured(QByteArray)));
|
connect(m_camera, SIGNAL(pictureCaptured(QByteArray)), this, SLOT(onCameraPictureCaptured(QByteArray)));
|
||||||
|
connect(m_camera, SIGNAL(previewStarted()), this, SLOT(onCameraPreviewStarted()));
|
||||||
|
connect(m_camera, SIGNAL(previewStopped()), this, SLOT(onCameraPreviewStopped()));
|
||||||
|
|
||||||
m_nativeOrientation = m_camera->getNativeOrientation();
|
m_nativeOrientation = m_camera->getNativeOrientation();
|
||||||
|
|
||||||
@@ -309,11 +312,6 @@ void QAndroidCameraSession::startPreview()
|
|||||||
|
|
||||||
m_camera->startPreview();
|
m_camera->startPreview();
|
||||||
m_previewStarted = true;
|
m_previewStarted = true;
|
||||||
|
|
||||||
m_status = QCamera::ActiveStatus;
|
|
||||||
emit statusChanged(m_status);
|
|
||||||
|
|
||||||
setReadyForCapture(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QAndroidCameraSession::stopPreview()
|
void QAndroidCameraSession::stopPreview()
|
||||||
@@ -331,11 +329,6 @@ void QAndroidCameraSession::stopPreview()
|
|||||||
if (m_videoOutput)
|
if (m_videoOutput)
|
||||||
m_videoOutput->stop();
|
m_videoOutput->stop();
|
||||||
m_previewStarted = false;
|
m_previewStarted = false;
|
||||||
|
|
||||||
m_status = QCamera::LoadedStatus;
|
|
||||||
emit statusChanged(m_status);
|
|
||||||
|
|
||||||
setReadyForCapture(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QAndroidCameraSession::setImageSettings(const QImageEncoderSettings &settings)
|
void QAndroidCameraSession::setImageSettings(const QImageEncoderSettings &settings)
|
||||||
@@ -507,11 +500,15 @@ void QAndroidCameraSession::onCameraPictureExposed()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
emit imageExposed(m_currentImageCaptureId);
|
emit imageExposed(m_currentImageCaptureId);
|
||||||
QByteArray lastFrame = m_camera->fetchLastPreviewFrame();
|
m_camera->fetchLastPreviewFrame();
|
||||||
if (lastFrame.size()) {
|
}
|
||||||
|
|
||||||
|
void QAndroidCameraSession::onCameraPreviewFetched(const QByteArray &preview)
|
||||||
|
{
|
||||||
|
if (preview.size()) {
|
||||||
QtConcurrent::run(this, &QAndroidCameraSession::processPreviewImage,
|
QtConcurrent::run(this, &QAndroidCameraSession::processPreviewImage,
|
||||||
m_currentImageCaptureId,
|
m_currentImageCaptureId,
|
||||||
lastFrame,
|
preview,
|
||||||
m_camera->getRotation());
|
m_camera->getRotation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -532,10 +529,28 @@ void QAndroidCameraSession::onCameraPictureCaptured(const QByteArray &data)
|
|||||||
|
|
||||||
// Preview needs to be restarted after taking a picture
|
// Preview needs to be restarted after taking a picture
|
||||||
m_camera->startPreview();
|
m_camera->startPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QAndroidCameraSession::onCameraPreviewStarted()
|
||||||
|
{
|
||||||
|
if (m_status == QCamera::StartingStatus) {
|
||||||
|
m_status = QCamera::ActiveStatus;
|
||||||
|
emit statusChanged(m_status);
|
||||||
|
}
|
||||||
|
|
||||||
setReadyForCapture(true);
|
setReadyForCapture(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QAndroidCameraSession::onCameraPreviewStopped()
|
||||||
|
{
|
||||||
|
if (m_status == QCamera::StoppingStatus) {
|
||||||
|
m_status = QCamera::LoadedStatus;
|
||||||
|
emit statusChanged(m_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
setReadyForCapture(false);
|
||||||
|
}
|
||||||
|
|
||||||
void QAndroidCameraSession::processCapturedImage(int id,
|
void QAndroidCameraSession::processCapturedImage(int id,
|
||||||
const QByteArray &data,
|
const QByteArray &data,
|
||||||
const QSize &resolution,
|
const QSize &resolution,
|
||||||
|
|||||||
@@ -113,7 +113,10 @@ private Q_SLOTS:
|
|||||||
void onApplicationStateChanged(Qt::ApplicationState state);
|
void onApplicationStateChanged(Qt::ApplicationState state);
|
||||||
|
|
||||||
void onCameraPictureExposed();
|
void onCameraPictureExposed();
|
||||||
|
void onCameraPreviewFetched(const QByteArray &preview);
|
||||||
void onCameraPictureCaptured(const QByteArray &data);
|
void onCameraPictureCaptured(const QByteArray &data);
|
||||||
|
void onCameraPreviewStarted();
|
||||||
|
void onCameraPreviewStopped();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool open();
|
bool open();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -49,9 +49,15 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class JCamera : public QObject, public QJNIObjectPrivate
|
class QThread;
|
||||||
|
|
||||||
|
class JCameraWorker;
|
||||||
|
|
||||||
|
class JCamera : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_ENUMS(CameraFacing)
|
||||||
|
Q_ENUMS(ImageFormat)
|
||||||
public:
|
public:
|
||||||
enum CameraFacing {
|
enum CameraFacing {
|
||||||
CameraFacingBack = 0,
|
CameraFacingBack = 0,
|
||||||
@@ -72,7 +78,7 @@ public:
|
|||||||
|
|
||||||
static JCamera *open(int cameraId);
|
static JCamera *open(int cameraId);
|
||||||
|
|
||||||
int cameraId() const { return m_cameraId; }
|
int cameraId() const;
|
||||||
|
|
||||||
void lock();
|
void lock();
|
||||||
void unlock();
|
void unlock();
|
||||||
@@ -90,7 +96,7 @@ public:
|
|||||||
ImageFormat getPreviewFormat();
|
ImageFormat getPreviewFormat();
|
||||||
void setPreviewFormat(ImageFormat fmt);
|
void setPreviewFormat(ImageFormat fmt);
|
||||||
|
|
||||||
QSize previewSize() const { return m_previewSize; }
|
QSize previewSize() const;
|
||||||
void setPreviewSize(const QSize &size);
|
void setPreviewSize(const QSize &size);
|
||||||
void setPreviewTexture(jobject surfaceTexture);
|
void setPreviewTexture(jobject surfaceTexture);
|
||||||
|
|
||||||
@@ -149,12 +155,15 @@ public:
|
|||||||
|
|
||||||
void takePicture();
|
void takePicture();
|
||||||
|
|
||||||
QByteArray fetchLastPreviewFrame();
|
void fetchLastPreviewFrame();
|
||||||
|
QJNIObjectPrivate getCameraObject();
|
||||||
|
|
||||||
static bool initJNI(JNIEnv *env);
|
static bool initJNI(JNIEnv *env);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void previewSizeChanged();
|
void previewSizeChanged();
|
||||||
|
void previewStarted();
|
||||||
|
void previewStopped();
|
||||||
|
|
||||||
void autoFocusStarted();
|
void autoFocusStarted();
|
||||||
void autoFocusComplete(bool success);
|
void autoFocusComplete(bool success);
|
||||||
@@ -163,21 +172,12 @@ Q_SIGNALS:
|
|||||||
|
|
||||||
void pictureExposed();
|
void pictureExposed();
|
||||||
void pictureCaptured(const QByteArray &data);
|
void pictureCaptured(const QByteArray &data);
|
||||||
|
void previewFetched(const QByteArray &preview);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JCamera(int cameraId, jobject cam);
|
JCamera(int cameraId, jobject cam, QThread *workerThread);
|
||||||
void applyParameters();
|
|
||||||
|
|
||||||
QStringList callStringListMethod(const char *methodName);
|
JCameraWorker *d;
|
||||||
|
|
||||||
int m_cameraId;
|
|
||||||
QJNIObjectPrivate m_info;
|
|
||||||
QJNIObjectPrivate m_parameters;
|
|
||||||
|
|
||||||
QSize m_previewSize;
|
|
||||||
int m_rotation;
|
|
||||||
|
|
||||||
bool m_hasAPI14;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ void JMediaRecorder::setAudioSource(AudioSource source)
|
|||||||
|
|
||||||
void JMediaRecorder::setCamera(JCamera *camera)
|
void JMediaRecorder::setCamera(JCamera *camera)
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate cam = camera->getObjectField("m_camera", "Landroid/hardware/Camera;");
|
QJNIObjectPrivate cam = camera->getCameraObject();
|
||||||
callMethod<void>("setCamera", "(Landroid/hardware/Camera;)V", cam.object());
|
callMethod<void>("setCamera", "(Landroid/hardware/Camera;)V", cam.object());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user