Merge "camera2: Make legacy error handling more robust." into lmp-mr1-dev
This commit is contained in:
@@ -44,6 +44,7 @@ import java.util.Collections;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import static com.android.internal.util.Preconditions.*;
|
import static com.android.internal.util.Preconditions.*;
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ public class RequestThreadManager {
|
|||||||
// For slightly more spammy messages that will get repeated every frame
|
// For slightly more spammy messages that will get repeated every frame
|
||||||
private static final boolean VERBOSE =
|
private static final boolean VERBOSE =
|
||||||
Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.VERBOSE);
|
Log.isLoggable(LegacyCameraDevice.DEBUG_PROP, Log.VERBOSE);
|
||||||
private final Camera mCamera;
|
private Camera mCamera;
|
||||||
private final CameraCharacteristics mCharacteristics;
|
private final CameraCharacteristics mCharacteristics;
|
||||||
|
|
||||||
private final CameraDeviceState mDeviceState;
|
private final CameraDeviceState mDeviceState;
|
||||||
@@ -83,8 +84,8 @@ public class RequestThreadManager {
|
|||||||
private static final int MAX_IN_FLIGHT_REQUESTS = 2;
|
private static final int MAX_IN_FLIGHT_REQUESTS = 2;
|
||||||
|
|
||||||
private static final int PREVIEW_FRAME_TIMEOUT = 1000; // ms
|
private static final int PREVIEW_FRAME_TIMEOUT = 1000; // ms
|
||||||
private static final int JPEG_FRAME_TIMEOUT = 3000; // ms (same as CTS for API2)
|
private static final int JPEG_FRAME_TIMEOUT = 4000; // ms (same as CTS for API2)
|
||||||
private static final int REQUEST_COMPLETE_TIMEOUT = 3000; // ms (same as JPEG timeout)
|
private static final int REQUEST_COMPLETE_TIMEOUT = JPEG_FRAME_TIMEOUT; // ms (same as JPEG timeout)
|
||||||
|
|
||||||
private static final float ASPECT_RATIO_TOLERANCE = 0.01f;
|
private static final float ASPECT_RATIO_TOLERANCE = 0.01f;
|
||||||
private boolean mPreviewRunning = false;
|
private boolean mPreviewRunning = false;
|
||||||
@@ -108,6 +109,8 @@ public class RequestThreadManager {
|
|||||||
private final FpsCounter mPrevCounter = new FpsCounter("Incoming Preview");
|
private final FpsCounter mPrevCounter = new FpsCounter("Incoming Preview");
|
||||||
private final FpsCounter mRequestCounter = new FpsCounter("Incoming Requests");
|
private final FpsCounter mRequestCounter = new FpsCounter("Incoming Requests");
|
||||||
|
|
||||||
|
private final AtomicBoolean mQuit = new AtomicBoolean(false);
|
||||||
|
|
||||||
// Stuff JPEGs into HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers to get around SW write
|
// Stuff JPEGs into HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers to get around SW write
|
||||||
// limitations for (b/17379185).
|
// limitations for (b/17379185).
|
||||||
private static final boolean USE_BLOB_FORMAT_OVERRIDE = true;
|
private static final boolean USE_BLOB_FORMAT_OVERRIDE = true;
|
||||||
@@ -325,7 +328,15 @@ public class RequestThreadManager {
|
|||||||
Log.d(TAG, "configureOutputs with " + outputsStr);
|
Log.d(TAG, "configureOutputs with " + outputsStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
stopPreview();
|
try {
|
||||||
|
stopPreview();
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
Log.e(TAG, "Received device exception in configure call: ", e);
|
||||||
|
mDeviceState.setError(
|
||||||
|
CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to release the previous preview's surface texture earlier if we end up
|
* Try to release the previous preview's surface texture earlier if we end up
|
||||||
* using a different one; this also reduces the likelihood of getting into a deadlock
|
* using a different one; this also reduces the likelihood of getting into a deadlock
|
||||||
@@ -335,6 +346,11 @@ public class RequestThreadManager {
|
|||||||
mCamera.setPreviewTexture(/*surfaceTexture*/null);
|
mCamera.setPreviewTexture(/*surfaceTexture*/null);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.w(TAG, "Failed to clear prior SurfaceTexture, may cause GL deadlock: ", e);
|
Log.w(TAG, "Failed to clear prior SurfaceTexture, may cause GL deadlock: ", e);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
Log.e(TAG, "Received device exception in configure call: ", e);
|
||||||
|
mDeviceState.setError(
|
||||||
|
CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mGLThreadManager != null) {
|
if (mGLThreadManager != null) {
|
||||||
@@ -470,7 +486,14 @@ public class RequestThreadManager {
|
|||||||
mPreviewTexture.setOnFrameAvailableListener(mPreviewCallback);
|
mPreviewTexture.setOnFrameAvailableListener(mPreviewCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
mCamera.setParameters(mParams);
|
try {
|
||||||
|
mCamera.setParameters(mParams);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
Log.e(TAG, "Received device exception while configuring: ", e);
|
||||||
|
mDeviceState.setError(
|
||||||
|
CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetJpegSurfaceFormats(Collection<Surface> surfaces) {
|
private void resetJpegSurfaceFormats(Collection<Surface> surfaces) {
|
||||||
@@ -793,7 +816,7 @@ public class RequestThreadManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "Received device exception: ", e);
|
Log.e(TAG, "Received device exception during capture call: ", e);
|
||||||
mDeviceState.setError(
|
mDeviceState.setError(
|
||||||
CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
|
CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
|
||||||
break;
|
break;
|
||||||
@@ -802,6 +825,11 @@ public class RequestThreadManager {
|
|||||||
mDeviceState.setError(
|
mDeviceState.setError(
|
||||||
CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
|
CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
|
||||||
break;
|
break;
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
Log.e(TAG, "Received device exception during capture call: ", e);
|
||||||
|
mDeviceState.setError(
|
||||||
|
CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paramsChanged) {
|
if (paramsChanged) {
|
||||||
@@ -878,9 +906,11 @@ public class RequestThreadManager {
|
|||||||
}
|
}
|
||||||
if (mGLThreadManager != null) {
|
if (mGLThreadManager != null) {
|
||||||
mGLThreadManager.quit();
|
mGLThreadManager.quit();
|
||||||
|
mGLThreadManager = null;
|
||||||
}
|
}
|
||||||
if (mCamera != null) {
|
if (mCamera != null) {
|
||||||
mCamera.release();
|
mCamera.release();
|
||||||
|
mCamera = null;
|
||||||
}
|
}
|
||||||
resetJpegSurfaceFormats(mCallbackOutputs);
|
resetJpegSurfaceFormats(mCallbackOutputs);
|
||||||
break;
|
break;
|
||||||
@@ -942,14 +972,16 @@ public class RequestThreadManager {
|
|||||||
* Quit the request thread, and clean up everything.
|
* Quit the request thread, and clean up everything.
|
||||||
*/
|
*/
|
||||||
public void quit() {
|
public void quit() {
|
||||||
Handler handler = mRequestThread.waitAndGetHandler();
|
if (!mQuit.getAndSet(true)) { // Avoid sending messages on dead thread's handler.
|
||||||
handler.sendMessageAtFrontOfQueue(handler.obtainMessage(MSG_CLEANUP));
|
Handler handler = mRequestThread.waitAndGetHandler();
|
||||||
mRequestThread.quitSafely();
|
handler.sendMessageAtFrontOfQueue(handler.obtainMessage(MSG_CLEANUP));
|
||||||
try {
|
mRequestThread.quitSafely();
|
||||||
mRequestThread.join();
|
try {
|
||||||
} catch (InterruptedException e) {
|
mRequestThread.join();
|
||||||
Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.",
|
} catch (InterruptedException e) {
|
||||||
mRequestThread.getName(), mRequestThread.getId()));
|
Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.",
|
||||||
|
mRequestThread.getName(), mRequestThread.getId()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user