Android: Camera code clean-up
Change-Id: Ib400afde12067764c3dcc0f44e40ddc1abb3012f Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
This commit is contained in:
committed by
The Qt Project
parent
60a911096f
commit
b088962950
@@ -6,7 +6,7 @@ API_VERSION = android-11
|
|||||||
JAVACLASSPATH += $$PWD/src
|
JAVACLASSPATH += $$PWD/src
|
||||||
|
|
||||||
JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/multimedia/QtAndroidMediaPlayer.java \
|
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/QtSurfaceTextureListener.java \
|
||||||
$$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java \
|
$$PWD/src/org/qtproject/qt5/android/multimedia/QtSurfaceTextureHolder.java \
|
||||||
$$PWD/src/org/qtproject/qt5/android/multimedia/QtMultimediaUtils.java \
|
$$PWD/src/org/qtproject/qt5/android/multimedia/QtMultimediaUtils.java \
|
||||||
|
|||||||
@@ -48,98 +48,33 @@ import android.util.Log;
|
|||||||
import java.lang.Math;
|
import java.lang.Math;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public class QtCamera implements Camera.ShutterCallback,
|
public class QtCameraListener implements Camera.ShutterCallback,
|
||||||
Camera.PictureCallback,
|
Camera.PictureCallback,
|
||||||
Camera.AutoFocusCallback,
|
Camera.AutoFocusCallback,
|
||||||
Camera.PreviewCallback
|
Camera.PreviewCallback
|
||||||
{
|
{
|
||||||
private int m_cameraId = -1;
|
private int m_cameraId = -1;
|
||||||
private Camera m_camera = null;
|
private byte[][] m_cameraPreviewBuffer = null;
|
||||||
private byte[] m_cameraPreviewFirstBuffer = null;
|
private volatile int m_actualPreviewBuffer = 0;
|
||||||
private byte[] m_cameraPreviewSecondBuffer = null;
|
|
||||||
private int m_actualPreviewBuffer = 0;
|
|
||||||
private final ReentrantLock m_buffersLock = new ReentrantLock();
|
private final ReentrantLock m_buffersLock = new ReentrantLock();
|
||||||
private boolean m_isReleased = false;
|
|
||||||
private boolean m_fetchEachFrame = false;
|
private boolean m_fetchEachFrame = false;
|
||||||
|
|
||||||
private static final String TAG = "Qt Camera";
|
private static final String TAG = "Qt Camera";
|
||||||
|
|
||||||
private QtCamera(int id, Camera cam)
|
private QtCameraListener(int id)
|
||||||
{
|
{
|
||||||
m_cameraId = id;
|
m_cameraId = id;
|
||||||
m_camera = cam;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static QtCamera open(int cameraId)
|
public void preparePreviewBuffer(Camera camera)
|
||||||
{
|
{
|
||||||
try {
|
Camera.Size previewSize = camera.getParameters().getPreviewSize();
|
||||||
Camera cam = Camera.open(cameraId);
|
double bytesPerPixel = ImageFormat.getBitsPerPixel(camera.getParameters().getPreviewFormat()) / 8.0;
|
||||||
return new QtCamera(cameraId, cam);
|
int bufferSizeNeeded = (int)Math.ceil(bytesPerPixel*previewSize.width*previewSize.height);
|
||||||
} catch(Exception e) {
|
m_buffersLock.lock();
|
||||||
Log.d(TAG, e.getMessage());
|
if (m_cameraPreviewBuffer == null || m_cameraPreviewBuffer[0].length < bufferSizeNeeded)
|
||||||
}
|
m_cameraPreviewBuffer = new byte[2][bufferSizeNeeded];
|
||||||
return null;
|
m_buffersLock.unlock();
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
public void fetchEachFrame(boolean fetch)
|
||||||
@@ -147,51 +82,6 @@ public class QtCamera implements Camera.ShutterCallback,
|
|||||||
m_fetchEachFrame = 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()
|
public byte[] lockAndFetchPreviewBuffer()
|
||||||
{
|
{
|
||||||
//This method should always be followed by unlockPreviewBuffer()
|
//This method should always be followed by unlockPreviewBuffer()
|
||||||
@@ -199,10 +89,7 @@ public class QtCamera implements Camera.ShutterCallback,
|
|||||||
//We should reset actualBuffer flag here to make sure we will not use old preview with future captures
|
//We should reset actualBuffer flag here to make sure we will not use old preview with future captures
|
||||||
byte[] result = null;
|
byte[] result = null;
|
||||||
m_buffersLock.lock();
|
m_buffersLock.lock();
|
||||||
if (m_actualPreviewBuffer == 1)
|
result = m_cameraPreviewBuffer[(m_actualPreviewBuffer == 1) ? 0 : 1];
|
||||||
result = m_cameraPreviewFirstBuffer;
|
|
||||||
else if (m_actualPreviewBuffer == 2)
|
|
||||||
result = m_cameraPreviewSecondBuffer;
|
|
||||||
m_actualPreviewBuffer = 0;
|
m_actualPreviewBuffer = 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -213,14 +100,9 @@ public class QtCamera implements Camera.ShutterCallback,
|
|||||||
m_buffersLock.unlock();
|
m_buffersLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCallbackBuffer()
|
public byte[] callbackBuffer()
|
||||||
{
|
{
|
||||||
if (m_isReleased)
|
return m_cameraPreviewBuffer[(m_actualPreviewBuffer == 1) ? 1 : 0];
|
||||||
return;
|
|
||||||
|
|
||||||
m_camera.addCallbackBuffer((m_actualPreviewBuffer == 1)
|
|
||||||
? m_cameraPreviewSecondBuffer
|
|
||||||
: m_cameraPreviewFirstBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -243,13 +125,13 @@ public class QtCamera implements Camera.ShutterCallback,
|
|||||||
if (data != null && m_fetchEachFrame)
|
if (data != null && m_fetchEachFrame)
|
||||||
notifyFrameFetched(m_cameraId, data);
|
notifyFrameFetched(m_cameraId, data);
|
||||||
|
|
||||||
if (data == m_cameraPreviewFirstBuffer)
|
if (data == m_cameraPreviewBuffer[0])
|
||||||
m_actualPreviewBuffer = 1;
|
m_actualPreviewBuffer = 1;
|
||||||
else if (data == m_cameraPreviewSecondBuffer)
|
else if (data == m_cameraPreviewBuffer[1])
|
||||||
m_actualPreviewBuffer = 2;
|
m_actualPreviewBuffer = 2;
|
||||||
else
|
else
|
||||||
m_actualPreviewBuffer = 0;
|
m_actualPreviewBuffer = 0;
|
||||||
addCallbackBuffer();
|
camera.addCallbackBuffer(m_cameraPreviewBuffer[(m_actualPreviewBuffer == 1) ? 1 : 0]);
|
||||||
m_buffersLock.unlock();
|
m_buffersLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
class QThread;
|
class QThread;
|
||||||
|
|
||||||
class JCameraWorker;
|
class JCameraPrivate;
|
||||||
|
|
||||||
class JCamera : public QObject
|
class JCamera : public QObject
|
||||||
{
|
{
|
||||||
@@ -175,9 +175,11 @@ Q_SIGNALS:
|
|||||||
void frameFetched(const QByteArray &frame);
|
void frameFetched(const QByteArray &frame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JCamera(int cameraId, jobject cam, QThread *workerThread);
|
JCamera(JCameraPrivate *d, QThread *worker);
|
||||||
|
|
||||||
JCameraWorker *d;
|
Q_DECLARE_PRIVATE(JCamera)
|
||||||
|
JCameraPrivate *d_ptr;
|
||||||
|
QScopedPointer<QThread> m_worker;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
Reference in New Issue
Block a user