Android: Camera code clean-up

Change-Id: Ib400afde12067764c3dcc0f44e40ddc1abb3012f
Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
This commit is contained in:
Christian Strømme
2014-04-03 18:09:48 +02:00
committed by The Qt Project
parent 60a911096f
commit b088962950
4 changed files with 307 additions and 337 deletions

View File

@@ -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 \

View File

@@ -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

View File

@@ -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