Loading core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +9 −16 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ import java.util.TreeSet; * HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate */ public class CameraDeviceImpl extends CameraDevice { private final String TAG; private final boolean DEBUG; Loading Loading @@ -1136,7 +1135,6 @@ public class CameraDeviceImpl extends CameraDevice { } public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub { // // Constants below need to be kept up-to-date with // frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h Loading @@ -1149,34 +1147,29 @@ public class CameraDeviceImpl extends CameraDevice { /** * Camera has been disconnected */ static final int ERROR_CAMERA_DISCONNECTED = 0; public static final int ERROR_CAMERA_DISCONNECTED = 0; /** * Camera has encountered a device-level error * Matches CameraDevice.StateCallback#ERROR_CAMERA_DEVICE */ static final int ERROR_CAMERA_DEVICE = 1; public static final int ERROR_CAMERA_DEVICE = 1; /** * Camera has encountered a service-level error * Matches CameraDevice.StateCallback#ERROR_CAMERA_SERVICE */ static final int ERROR_CAMERA_SERVICE = 2; public static final int ERROR_CAMERA_SERVICE = 2; /** * Camera has encountered an error processing a single request. */ static final int ERROR_CAMERA_REQUEST = 3; public static final int ERROR_CAMERA_REQUEST = 3; /** * Camera has encountered an error producing metadata for a single capture */ static final int ERROR_CAMERA_RESULT = 4; public static final int ERROR_CAMERA_RESULT = 4; /** * Camera has encountered an error producing an image buffer for a single capture */ static final int ERROR_CAMERA_BUFFER = 5; public static final int ERROR_CAMERA_BUFFER = 5; @Override public IBinder asBinder() { Loading core/java/android/hardware/camera2/legacy/CameraDeviceState.java +59 −22 Original line number Diff line number Diff line Loading @@ -49,6 +49,9 @@ public class CameraDeviceState { private static final int STATE_IDLE = 3; private static final int STATE_CAPTURING = 4; private static final String[] sStateNames = { "ERROR", "UNCONFIGURED", "CONFIGURING", "IDLE", "CAPTURING"}; private int mCurrentState = STATE_UNCONFIGURED; private int mCurrentError = CameraBinderDecorator.NO_ERROR; Loading @@ -57,6 +60,11 @@ public class CameraDeviceState { private Handler mCurrentHandler = null; private CameraDeviceStateListener mCurrentListener = null; /** * Error code used by {@link #setCaptureStart} and {@link #setCaptureResult} to indicate that no * error has occurred. */ public static final int NO_CAPTURE_ERROR = -1; /** * CameraDeviceStateListener callbacks to be called after state transitions. Loading Loading @@ -126,11 +134,15 @@ public class CameraDeviceState { * * @param request A {@link RequestHolder} containing the request for the current capture. * @param timestamp The timestamp of the capture start in nanoseconds. * @param captureError Report a recoverable error for a single request using a valid * error code for {@code ICameraDeviceCallbacks}, or * {@link #NO_CAPTURE_ERROR} * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. */ public synchronized int setCaptureStart(final RequestHolder request, long timestamp) { public synchronized int setCaptureStart(final RequestHolder request, long timestamp, int captureError) { mCurrentRequest = request; doStateTransition(STATE_CAPTURING, timestamp); doStateTransition(STATE_CAPTURING, timestamp, captureError); return mCurrentError; } Loading @@ -144,12 +156,16 @@ public class CameraDeviceState { * the {@code ERROR} state, * </p> * * @param request the {@link RequestHolder} request that created this result. * @param result the {@link CameraMetadataNative} result to set. * @param request The {@link RequestHolder} request that created this result. * @param result The {@link CameraMetadataNative} result to set. * @param captureError Report a recoverable error for a single buffer or result using a valid * error code for {@code ICameraDeviceCallbacks}, or * {@link #NO_CAPTURE_ERROR}. * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. */ public synchronized int setCaptureResult(final RequestHolder request, final CameraMetadataNative result) { final CameraMetadataNative result, final int captureError) { if (mCurrentState != STATE_CAPTURING) { Log.e(TAG, "Cannot receive result while in state: " + mCurrentState); mCurrentError = CameraBinderDecorator.INVALID_OPERATION; Loading @@ -158,6 +174,14 @@ public class CameraDeviceState { } if (mCurrentHandler != null && mCurrentListener != null) { if (captureError != NO_CAPTURE_ERROR) { mCurrentHandler.post(new Runnable() { @Override public void run() { mCurrentListener.onError(captureError, request); } }); } else { mCurrentHandler.post(new Runnable() { @Override public void run() { Loading @@ -165,6 +189,7 @@ public class CameraDeviceState { } }); } } return mCurrentError; } Loading @@ -181,14 +206,16 @@ public class CameraDeviceState { } private void doStateTransition(int newState) { doStateTransition(newState, /*timestamp*/0); doStateTransition(newState, /*timestamp*/0, CameraBinderDecorator.NO_ERROR); } private void doStateTransition(int newState, final long timestamp) { if (DEBUG) { private void doStateTransition(int newState, final long timestamp, final int error) { if (newState != mCurrentState) { Log.d(TAG, "Transitioning to state " + newState); String stateName = "UNKNOWN"; if (newState >= 0 && newState < sStateNames.length) { stateName = sStateNames[newState]; } Log.i(TAG, "Legacy camera service transitioning to state " + stateName); } switch(newState) { case STATE_ERROR: Loading Loading @@ -251,7 +278,16 @@ public class CameraDeviceState { doStateTransition(STATE_ERROR); break; } if (mCurrentHandler != null && mCurrentListener != null) { if (error != NO_CAPTURE_ERROR) { mCurrentHandler.post(new Runnable() { @Override public void run() { mCurrentListener.onError(error, mCurrentRequest); } }); } else { mCurrentHandler.post(new Runnable() { @Override public void run() { Loading @@ -259,6 +295,7 @@ public class CameraDeviceState { } }); } } mCurrentState = STATE_CAPTURING; break; default: Loading core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java +57 −1 Original line number Diff line number Diff line Loading @@ -341,6 +341,10 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { Log.d(TAG, "disconnect called."); } if (mLegacyDevice.isClosed()) { Log.w(TAG, "Cannot disconnect, device has already been closed."); } try { mLegacyDevice.close(); } finally { Loading @@ -355,6 +359,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "submitRequest called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot submit request, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot submit request, configuration change in progress."); Loading @@ -370,6 +379,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "submitRequestList called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot submit request list, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot submit request, configuration change in progress."); Loading @@ -384,6 +398,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "cancelRequest called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot cancel request, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot cancel request, configuration change in progress."); Loading @@ -400,6 +419,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "beginConfigure called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot begin configure, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot begin configure, configuration change already in progress."); Loading @@ -415,6 +439,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "endConfigure called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot end configure, device has been closed."); return CameraBinderDecorator.ENODEV; } ArrayList<Surface> surfaces = null; synchronized(mConfigureLock) { if (!mConfiguring) { Loading @@ -438,6 +467,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "deleteStream called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot delete stream, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (!mConfiguring) { Log.e(TAG, "Cannot delete stream, beginConfigure hasn't been called yet."); Loading @@ -458,6 +492,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "createStream called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot create stream, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (!mConfiguring) { Log.e(TAG, "Cannot create stream, beginConfigure hasn't been called yet."); Loading @@ -474,6 +513,10 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "createDefaultRequest called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot create default request, device has been closed."); return CameraBinderDecorator.ENODEV; } CameraMetadataNative template; try { Loading Loading @@ -503,6 +546,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "waitUntilIdle called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot wait until idle, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot wait until idle, configuration change in progress."); Loading @@ -518,13 +566,21 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "flush called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot flush, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot flush, configuration change in progress."); return CameraBinderDecorator.INVALID_OPERATION; } } // TODO: implement flush. long lastFrame = mLegacyDevice.flush(); if (lastFrameNumber != null) { lastFrameNumber.setNumber(lastFrame); } return CameraBinderDecorator.NO_ERROR; } Loading core/java/android/hardware/camera2/legacy/CaptureCollector.java +171 −9 Original line number Diff line number Diff line Loading @@ -15,12 +15,14 @@ */ package android.hardware.camera2.legacy; import android.hardware.camera2.impl.CameraDeviceImpl; import android.util.Log; import android.util.MutableLong; import android.util.Pair; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.TreeSet; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; Loading @@ -44,7 +46,7 @@ public class CaptureCollector { private static final int MAX_JPEGS_IN_FLIGHT = 1; private class CaptureHolder { private class CaptureHolder implements Comparable<CaptureHolder>{ private final RequestHolder mRequest; private final LegacyRequest mLegacy; public final boolean needsJpeg; Loading @@ -53,6 +55,10 @@ public class CaptureCollector { private long mTimestamp = 0; private int mReceivedFlags = 0; private boolean mHasStarted = false; private boolean mFailedJpeg = false; private boolean mFailedPreview = false; private boolean mCompleted = false; private boolean mPreviewCompleted = false; public CaptureHolder(RequestHolder request, LegacyRequest legacyHolder) { mRequest = request; Loading @@ -74,11 +80,43 @@ public class CaptureCollector { } public void tryComplete() { if (isCompleted()) { if (needsPreview && isPreviewCompleted()) { if (!mPreviewCompleted && needsPreview && isPreviewCompleted()) { CaptureCollector.this.onPreviewCompleted(); mPreviewCompleted = true; } if (isCompleted() && !mCompleted) { if (mFailedPreview || mFailedJpeg) { if (!mHasStarted) { // Send a request error if the capture has not yet started. mRequest.failRequest(); CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp, CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_REQUEST); } else { // Send buffer dropped errors for each pending buffer if the request has // started. if (mFailedPreview) { Log.w(TAG, "Preview buffers dropped for request: " + mRequest.getRequestId()); for (int i = 0; i < mRequest.numPreviewTargets(); i++) { CaptureCollector.this.mDeviceState.setCaptureResult(mRequest, /*result*/null, CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_BUFFER); } } if (mFailedJpeg) { Log.w(TAG, "Jpeg buffers dropped for request: " + mRequest.getRequestId()); for (int i = 0; i < mRequest.numJpegTargets(); i++) { CaptureCollector.this.mDeviceState.setCaptureResult(mRequest, /*result*/null, CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_BUFFER); } } } } CaptureCollector.this.onRequestCompleted(this); CaptureCollector.this.onRequestCompleted(CaptureHolder.this); mCompleted = true; } } Loading @@ -103,7 +141,8 @@ public class CaptureCollector { if (!mHasStarted) { mHasStarted = true; CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp); CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp, CameraDeviceState.NO_CAPTURE_ERROR); } tryComplete(); Loading @@ -126,6 +165,20 @@ public class CaptureCollector { tryComplete(); } public void setJpegFailed() { if (DEBUG) { Log.d(TAG, "setJpegFailed - called for request " + mRequest.getRequestId()); } if (!needsJpeg || isJpegCompleted()) { return; } mFailedJpeg = true; mReceivedFlags |= FLAG_RECEIVED_JPEG; mReceivedFlags |= FLAG_RECEIVED_JPEG_TS; tryComplete(); } public void setPreviewTimestamp(long timestamp) { if (DEBUG) { Log.d(TAG, "setPreviewTimestamp - called for request " + mRequest.getRequestId()); Loading @@ -148,7 +201,8 @@ public class CaptureCollector { if (!needsJpeg) { if (!mHasStarted) { mHasStarted = true; CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp); CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp, CameraDeviceState.NO_CAPTURE_ERROR); } } Loading @@ -171,8 +225,37 @@ public class CaptureCollector { mReceivedFlags |= FLAG_RECEIVED_PREVIEW; tryComplete(); } public void setPreviewFailed() { if (DEBUG) { Log.d(TAG, "setPreviewFailed - called for request " + mRequest.getRequestId()); } if (!needsPreview || isPreviewCompleted()) { return; } mFailedPreview = true; mReceivedFlags |= FLAG_RECEIVED_PREVIEW; mReceivedFlags |= FLAG_RECEIVED_PREVIEW_TS; tryComplete(); } // Comparison and equals based on frame number. @Override public int compareTo(CaptureHolder captureHolder) { return (mRequest.getFrameNumber() > captureHolder.mRequest.getFrameNumber()) ? 1 : ((mRequest.getFrameNumber() == captureHolder.mRequest.getFrameNumber()) ? 0 : -1); } // Comparison and equals based on frame number. @Override public boolean equals(Object o) { return o instanceof CaptureHolder && compareTo((CaptureHolder) o) == 0; } } private final TreeSet<CaptureHolder> mActiveRequests; private final ArrayDeque<CaptureHolder> mJpegCaptureQueue; private final ArrayDeque<CaptureHolder> mJpegProduceQueue; private final ArrayDeque<CaptureHolder> mPreviewCaptureQueue; Loading Loading @@ -200,6 +283,7 @@ public class CaptureCollector { mJpegProduceQueue = new ArrayDeque<>(MAX_JPEGS_IN_FLIGHT); mPreviewCaptureQueue = new ArrayDeque<>(mMaxInFlight); mPreviewProduceQueue = new ArrayDeque<>(mMaxInFlight); mActiveRequests = new TreeSet<>(); mIsEmpty = mLock.newCondition(); mNotFull = mLock.newCondition(); mPreviewsEmpty = mLock.newCondition(); Loading Loading @@ -263,7 +347,7 @@ public class CaptureCollector { mPreviewProduceQueue.add(h); mInFlightPreviews++; } mActiveRequests.add(h); mInFlight++; return true; Loading Loading @@ -440,7 +524,9 @@ public class CaptureCollector { try { CaptureHolder h = mPreviewCaptureQueue.poll(); if (h == null) { Log.w(TAG, "previewCaptured called with no preview request on queue!"); if (DEBUG) { Log.d(TAG, "previewCaptured called with no preview request on queue!"); } return null; } h.setPreviewTimestamp(timestamp); Loading Loading @@ -471,6 +557,81 @@ public class CaptureCollector { } } /** * Called to alert the {@link CaptureCollector} that the next pending preview capture has failed. */ public void failNextPreview() { final ReentrantLock lock = this.mLock; lock.lock(); try { CaptureHolder h1 = mPreviewCaptureQueue.peek(); CaptureHolder h2 = mPreviewProduceQueue.peek(); // Find the request with the lowest frame number. CaptureHolder h = (h1 == null) ? h2 : ((h2 == null) ? h1 : ((h1.compareTo(h2) <= 0) ? h1 : h2)); if (h != null) { mPreviewCaptureQueue.remove(h); mPreviewProduceQueue.remove(h); mActiveRequests.remove(h); h.setPreviewFailed(); } } finally { lock.unlock(); } } /** * Called to alert the {@link CaptureCollector} that the next pending jpeg capture has failed. */ public void failNextJpeg() { final ReentrantLock lock = this.mLock; lock.lock(); try { CaptureHolder h1 = mJpegCaptureQueue.peek(); CaptureHolder h2 = mJpegProduceQueue.peek(); // Find the request with the lowest frame number. CaptureHolder h = (h1 == null) ? h2 : ((h2 == null) ? h1 : ((h1.compareTo(h2) <= 0) ? h1 : h2)); if (h != null) { mJpegCaptureQueue.remove(h); mJpegProduceQueue.remove(h); mActiveRequests.remove(h); h.setJpegFailed(); } } finally { lock.unlock(); } } /** * Called to alert the {@link CaptureCollector} all pending captures have failed. */ public void failAll() { final ReentrantLock lock = this.mLock; lock.lock(); try { CaptureHolder h; while ((h = mActiveRequests.pollFirst()) != null) { h.setPreviewFailed(); h.setJpegFailed(); } mPreviewCaptureQueue.clear(); mPreviewProduceQueue.clear(); mJpegCaptureQueue.clear(); mJpegProduceQueue.clear(); } finally { lock.unlock(); } } private void onPreviewCompleted() { mInFlightPreviews--; if (mInFlightPreviews < 0) { Loading @@ -496,6 +657,7 @@ public class CaptureCollector { } mCompletedRequests.add(capture); mActiveRequests.remove(capture); mNotFull.signalAll(); if (mInFlight == 0) { Loading core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +72 −9 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +9 −16 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ import java.util.TreeSet; * HAL2.1+ implementation of CameraDevice. Use CameraManager#open to instantiate */ public class CameraDeviceImpl extends CameraDevice { private final String TAG; private final boolean DEBUG; Loading Loading @@ -1136,7 +1135,6 @@ public class CameraDeviceImpl extends CameraDevice { } public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub { // // Constants below need to be kept up-to-date with // frameworks/av/include/camera/camera2/ICameraDeviceCallbacks.h Loading @@ -1149,34 +1147,29 @@ public class CameraDeviceImpl extends CameraDevice { /** * Camera has been disconnected */ static final int ERROR_CAMERA_DISCONNECTED = 0; public static final int ERROR_CAMERA_DISCONNECTED = 0; /** * Camera has encountered a device-level error * Matches CameraDevice.StateCallback#ERROR_CAMERA_DEVICE */ static final int ERROR_CAMERA_DEVICE = 1; public static final int ERROR_CAMERA_DEVICE = 1; /** * Camera has encountered a service-level error * Matches CameraDevice.StateCallback#ERROR_CAMERA_SERVICE */ static final int ERROR_CAMERA_SERVICE = 2; public static final int ERROR_CAMERA_SERVICE = 2; /** * Camera has encountered an error processing a single request. */ static final int ERROR_CAMERA_REQUEST = 3; public static final int ERROR_CAMERA_REQUEST = 3; /** * Camera has encountered an error producing metadata for a single capture */ static final int ERROR_CAMERA_RESULT = 4; public static final int ERROR_CAMERA_RESULT = 4; /** * Camera has encountered an error producing an image buffer for a single capture */ static final int ERROR_CAMERA_BUFFER = 5; public static final int ERROR_CAMERA_BUFFER = 5; @Override public IBinder asBinder() { Loading
core/java/android/hardware/camera2/legacy/CameraDeviceState.java +59 −22 Original line number Diff line number Diff line Loading @@ -49,6 +49,9 @@ public class CameraDeviceState { private static final int STATE_IDLE = 3; private static final int STATE_CAPTURING = 4; private static final String[] sStateNames = { "ERROR", "UNCONFIGURED", "CONFIGURING", "IDLE", "CAPTURING"}; private int mCurrentState = STATE_UNCONFIGURED; private int mCurrentError = CameraBinderDecorator.NO_ERROR; Loading @@ -57,6 +60,11 @@ public class CameraDeviceState { private Handler mCurrentHandler = null; private CameraDeviceStateListener mCurrentListener = null; /** * Error code used by {@link #setCaptureStart} and {@link #setCaptureResult} to indicate that no * error has occurred. */ public static final int NO_CAPTURE_ERROR = -1; /** * CameraDeviceStateListener callbacks to be called after state transitions. Loading Loading @@ -126,11 +134,15 @@ public class CameraDeviceState { * * @param request A {@link RequestHolder} containing the request for the current capture. * @param timestamp The timestamp of the capture start in nanoseconds. * @param captureError Report a recoverable error for a single request using a valid * error code for {@code ICameraDeviceCallbacks}, or * {@link #NO_CAPTURE_ERROR} * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. */ public synchronized int setCaptureStart(final RequestHolder request, long timestamp) { public synchronized int setCaptureStart(final RequestHolder request, long timestamp, int captureError) { mCurrentRequest = request; doStateTransition(STATE_CAPTURING, timestamp); doStateTransition(STATE_CAPTURING, timestamp, captureError); return mCurrentError; } Loading @@ -144,12 +156,16 @@ public class CameraDeviceState { * the {@code ERROR} state, * </p> * * @param request the {@link RequestHolder} request that created this result. * @param result the {@link CameraMetadataNative} result to set. * @param request The {@link RequestHolder} request that created this result. * @param result The {@link CameraMetadataNative} result to set. * @param captureError Report a recoverable error for a single buffer or result using a valid * error code for {@code ICameraDeviceCallbacks}, or * {@link #NO_CAPTURE_ERROR}. * @return {@link CameraBinderDecorator#NO_ERROR}, or an error if one has occurred. */ public synchronized int setCaptureResult(final RequestHolder request, final CameraMetadataNative result) { final CameraMetadataNative result, final int captureError) { if (mCurrentState != STATE_CAPTURING) { Log.e(TAG, "Cannot receive result while in state: " + mCurrentState); mCurrentError = CameraBinderDecorator.INVALID_OPERATION; Loading @@ -158,6 +174,14 @@ public class CameraDeviceState { } if (mCurrentHandler != null && mCurrentListener != null) { if (captureError != NO_CAPTURE_ERROR) { mCurrentHandler.post(new Runnable() { @Override public void run() { mCurrentListener.onError(captureError, request); } }); } else { mCurrentHandler.post(new Runnable() { @Override public void run() { Loading @@ -165,6 +189,7 @@ public class CameraDeviceState { } }); } } return mCurrentError; } Loading @@ -181,14 +206,16 @@ public class CameraDeviceState { } private void doStateTransition(int newState) { doStateTransition(newState, /*timestamp*/0); doStateTransition(newState, /*timestamp*/0, CameraBinderDecorator.NO_ERROR); } private void doStateTransition(int newState, final long timestamp) { if (DEBUG) { private void doStateTransition(int newState, final long timestamp, final int error) { if (newState != mCurrentState) { Log.d(TAG, "Transitioning to state " + newState); String stateName = "UNKNOWN"; if (newState >= 0 && newState < sStateNames.length) { stateName = sStateNames[newState]; } Log.i(TAG, "Legacy camera service transitioning to state " + stateName); } switch(newState) { case STATE_ERROR: Loading Loading @@ -251,7 +278,16 @@ public class CameraDeviceState { doStateTransition(STATE_ERROR); break; } if (mCurrentHandler != null && mCurrentListener != null) { if (error != NO_CAPTURE_ERROR) { mCurrentHandler.post(new Runnable() { @Override public void run() { mCurrentListener.onError(error, mCurrentRequest); } }); } else { mCurrentHandler.post(new Runnable() { @Override public void run() { Loading @@ -259,6 +295,7 @@ public class CameraDeviceState { } }); } } mCurrentState = STATE_CAPTURING; break; default: Loading
core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java +57 −1 Original line number Diff line number Diff line Loading @@ -341,6 +341,10 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { Log.d(TAG, "disconnect called."); } if (mLegacyDevice.isClosed()) { Log.w(TAG, "Cannot disconnect, device has already been closed."); } try { mLegacyDevice.close(); } finally { Loading @@ -355,6 +359,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "submitRequest called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot submit request, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot submit request, configuration change in progress."); Loading @@ -370,6 +379,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "submitRequestList called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot submit request list, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot submit request, configuration change in progress."); Loading @@ -384,6 +398,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "cancelRequest called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot cancel request, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot cancel request, configuration change in progress."); Loading @@ -400,6 +419,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "beginConfigure called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot begin configure, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot begin configure, configuration change already in progress."); Loading @@ -415,6 +439,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "endConfigure called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot end configure, device has been closed."); return CameraBinderDecorator.ENODEV; } ArrayList<Surface> surfaces = null; synchronized(mConfigureLock) { if (!mConfiguring) { Loading @@ -438,6 +467,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "deleteStream called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot delete stream, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (!mConfiguring) { Log.e(TAG, "Cannot delete stream, beginConfigure hasn't been called yet."); Loading @@ -458,6 +492,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "createStream called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot create stream, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (!mConfiguring) { Log.e(TAG, "Cannot create stream, beginConfigure hasn't been called yet."); Loading @@ -474,6 +513,10 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "createDefaultRequest called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot create default request, device has been closed."); return CameraBinderDecorator.ENODEV; } CameraMetadataNative template; try { Loading Loading @@ -503,6 +546,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "waitUntilIdle called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot wait until idle, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot wait until idle, configuration change in progress."); Loading @@ -518,13 +566,21 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { if (DEBUG) { Log.d(TAG, "flush called."); } if (mLegacyDevice.isClosed()) { Log.e(TAG, "Cannot flush, device has been closed."); return CameraBinderDecorator.ENODEV; } synchronized(mConfigureLock) { if (mConfiguring) { Log.e(TAG, "Cannot flush, configuration change in progress."); return CameraBinderDecorator.INVALID_OPERATION; } } // TODO: implement flush. long lastFrame = mLegacyDevice.flush(); if (lastFrameNumber != null) { lastFrameNumber.setNumber(lastFrame); } return CameraBinderDecorator.NO_ERROR; } Loading
core/java/android/hardware/camera2/legacy/CaptureCollector.java +171 −9 Original line number Diff line number Diff line Loading @@ -15,12 +15,14 @@ */ package android.hardware.camera2.legacy; import android.hardware.camera2.impl.CameraDeviceImpl; import android.util.Log; import android.util.MutableLong; import android.util.Pair; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.TreeSet; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; Loading @@ -44,7 +46,7 @@ public class CaptureCollector { private static final int MAX_JPEGS_IN_FLIGHT = 1; private class CaptureHolder { private class CaptureHolder implements Comparable<CaptureHolder>{ private final RequestHolder mRequest; private final LegacyRequest mLegacy; public final boolean needsJpeg; Loading @@ -53,6 +55,10 @@ public class CaptureCollector { private long mTimestamp = 0; private int mReceivedFlags = 0; private boolean mHasStarted = false; private boolean mFailedJpeg = false; private boolean mFailedPreview = false; private boolean mCompleted = false; private boolean mPreviewCompleted = false; public CaptureHolder(RequestHolder request, LegacyRequest legacyHolder) { mRequest = request; Loading @@ -74,11 +80,43 @@ public class CaptureCollector { } public void tryComplete() { if (isCompleted()) { if (needsPreview && isPreviewCompleted()) { if (!mPreviewCompleted && needsPreview && isPreviewCompleted()) { CaptureCollector.this.onPreviewCompleted(); mPreviewCompleted = true; } if (isCompleted() && !mCompleted) { if (mFailedPreview || mFailedJpeg) { if (!mHasStarted) { // Send a request error if the capture has not yet started. mRequest.failRequest(); CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp, CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_REQUEST); } else { // Send buffer dropped errors for each pending buffer if the request has // started. if (mFailedPreview) { Log.w(TAG, "Preview buffers dropped for request: " + mRequest.getRequestId()); for (int i = 0; i < mRequest.numPreviewTargets(); i++) { CaptureCollector.this.mDeviceState.setCaptureResult(mRequest, /*result*/null, CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_BUFFER); } } if (mFailedJpeg) { Log.w(TAG, "Jpeg buffers dropped for request: " + mRequest.getRequestId()); for (int i = 0; i < mRequest.numJpegTargets(); i++) { CaptureCollector.this.mDeviceState.setCaptureResult(mRequest, /*result*/null, CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_BUFFER); } } } } CaptureCollector.this.onRequestCompleted(this); CaptureCollector.this.onRequestCompleted(CaptureHolder.this); mCompleted = true; } } Loading @@ -103,7 +141,8 @@ public class CaptureCollector { if (!mHasStarted) { mHasStarted = true; CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp); CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp, CameraDeviceState.NO_CAPTURE_ERROR); } tryComplete(); Loading @@ -126,6 +165,20 @@ public class CaptureCollector { tryComplete(); } public void setJpegFailed() { if (DEBUG) { Log.d(TAG, "setJpegFailed - called for request " + mRequest.getRequestId()); } if (!needsJpeg || isJpegCompleted()) { return; } mFailedJpeg = true; mReceivedFlags |= FLAG_RECEIVED_JPEG; mReceivedFlags |= FLAG_RECEIVED_JPEG_TS; tryComplete(); } public void setPreviewTimestamp(long timestamp) { if (DEBUG) { Log.d(TAG, "setPreviewTimestamp - called for request " + mRequest.getRequestId()); Loading @@ -148,7 +201,8 @@ public class CaptureCollector { if (!needsJpeg) { if (!mHasStarted) { mHasStarted = true; CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp); CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp, CameraDeviceState.NO_CAPTURE_ERROR); } } Loading @@ -171,8 +225,37 @@ public class CaptureCollector { mReceivedFlags |= FLAG_RECEIVED_PREVIEW; tryComplete(); } public void setPreviewFailed() { if (DEBUG) { Log.d(TAG, "setPreviewFailed - called for request " + mRequest.getRequestId()); } if (!needsPreview || isPreviewCompleted()) { return; } mFailedPreview = true; mReceivedFlags |= FLAG_RECEIVED_PREVIEW; mReceivedFlags |= FLAG_RECEIVED_PREVIEW_TS; tryComplete(); } // Comparison and equals based on frame number. @Override public int compareTo(CaptureHolder captureHolder) { return (mRequest.getFrameNumber() > captureHolder.mRequest.getFrameNumber()) ? 1 : ((mRequest.getFrameNumber() == captureHolder.mRequest.getFrameNumber()) ? 0 : -1); } // Comparison and equals based on frame number. @Override public boolean equals(Object o) { return o instanceof CaptureHolder && compareTo((CaptureHolder) o) == 0; } } private final TreeSet<CaptureHolder> mActiveRequests; private final ArrayDeque<CaptureHolder> mJpegCaptureQueue; private final ArrayDeque<CaptureHolder> mJpegProduceQueue; private final ArrayDeque<CaptureHolder> mPreviewCaptureQueue; Loading Loading @@ -200,6 +283,7 @@ public class CaptureCollector { mJpegProduceQueue = new ArrayDeque<>(MAX_JPEGS_IN_FLIGHT); mPreviewCaptureQueue = new ArrayDeque<>(mMaxInFlight); mPreviewProduceQueue = new ArrayDeque<>(mMaxInFlight); mActiveRequests = new TreeSet<>(); mIsEmpty = mLock.newCondition(); mNotFull = mLock.newCondition(); mPreviewsEmpty = mLock.newCondition(); Loading Loading @@ -263,7 +347,7 @@ public class CaptureCollector { mPreviewProduceQueue.add(h); mInFlightPreviews++; } mActiveRequests.add(h); mInFlight++; return true; Loading Loading @@ -440,7 +524,9 @@ public class CaptureCollector { try { CaptureHolder h = mPreviewCaptureQueue.poll(); if (h == null) { Log.w(TAG, "previewCaptured called with no preview request on queue!"); if (DEBUG) { Log.d(TAG, "previewCaptured called with no preview request on queue!"); } return null; } h.setPreviewTimestamp(timestamp); Loading Loading @@ -471,6 +557,81 @@ public class CaptureCollector { } } /** * Called to alert the {@link CaptureCollector} that the next pending preview capture has failed. */ public void failNextPreview() { final ReentrantLock lock = this.mLock; lock.lock(); try { CaptureHolder h1 = mPreviewCaptureQueue.peek(); CaptureHolder h2 = mPreviewProduceQueue.peek(); // Find the request with the lowest frame number. CaptureHolder h = (h1 == null) ? h2 : ((h2 == null) ? h1 : ((h1.compareTo(h2) <= 0) ? h1 : h2)); if (h != null) { mPreviewCaptureQueue.remove(h); mPreviewProduceQueue.remove(h); mActiveRequests.remove(h); h.setPreviewFailed(); } } finally { lock.unlock(); } } /** * Called to alert the {@link CaptureCollector} that the next pending jpeg capture has failed. */ public void failNextJpeg() { final ReentrantLock lock = this.mLock; lock.lock(); try { CaptureHolder h1 = mJpegCaptureQueue.peek(); CaptureHolder h2 = mJpegProduceQueue.peek(); // Find the request with the lowest frame number. CaptureHolder h = (h1 == null) ? h2 : ((h2 == null) ? h1 : ((h1.compareTo(h2) <= 0) ? h1 : h2)); if (h != null) { mJpegCaptureQueue.remove(h); mJpegProduceQueue.remove(h); mActiveRequests.remove(h); h.setJpegFailed(); } } finally { lock.unlock(); } } /** * Called to alert the {@link CaptureCollector} all pending captures have failed. */ public void failAll() { final ReentrantLock lock = this.mLock; lock.lock(); try { CaptureHolder h; while ((h = mActiveRequests.pollFirst()) != null) { h.setPreviewFailed(); h.setJpegFailed(); } mPreviewCaptureQueue.clear(); mPreviewProduceQueue.clear(); mJpegCaptureQueue.clear(); mJpegProduceQueue.clear(); } finally { lock.unlock(); } } private void onPreviewCompleted() { mInFlightPreviews--; if (mInFlightPreviews < 0) { Loading @@ -496,6 +657,7 @@ public class CaptureCollector { } mCompletedRequests.add(capture); mActiveRequests.remove(capture); mNotFull.signalAll(); if (mInFlight == 0) { Loading
core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +72 −9 File changed.Preview size limit exceeded, changes collapsed. Show changes