From e23bf25c468aec0e8a12746c56edcf6a8ff68aed Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Tue, 26 Jul 2011 10:05:53 -0700 Subject: [PATCH] Concurrency fix to CameraSource. Don't hold a lock on the whole object while waiting for new frames. Could have potentially deadlocked the filter if the UI thread attempted to call get/setCameraParameters while filter was waiting for a new frame. Bug-Id: 5075306 Change-Id: I12391ff3247c64a2c6a303bfc9f542e1e80d2c24 --- mca/filterpacks/videosrc/java/CameraSource.java | 30 ++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/mca/filterpacks/videosrc/java/CameraSource.java b/mca/filterpacks/videosrc/java/CameraSource.java index 46800eac..a361db0e 100644 --- a/mca/filterpacks/videosrc/java/CameraSource.java +++ b/mca/filterpacks/videosrc/java/CameraSource.java @@ -78,9 +78,13 @@ public class CameraSource extends Filter { private SurfaceTexture mSurfaceTexture; private ShaderProgram mFrameExtractor; private MutableFrameFormat mOutputFormat; - private ConditionVariable mNewFrameAvailable; private float[] mCameraTransform; + private static final int NEWFRAME_TIMEOUT = 100; //ms + private static final int NEWFRAME_TIMEOUT_REPEAT = 10; + + private boolean mNewFrameAvailable; + private Camera.Parameters mCameraParameters; private static final String mFrameShader = @@ -99,7 +103,6 @@ public class CameraSource extends Filter { public CameraSource(String name) { super(name); - mNewFrameAvailable = new ConditionVariable(); mCameraTransform = new float[16]; mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE); @@ -156,6 +159,7 @@ public class CameraSource extends Filter { // Connect SurfaceTexture to callback mSurfaceTexture.setOnFrameAvailableListener(onCameraFrameAvailableListener); // Start the preview + mNewFrameAvailable = false; mCamera.startPreview(); } @@ -164,12 +168,19 @@ public class CameraSource extends Filter { if (mLogVerbose) Log.v(TAG, "Processing new frame"); if (mWaitForNewFrame) { - boolean gotNewFrame; - gotNewFrame = mNewFrameAvailable.block(1000); - if (!gotNewFrame) { - throw new RuntimeException("Timeout waiting for new frame from camera"); + int waitCount = 0; + while (!mNewFrameAvailable) { + if (waitCount == NEWFRAME_TIMEOUT_REPEAT) { + throw new RuntimeException("Timeout waiting for new frame"); + } + try { + this.wait(NEWFRAME_TIMEOUT); + } catch (InterruptedException e) { + if (mLogVerbose) Log.v(TAG, "Interrupted while waiting for new frame"); + } } - mNewFrameAvailable.close(); + mNewFrameAvailable = false; + if (mLogVerbose) Log.v(TAG, "Got new frame"); } mSurfaceTexture.updateTexImage(); @@ -325,7 +336,10 @@ public class CameraSource extends Filter { @Override public void onFrameAvailable(SurfaceTexture surfaceTexture) { if (mLogVerbose) Log.v(TAG, "New frame from camera"); - mNewFrameAvailable.open(); + synchronized(CameraSource.this) { + mNewFrameAvailable = true; + CameraSource.this.notify(); + } } }; -- 2.11.0