Merge changes I6de585de,Id0f9b5a9 am: c681633836
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1438913 Change-Id: Id1f8c73f4e8e54c1056d988716cc58a914a259d3
This commit is contained in:
@@ -37,12 +37,16 @@ public class FrameNumberTracker {
|
|||||||
/** the completed frame number for each type of capture results */
|
/** the completed frame number for each type of capture results */
|
||||||
private long[] mCompletedFrameNumber = new long[CaptureRequest.REQUEST_TYPE_COUNT];
|
private long[] mCompletedFrameNumber = new long[CaptureRequest.REQUEST_TYPE_COUNT];
|
||||||
|
|
||||||
/** the skipped frame numbers that don't belong to each type of capture results */
|
/** the frame numbers that don't belong to each type of capture results and are yet to be seen
|
||||||
private final LinkedList<Long>[] mSkippedOtherFrameNumbers =
|
* through an updateTracker() call. Each list holds a list of frame numbers that should appear
|
||||||
|
* with request types other than that, to which the list corresponds.
|
||||||
|
*/
|
||||||
|
private final LinkedList<Long>[] mPendingFrameNumbersWithOtherType =
|
||||||
new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
|
new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
|
||||||
|
|
||||||
/** the skipped frame numbers that belong to each type of capture results */
|
/** the frame numbers that belong to each type of capture results which should appear, but
|
||||||
private final LinkedList<Long>[] mSkippedFrameNumbers =
|
* haven't yet.*/
|
||||||
|
private final LinkedList<Long>[] mPendingFrameNumbers =
|
||||||
new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
|
new LinkedList[CaptureRequest.REQUEST_TYPE_COUNT];
|
||||||
|
|
||||||
/** frame number -> request type */
|
/** frame number -> request type */
|
||||||
@@ -53,8 +57,8 @@ public class FrameNumberTracker {
|
|||||||
public FrameNumberTracker() {
|
public FrameNumberTracker() {
|
||||||
for (int i = 0; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
|
for (int i = 0; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
|
||||||
mCompletedFrameNumber[i] = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
|
mCompletedFrameNumber[i] = CameraCaptureSession.CaptureCallback.NO_FRAMES_CAPTURED;
|
||||||
mSkippedOtherFrameNumbers[i] = new LinkedList<Long>();
|
mPendingFrameNumbersWithOtherType[i] = new LinkedList<Long>();
|
||||||
mSkippedFrameNumbers[i] = new LinkedList<Long>();
|
mPendingFrameNumbers[i] = new LinkedList<Long>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,29 +70,29 @@ public class FrameNumberTracker {
|
|||||||
int requestType = (int) pair.getValue();
|
int requestType = (int) pair.getValue();
|
||||||
Boolean removeError = false;
|
Boolean removeError = false;
|
||||||
if (errorFrameNumber == mCompletedFrameNumber[requestType] + 1) {
|
if (errorFrameNumber == mCompletedFrameNumber[requestType] + 1) {
|
||||||
mCompletedFrameNumber[requestType] = errorFrameNumber;
|
|
||||||
removeError = true;
|
removeError = true;
|
||||||
|
}
|
||||||
|
// The error frame number could have also either been in the pending list or one of the
|
||||||
|
// 'other' pending lists.
|
||||||
|
if (!mPendingFrameNumbers[requestType].isEmpty()) {
|
||||||
|
if (errorFrameNumber == mPendingFrameNumbers[requestType].element()) {
|
||||||
|
mPendingFrameNumbers[requestType].remove();
|
||||||
|
removeError = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!mSkippedFrameNumbers[requestType].isEmpty()) {
|
for (int i = 1; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
|
||||||
if (errorFrameNumber == mSkippedFrameNumbers[requestType].element()) {
|
int otherType = (requestType + i) % CaptureRequest.REQUEST_TYPE_COUNT;
|
||||||
mCompletedFrameNumber[requestType] = errorFrameNumber;
|
if (!mPendingFrameNumbersWithOtherType[otherType].isEmpty() && errorFrameNumber
|
||||||
mSkippedFrameNumbers[requestType].remove();
|
== mPendingFrameNumbersWithOtherType[otherType].element()) {
|
||||||
|
mPendingFrameNumbersWithOtherType[otherType].remove();
|
||||||
removeError = true;
|
removeError = true;
|
||||||
}
|
break;
|
||||||
} else {
|
|
||||||
for (int i = 1; i < CaptureRequest.REQUEST_TYPE_COUNT; i++) {
|
|
||||||
int otherType = (requestType + i) % CaptureRequest.REQUEST_TYPE_COUNT;
|
|
||||||
if (!mSkippedOtherFrameNumbers[otherType].isEmpty() && errorFrameNumber
|
|
||||||
== mSkippedOtherFrameNumbers[otherType].element()) {
|
|
||||||
mCompletedFrameNumber[requestType] = errorFrameNumber;
|
|
||||||
mSkippedOtherFrameNumbers[otherType].remove();
|
|
||||||
removeError = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (removeError) {
|
if (removeError) {
|
||||||
|
mCompletedFrameNumber[requestType] = errorFrameNumber;
|
||||||
|
mPartialResults.remove(errorFrameNumber);
|
||||||
iter.remove();
|
iter.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,7 +186,7 @@ public class FrameNumberTracker {
|
|||||||
* It validates that all previous frames of the same category have arrived.
|
* It validates that all previous frames of the same category have arrived.
|
||||||
*
|
*
|
||||||
* If there is a gap since previous frame number of the same category, assume the frames in
|
* If there is a gap since previous frame number of the same category, assume the frames in
|
||||||
* the gap are other categories and store them in the skipped frame number queue to check
|
* the gap are other categories and store them in the pending frame number queue to check
|
||||||
* against when frames of those categories arrive.
|
* against when frames of those categories arrive.
|
||||||
*/
|
*/
|
||||||
private void updateCompletedFrameNumber(long frameNumber,
|
private void updateCompletedFrameNumber(long frameNumber,
|
||||||
@@ -199,25 +203,29 @@ public class FrameNumberTracker {
|
|||||||
if (frameNumber < maxOtherFrameNumberSeen) {
|
if (frameNumber < maxOtherFrameNumberSeen) {
|
||||||
// if frame number is smaller than completed frame numbers of other categories,
|
// if frame number is smaller than completed frame numbers of other categories,
|
||||||
// it must be:
|
// it must be:
|
||||||
// - the head of mSkippedFrameNumbers for this category, or
|
// - the head of mPendingFrameNumbers for this category, or
|
||||||
// - in one of other mSkippedOtherFrameNumbers
|
// - in one of other mPendingFrameNumbersWithOtherType
|
||||||
if (!mSkippedFrameNumbers[requestType].isEmpty()) {
|
if (!mPendingFrameNumbers[requestType].isEmpty()) {
|
||||||
// frame number must be head of current type of mSkippedFrameNumbers if
|
// frame number must be head of current type of mPendingFrameNumbers if
|
||||||
// mSkippedFrameNumbers isn't empty.
|
// mPendingFrameNumbers isn't empty.
|
||||||
if (frameNumber < mSkippedFrameNumbers[requestType].element()) {
|
Long pendingFrameNumberSameType = mPendingFrameNumbers[requestType].element();
|
||||||
|
if (frameNumber == pendingFrameNumberSameType) {
|
||||||
|
// frame number matches the head of the pending frame number queue.
|
||||||
|
// Do this before the inequality checks since this is likely to be the common
|
||||||
|
// case.
|
||||||
|
mPendingFrameNumbers[requestType].remove();
|
||||||
|
} else if (frameNumber < pendingFrameNumberSameType) {
|
||||||
throw new IllegalArgumentException("frame number " + frameNumber
|
throw new IllegalArgumentException("frame number " + frameNumber
|
||||||
+ " is a repeat");
|
+ " is a repeat");
|
||||||
} else if (frameNumber > mSkippedFrameNumbers[requestType].element()) {
|
} else {
|
||||||
throw new IllegalArgumentException("frame number " + frameNumber
|
throw new IllegalArgumentException("frame number " + frameNumber
|
||||||
+ " comes out of order. Expecting "
|
+ " comes out of order. Expecting "
|
||||||
+ mSkippedFrameNumbers[requestType].element());
|
+ pendingFrameNumberSameType);
|
||||||
}
|
}
|
||||||
// frame number matches the head of the skipped frame number queue.
|
|
||||||
mSkippedFrameNumbers[requestType].remove();
|
|
||||||
} else {
|
} else {
|
||||||
// frame number must be in one of the other mSkippedOtherFrameNumbers.
|
// frame number must be in one of the other mPendingFrameNumbersWithOtherType.
|
||||||
int index1 = mSkippedOtherFrameNumbers[otherType1].indexOf(frameNumber);
|
int index1 = mPendingFrameNumbersWithOtherType[otherType1].indexOf(frameNumber);
|
||||||
int index2 = mSkippedOtherFrameNumbers[otherType2].indexOf(frameNumber);
|
int index2 = mPendingFrameNumbersWithOtherType[otherType2].indexOf(frameNumber);
|
||||||
boolean inSkippedOther1 = index1 != -1;
|
boolean inSkippedOther1 = index1 != -1;
|
||||||
boolean inSkippedOther2 = index2 != -1;
|
boolean inSkippedOther2 = index2 != -1;
|
||||||
if (!(inSkippedOther1 ^ inSkippedOther2)) {
|
if (!(inSkippedOther1 ^ inSkippedOther2)) {
|
||||||
@@ -225,33 +233,39 @@ public class FrameNumberTracker {
|
|||||||
+ " is a repeat or invalid");
|
+ " is a repeat or invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
// We know the category of frame numbers in skippedOtherFrameNumbers leading up
|
// We know the category of frame numbers in pendingFrameNumbersWithOtherType leading
|
||||||
// to the current frame number. Move them into the correct skippedFrameNumbers.
|
// up to the current frame number. The destination is the type which isn't the
|
||||||
|
// requestType* and isn't the src. Move them into the correct pendingFrameNumbers.
|
||||||
|
// * : This is since frameNumber is the first frame of requestType that we've
|
||||||
|
// received in the 'others' list, since for each request type frames come in order.
|
||||||
|
// All the frames before frameNumber are of the same type. They're not of
|
||||||
|
// 'requestType', neither of the type of the 'others' list they were found in. The
|
||||||
|
// remaining option is the 3rd type.
|
||||||
LinkedList<Long> srcList, dstList;
|
LinkedList<Long> srcList, dstList;
|
||||||
int index;
|
int index;
|
||||||
if (inSkippedOther1) {
|
if (inSkippedOther1) {
|
||||||
srcList = mSkippedOtherFrameNumbers[otherType1];
|
srcList = mPendingFrameNumbersWithOtherType[otherType1];
|
||||||
dstList = mSkippedFrameNumbers[otherType2];
|
dstList = mPendingFrameNumbers[otherType2];
|
||||||
index = index1;
|
index = index1;
|
||||||
} else {
|
} else {
|
||||||
srcList = mSkippedOtherFrameNumbers[otherType2];
|
srcList = mPendingFrameNumbersWithOtherType[otherType2];
|
||||||
dstList = mSkippedFrameNumbers[otherType1];
|
dstList = mPendingFrameNumbers[otherType1];
|
||||||
index = index2;
|
index = index2;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < index; i++) {
|
for (int i = 0; i < index; i++) {
|
||||||
dstList.add(srcList.removeFirst());
|
dstList.add(srcList.removeFirst());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove current frame number from skippedOtherFrameNumbers
|
// Remove current frame number from pendingFrameNumbersWithOtherType
|
||||||
srcList.remove();
|
srcList.remove();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// there is a gap of unseen frame numbers which should belong to the other
|
// there is a gap of unseen frame numbers which should belong to the other
|
||||||
// 2 categories. Put all the skipped frame numbers in the queue.
|
// 2 categories. Put all the pending frame numbers in the queue.
|
||||||
for (long i =
|
for (long i =
|
||||||
Math.max(maxOtherFrameNumberSeen, mCompletedFrameNumber[requestType]) + 1;
|
Math.max(maxOtherFrameNumberSeen, mCompletedFrameNumber[requestType]) + 1;
|
||||||
i < frameNumber; i++) {
|
i < frameNumber; i++) {
|
||||||
mSkippedOtherFrameNumbers[requestType].add(i);
|
mPendingFrameNumbersWithOtherType[requestType].add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user