Merge "camera2: allow mixing regular/reprocess requests" into mnc-dev
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index aeddf03..ef71c42 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -212,8 +212,7 @@
* <p>All capture sessions can be used for capturing images from the camera but only capture
* sessions created by
* {@link CameraDevice#createReprocessibleCaptureSession createReprocessibleCaptureSession}
- * can submit reprocess capture requests. The list of requests must all be capturing images from
- * the camera or all be reprocess capture requests. Submitting a reprocess request to a regular
+ * can submit reprocess capture requests. Submitting a reprocess request to a regular
* capture session will result in an {@link IllegalArgumentException}.</p>
*
* @param requests the list of settings for this burst capture
@@ -236,9 +235,7 @@
* @throws IllegalArgumentException If the requests target no Surfaces, or the requests target
* Surfaces not currently configured as outputs; or a reprocess
* capture request is submitted in a non-reprocessible capture
- * session; or the list of requests contains both requests to
- * capture images from the camera and reprocess capture
- * requests; or one of the reprocess capture requests was
+ * session; or one of the reprocess capture requests was
* created with a {@link TotalCaptureResult} from a different
* session; or one of the captures targets a Surface in the
* middle of being {@link #prepare prepared}; or if the handler
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index 3c19529..dff6227 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -177,26 +177,20 @@
public synchronized int captureBurst(List<CaptureRequest> requests, CaptureCallback callback,
Handler handler) throws CameraAccessException {
if (requests == null) {
- throw new IllegalArgumentException("requests must not be null");
+ throw new IllegalArgumentException("Requests must not be null");
} else if (requests.isEmpty()) {
- throw new IllegalArgumentException("requests must have at least one element");
+ throw new IllegalArgumentException("Requests must have at least one element");
}
- boolean reprocess = requests.get(0).isReprocess();
- if (reprocess && !isReprocessible()) {
- throw new IllegalArgumentException("this capture session cannot handle reprocess " +
- "requests");
- } else if (reprocess && requests.get(0).getReprocessibleSessionId() != mId) {
- throw new IllegalArgumentException("capture request was created for another session");
- }
-
- for (int i = 1; i < requests.size(); i++) {
- if (requests.get(i).isReprocess() != reprocess) {
- throw new IllegalArgumentException("cannot mix regular and reprocess capture " +
- " requests");
- } else if (reprocess && requests.get(i).getReprocessibleSessionId() != mId) {
- throw new IllegalArgumentException("capture request was created for another " +
- "session");
+ for (CaptureRequest request : requests) {
+ if (request.isReprocess()) {
+ if (!isReprocessible()) {
+ throw new IllegalArgumentException("This capture session cannot handle " +
+ "reprocess requests");
+ } else if (request.getReprocessibleSessionId() != mId) {
+ throw new IllegalArgumentException("Capture request was created for another " +
+ "session");
+ }
}
}
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index ff4ad79..e84b46a 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -94,11 +94,11 @@
private final int mTotalPartialCount;
/**
- * A list tracking request and its expected last frame.
- * Updated when calling ICameraDeviceUser methods.
+ * A list tracking request and its expected last regular frame number and last reprocess frame
+ * number. Updated when calling ICameraDeviceUser methods.
*/
- private final List<SimpleEntry</*frameNumber*/Long, /*requestId*/Integer>>
- mFrameNumberRequestPairs = new ArrayList<SimpleEntry<Long, Integer>>();
+ private final List<RequestLastFrameNumbersHolder> mRequestLastFrameNumbersList =
+ new ArrayList<>();
/**
* An object tracking received frame numbers.
@@ -653,8 +653,8 @@
*
* <p>If lastFrameNumber is NO_FRAMES_CAPTURED, it means that the request was never
* sent to HAL. Then onCaptureSequenceAborted is immediately triggered.
- * If lastFrameNumber is non-negative, then the requestId and lastFrameNumber pair
- * is added to the list mFrameNumberRequestPairs.</p>
+ * If lastFrameNumber is non-negative, then the requestId and lastFrameNumber as the last
+ * regular frame number will be added to the list mRequestLastFrameNumbersList.</p>
*
* @param requestId the request ID of the current repeating request.
*
@@ -693,10 +693,6 @@
"early trigger sequence complete for request %d",
requestId));
}
- if (lastFrameNumber < Integer.MIN_VALUE
- || lastFrameNumber > Integer.MAX_VALUE) {
- throw new AssertionError(lastFrameNumber + " cannot be cast to int");
- }
holder.getCallback().onCaptureSequenceAborted(
CameraDeviceImpl.this,
requestId);
@@ -710,9 +706,11 @@
requestId));
}
} else {
- mFrameNumberRequestPairs.add(
- new SimpleEntry<Long, Integer>(lastFrameNumber,
- requestId));
+ // This function is only called for regular request so lastFrameNumber is the last
+ // regular frame number.
+ mRequestLastFrameNumbersList.add(new RequestLastFrameNumbersHolder(requestId,
+ lastFrameNumber));
+
// It is possible that the last frame has already arrived, so we need to check
// for sequence completion right away
checkAndFireSequenceComplete();
@@ -779,8 +777,8 @@
}
mRepeatingRequestId = requestId;
} else {
- mFrameNumberRequestPairs.add(
- new SimpleEntry<Long, Integer>(lastFrameNumber, requestId));
+ mRequestLastFrameNumbersList.add(new RequestLastFrameNumbersHolder(requestList,
+ requestId, lastFrameNumber));
}
if (mIdle) {
@@ -1146,7 +1144,101 @@
public int getSessionId() {
return mSessionId;
}
+ }
+ /**
+ * This class holds a capture ID and its expected last regular frame number and last reprocess
+ * frame number.
+ */
+ static class RequestLastFrameNumbersHolder {
+ // request ID
+ private final int mRequestId;
+ // The last regular frame number for this request ID. It's
+ // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no regular request.
+ private final long mLastRegularFrameNumber;
+ // The last reprocess frame number for this request ID. It's
+ // CaptureCallback.NO_FRAMES_CAPTURED if the request ID has no reprocess request.
+ private final long mLastReprocessFrameNumber;
+
+ /**
+ * Create a request-last-frame-numbers holder with a list of requests, request ID, and
+ * the last frame number returned by camera service.
+ */
+ public RequestLastFrameNumbersHolder(List<CaptureRequest> requestList, int requestId,
+ long lastFrameNumber) {
+ long lastRegularFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
+ long lastReprocessFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
+ long frameNumber = lastFrameNumber;
+
+ if (lastFrameNumber < requestList.size() - 1) {
+ throw new IllegalArgumentException("lastFrameNumber: " + lastFrameNumber +
+ " should be at least " + (requestList.size() - 1) + " for the number of " +
+ " requests in the list: " + requestList.size());
+ }
+
+ // find the last regular frame number and the last reprocess frame number
+ for (int i = requestList.size() - 1; i >= 0; i--) {
+ CaptureRequest request = requestList.get(i);
+ if (request.isReprocess() && lastReprocessFrameNumber ==
+ CaptureCallback.NO_FRAMES_CAPTURED) {
+ lastReprocessFrameNumber = frameNumber;
+ } else if (!request.isReprocess() && lastRegularFrameNumber ==
+ CaptureCallback.NO_FRAMES_CAPTURED) {
+ lastRegularFrameNumber = frameNumber;
+ }
+
+ if (lastReprocessFrameNumber != CaptureCallback.NO_FRAMES_CAPTURED &&
+ lastRegularFrameNumber != CaptureCallback.NO_FRAMES_CAPTURED) {
+ break;
+ }
+
+ frameNumber--;
+ }
+
+ mLastRegularFrameNumber = lastRegularFrameNumber;
+ mLastReprocessFrameNumber = lastReprocessFrameNumber;
+ mRequestId = requestId;
+ }
+
+ /**
+ * Create a request-last-frame-numbers holder with a request ID and last regular frame
+ * number.
+ */
+ public RequestLastFrameNumbersHolder(int requestId, long lastRegularFrameNumber) {
+ mLastRegularFrameNumber = lastRegularFrameNumber;
+ mLastReprocessFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
+ mRequestId = requestId;
+ }
+
+ /**
+ * Return the last regular frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
+ * it contains no regular request.
+ */
+ public long getLastRegularFrameNumber() {
+ return mLastRegularFrameNumber;
+ }
+
+ /**
+ * Return the last reprocess frame number. Return CaptureCallback.NO_FRAMES_CAPTURED if
+ * it contains no reprocess request.
+ */
+ public long getLastReprocessFrameNumber() {
+ return mLastReprocessFrameNumber;
+ }
+
+ /**
+ * Return the last frame number overall.
+ */
+ public long getLastFrameNumber() {
+ return Math.max(mLastRegularFrameNumber, mLastReprocessFrameNumber);
+ }
+
+ /**
+ * Return the request ID.
+ */
+ public int getRequestId() {
+ return mRequestId;
+ }
}
/**
@@ -1154,8 +1246,8 @@
*/
public class FrameNumberTracker {
- private long mCompletedFrameNumber = -1;
- private long mCompletedReprocessFrameNumber = -1;
+ private long mCompletedFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
+ private long mCompletedReprocessFrameNumber = CaptureCallback.NO_FRAMES_CAPTURED;
/** the skipped frame numbers that belong to regular results */
private final LinkedList<Long> mSkippedRegularFrameNumbers = new LinkedList<Long>();
/** the skipped frame numbers that belong to reprocess results */
@@ -1360,11 +1452,11 @@
long completedFrameNumber = mFrameNumberTracker.getCompletedFrameNumber();
long completedReprocessFrameNumber = mFrameNumberTracker.getCompletedReprocessFrameNumber();
boolean isReprocess = false;
- Iterator<SimpleEntry<Long, Integer> > iter = mFrameNumberRequestPairs.iterator();
+ Iterator<RequestLastFrameNumbersHolder> iter = mRequestLastFrameNumbersList.iterator();
while (iter.hasNext()) {
- final SimpleEntry<Long, Integer> frameNumberRequestPair = iter.next();
+ final RequestLastFrameNumbersHolder requestLastFrameNumbers = iter.next();
boolean sequenceCompleted = false;
- final int requestId = frameNumberRequestPair.getValue();
+ final int requestId = requestLastFrameNumbers.getRequestId();
final CaptureCallbackHolder holder;
synchronized(mInterfaceLock) {
if (mRemoteDevice == null) {
@@ -1376,19 +1468,22 @@
holder = (index >= 0) ?
mCaptureCallbackMap.valueAt(index) : null;
if (holder != null) {
- isReprocess = holder.getRequest().isReprocess();
+ long lastRegularFrameNumber =
+ requestLastFrameNumbers.getLastRegularFrameNumber();
+ long lastReprocessFrameNumber =
+ requestLastFrameNumbers.getLastReprocessFrameNumber();
+
// check if it's okay to remove request from mCaptureCallbackMap
- if ((isReprocess && frameNumberRequestPair.getKey() <=
- completedReprocessFrameNumber) || (!isReprocess &&
- frameNumberRequestPair.getKey() <= completedFrameNumber)) {
+ if (lastRegularFrameNumber <= completedFrameNumber &&
+ lastReprocessFrameNumber <= completedReprocessFrameNumber) {
sequenceCompleted = true;
mCaptureCallbackMap.removeAt(index);
if (DEBUG) {
Log.v(TAG, String.format(
- "remove holder for requestId %d, "
- + "because lastFrame %d is <= %d",
- requestId, frameNumberRequestPair.getKey(),
- completedFrameNumber));
+ "Remove holder for requestId %d, because lastRegularFrame %d " +
+ "is <= %d and lastReprocessFrame %d is <= %d", requestId,
+ lastRegularFrameNumber, completedFrameNumber,
+ lastReprocessFrameNumber, completedReprocessFrameNumber));
}
}
}
@@ -1412,16 +1507,10 @@
requestId));
}
- long lastFrameNumber = frameNumberRequestPair.getKey();
- if (lastFrameNumber < Integer.MIN_VALUE
- || lastFrameNumber > Integer.MAX_VALUE) {
- throw new AssertionError(lastFrameNumber
- + " cannot be cast to int");
- }
holder.getCallback().onCaptureSequenceCompleted(
CameraDeviceImpl.this,
requestId,
- lastFrameNumber);
+ requestLastFrameNumbers.getLastFrameNumber());
}
}
};