Commit 52effe9e authored by Alexander Alekhin's avatar Alexander Alekhin

Android: fix JavaCameraView implementation

1) Fixed deadlock if camera is started and stopped immediately
2) Invalid pattern usage of Object.wait(). Refer to "spurious wakeup": http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#wait
3) Fixed buffer usage:
  a) fix eliminates processing of zero NV12 (green in RGB) first frame
  b) latest ready frame is delivered for processing (not previous)
parent bdb088dc
......@@ -43,11 +43,13 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
public static class JavaCameraSizeAccessor implements ListItemAccessor {
@Override
public int getWidth(Object obj) {
Camera.Size size = (Camera.Size) obj;
return size.width;
}
@Override
public int getHeight(Object obj) {
Camera.Size size = (Camera.Size) obj;
return size.height;
......@@ -228,6 +230,8 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
}
}
private boolean mCameraFrameReady = false;
@Override
protected boolean connectCamera(int width, int height) {
......@@ -239,6 +243,8 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
if (!initializeCamera(width, height))
return false;
mCameraFrameReady = false;
/* now we can start update thread */
Log.d(TAG, "Starting processing thread");
mStopThread = false;
......@@ -248,6 +254,7 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
return true;
}
@Override
protected void disconnectCamera() {
/* 1. We need to stop thread which updating the frames
* 2. Stop camera and release it
......@@ -270,12 +277,16 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
/* Now release camera */
releaseCamera();
mCameraFrameReady = false;
}
@Override
public void onPreviewFrame(byte[] frame, Camera arg1) {
Log.d(TAG, "Preview Frame received. Frame size: " + frame.length);
synchronized (this) {
mFrameChain[1 - mChainIdx].put(0, 0, frame);
mFrameChain[mChainIdx].put(0, 0, frame);
mCameraFrameReady = true;
this.notify();
}
if (mCamera != null)
......@@ -283,10 +294,12 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
}
private class JavaCameraFrame implements CvCameraViewFrame {
@Override
public Mat gray() {
return mYuvFrameData.submat(0, mHeight, 0, mWidth);
}
@Override
public Mat rgba() {
Imgproc.cvtColor(mYuvFrameData, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4);
return mRgba;
......@@ -312,21 +325,25 @@ public class JavaCameraView extends CameraBridgeViewBase implements PreviewCallb
private class CameraWorker implements Runnable {
@Override
public void run() {
do {
synchronized (JavaCameraView.this) {
try {
JavaCameraView.this.wait();
while (!mCameraFrameReady && !mStopThread) {
JavaCameraView.this.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (mCameraFrameReady)
mChainIdx = 1 - mChainIdx;
}
if (!mStopThread) {
if (!mFrameChain[mChainIdx].empty())
deliverAndDrawFrame(mCameraFrame[mChainIdx]);
mChainIdx = 1 - mChainIdx;
if (!mStopThread && mCameraFrameReady) {
mCameraFrameReady = false;
if (!mFrameChain[1 - mChainIdx].empty())
deliverAndDrawFrame(mCameraFrame[1 - mChainIdx]);
}
} while (!mStopThread);
Log.d(TAG, "Finish processing thread");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment