summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/EffectsRecorder.java
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2011-09-20 13:49:42 -0700
committerEino-Ville Talvala <etalvala@google.com>2011-09-20 17:26:37 -0700
commita7409d87247162002fca1719c035de67fa7e7535 (patch)
tree2cc760fc4bb1d784f4d64bae3243dfa3c63f9b90 /src/com/android/camera/EffectsRecorder.java
parent494c4065b52bd58faa29307ccdb60dd425a843eb (diff)
downloadLegacyCamera-a7409d87247162002fca1719c035de67fa7e7535.zip
LegacyCamera-a7409d87247162002fca1719c035de67fa7e7535.tar.gz
LegacyCamera-a7409d87247162002fca1719c035de67fa7e7535.tar.bz2
Effects: Fix SurfaceTexture abandon/disconnect errors.
- Now ensures that camera preview is stopped before starting or stopping the effects processing, and that the previewTexture is set to null. - Fix a few potential race conditions relating to effect switching - Tear down old graphs properly This fixes errors relating to SurfaceTexture disconnect/abandon errors when swapping between effects, and possibly some rarely-occuring race condition crashes. Bug: 5328760 Change-Id: I6b655f32b835e7ac65cb7c8dc533befb5177907c
Diffstat (limited to 'src/com/android/camera/EffectsRecorder.java')
-rw-r--r--src/com/android/camera/EffectsRecorder.java47
1 files changed, 35 insertions, 12 deletions
diff --git a/src/com/android/camera/EffectsRecorder.java b/src/com/android/camera/EffectsRecorder.java
index f78f5dc..6d4faf4 100644
--- a/src/com/android/camera/EffectsRecorder.java
+++ b/src/com/android/camera/EffectsRecorder.java
@@ -85,6 +85,7 @@ public class EffectsRecorder {
private GraphEnvironment mGraphEnv;
private int mGraphId;
private GraphRunner mRunner = null;
+ private GraphRunner mOldRunner = null;
private SurfaceTexture mTextureSource;
@@ -262,7 +263,7 @@ public class EffectsRecorder {
mErrorListener = errorListener;
}
- public void initializeFilterFramework() {
+ private void initializeFilterFramework() {
mGraphEnv = new GraphEnvironment();
mGraphEnv.createGLEnvironment();
@@ -279,7 +280,7 @@ public class EffectsRecorder {
mCurrentEffect = EFFECT_NONE;
}
- public synchronized void initializeEffect(boolean forceReset) {
+ private synchronized void initializeEffect(boolean forceReset) {
if (forceReset ||
mCurrentEffect != mEffect ||
mCurrentEffect == EFFECT_BACKDROPPER) {
@@ -287,13 +288,11 @@ public class EffectsRecorder {
"previewSurface", mPreviewSurfaceHolder.getSurface(),
"previewWidth", mPreviewWidth,
"previewHeight", mPreviewHeight);
-
if (mState == STATE_PREVIEW) {
- // Switching effects while running. Stop existing runner.
- // The stop callback will take care of starting new runner.
+ // Switching effects while running. Inform video camera.
sendMessage(mCurrentEffect, EFFECT_MSG_STOPPING_EFFECT);
- mRunner.stop();
}
+
switch (mEffect) {
case EFFECT_GOOFY_FACE:
mGraphId = mGraphEnv.loadGraph(mContext, R.raw.goofy_face);
@@ -307,8 +306,21 @@ public class EffectsRecorder {
}
mCurrentEffect = mEffect;
+ mOldRunner = mRunner;
mRunner = mGraphEnv.getRunner(mGraphId, GraphEnvironment.MODE_ASYNCHRONOUS);
mRunner.setDoneCallback(mRunnerDoneCallback);
+
+ if (mState == STATE_PREVIEW) {
+ // Switching effects while running. Stop existing runner.
+ // The stop callback will take care of starting new runner.
+ mCameraDevice.stopPreview();
+ try {
+ mCameraDevice.setPreviewTexture(null);
+ } catch(IOException e) {
+ throw new RuntimeException("Unable to connect camera to effect input", e);
+ }
+ mOldRunner.stop();
+ }
}
switch (mCurrentEffect) {
@@ -328,7 +340,7 @@ public class EffectsRecorder {
setFaceDetectOrientation(mOrientationHint);
}
- public void startPreview() {
+ public synchronized void startPreview() {
if (mLogVerbose) Log.v(TAG, "Starting preview (" + this + ")");
switch (mState) {
@@ -421,7 +433,7 @@ public class EffectsRecorder {
}
};
- public void startRecording() {
+ public synchronized void startRecording() {
if (mLogVerbose) Log.v(TAG, "Starting recording (" + this + ")");
switch (mState) {
@@ -453,7 +465,7 @@ public class EffectsRecorder {
mState = STATE_RECORD;
}
- public void stopRecording() {
+ public synchronized void stopRecording() {
if (mLogVerbose) Log.v(TAG, "Stop recording (" + this + ")");
switch (mState) {
@@ -472,7 +484,7 @@ public class EffectsRecorder {
}
// Stop and release effect resources
- public void stopPreview() {
+ public synchronized void stopPreview() {
if (mLogVerbose) Log.v(TAG, "Stopping preview (" + this + ")");
switch (mState) {
@@ -493,7 +505,15 @@ public class EffectsRecorder {
mCurrentEffect = EFFECT_NONE;
+ mCameraDevice.stopPreview();
+ try {
+ mCameraDevice.setPreviewTexture(null);
+ } catch(IOException e) {
+ throw new RuntimeException("Unable to connect camera to effect input", e);
+ }
+
mState = STATE_CONFIGURE;
+ mOldRunner = mRunner;
mRunner.stop();
// Rest of stop and release handled in mRunnerDoneCallback
@@ -525,6 +545,11 @@ public class EffectsRecorder {
new OnRunnerDoneListener() {
public void onRunnerDone(int result) {
synchronized(EffectsRecorder.this) {
+ if (mOldRunner != null) {
+ if (mLogVerbose) Log.v(TAG, "Tearing down old graph.");
+ mOldRunner.getGraph().tearDown(mGraphEnv.getContext());
+ mOldRunner = null;
+ }
if (mState == STATE_PREVIEW) {
// Switching effects, start up the new runner
if (mLogVerbose) Log.v(TAG, "Previous effect halted, starting new effect.");
@@ -533,7 +558,6 @@ public class EffectsRecorder {
} else if (mState != STATE_RELEASED) {
// Shutting down effects
if (mLogVerbose) Log.v(TAG, "Runner halted, restoring direct preview");
- mCameraDevice.stopPreview();
try {
mCameraDevice.setPreviewDisplay(mPreviewSurfaceHolder);
} catch(IOException e) {
@@ -555,7 +579,6 @@ public class EffectsRecorder {
case STATE_RECORD:
case STATE_PREVIEW:
stopPreview();
- mCameraDevice.stopPreview();
// Fall-through
default:
mState = STATE_RELEASED;