Merge "camera2: Implement TotalCaptureResult#getPartialResults" into lmp-dev

This commit is contained in:
Igor Murashkin
2014-08-29 18:00:38 +00:00
committed by Android (Google) Code Review
2 changed files with 90 additions and 15 deletions

View File

@@ -19,6 +19,7 @@ package android.hardware.camera2;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -48,13 +49,23 @@ import java.util.List;
*/
public final class TotalCaptureResult extends CaptureResult {
private final List<CaptureResult> mPartialResults;
/**
* Takes ownership of the passed-in properties object
* Takes ownership of the passed-in camera metadata and the partial results
*
* @param partials a list of partial results; {@code null} will be substituted for an empty list
* @hide
*/
public TotalCaptureResult(CameraMetadataNative results, CaptureRequest parent,
CaptureResultExtras extras) {
CaptureResultExtras extras, List<CaptureResult> partials) {
super(results, parent, extras);
if (partials == null) {
mPartialResults = new ArrayList<>();
} else {
mPartialResults = partials;
}
}
/**
@@ -65,6 +76,8 @@ public final class TotalCaptureResult extends CaptureResult {
*/
public TotalCaptureResult(CameraMetadataNative results, int sequenceId) {
super(results, sequenceId);
mPartialResults = new ArrayList<>();
}
/**
@@ -73,14 +86,13 @@ public final class TotalCaptureResult extends CaptureResult {
* <p>The list is returned is unmodifiable; attempting to modify it will result in a
* {@code UnsupportedOperationException} being thrown.</p>
*
* <p>The list size will be inclusive between {@code 1} and
* {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT}, in ascending order
* <p>The list size will be inclusive between {@code 0} and
* {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT}, with elements in ascending order
* of when {@link CameraCaptureSession.CaptureListener#onCaptureProgressed} was invoked.</p>
*
* @return unmodifiable list of partial results
*/
public List<CaptureResult> getPartialResults() {
// TODO
return Collections.unmodifiableList(null);
return Collections.unmodifiableList(mPartialResults);
}
}

View File

@@ -41,6 +41,7 @@ import android.view.Surface;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -967,6 +968,8 @@ public class CameraDeviceImpl extends CameraDevice {
private long mCompletedFrameNumber = -1;
private final TreeSet<Long> mFutureErrorSet = new TreeSet<Long>();
/** Map frame numbers to list of partial results */
private final HashMap<Long, List<CaptureResult>> mPartialResults = new HashMap<>();
private void update() {
Iterator<Long> iter = mFutureErrorSet.iterator();
@@ -983,8 +986,8 @@ public class CameraDeviceImpl extends CameraDevice {
/**
* This function is called every time when a result or an error is received.
* @param frameNumber: the frame number corresponding to the result or error
* @param isError: true if it is an error, false if it is not an error
* @param frameNumber the frame number corresponding to the result or error
* @param isError true if it is an error, false if it is not an error
*/
public void updateTracker(long frameNumber, boolean isError) {
if (isError) {
@@ -1006,6 +1009,55 @@ public class CameraDeviceImpl extends CameraDevice {
update();
}
/**
* This function is called every time a result has been completed.
*
* <p>It keeps a track of all the partial results already created for a particular
* frame number.</p>
*
* @param frameNumber the frame number corresponding to the result
* @param result the total or partial result
* @param partial {@true} if the result is partial, {@code false} if total
*/
public void updateTracker(long frameNumber, CaptureResult result, boolean partial) {
if (!partial) {
// Update the total result's frame status as being successful
updateTracker(frameNumber, /*isError*/false);
// Don't keep a list of total results, we don't need to track them
return;
}
if (result == null) {
// Do not record blank results; this also means there will be no total result
// so it doesn't matter that the partials were not recorded
return;
}
// Partial results must be aggregated in-order for that frame number
List<CaptureResult> partials = mPartialResults.get(frameNumber);
if (partials == null) {
partials = new ArrayList<>();
mPartialResults.put(frameNumber, partials);
}
partials.add(result);
}
/**
* Attempt to pop off all of the partial results seen so far for the {@code frameNumber}.
*
* <p>Once popped-off, the partial results are forgotten (unless {@code updateTracker}
* is called again with new partials for that frame number).</p>
*
* @param frameNumber the frame number corresponding to the result
* @return a list of partial results for that frame with at least 1 element,
* or {@code null} if there were no partials recorded for that frame
*/
public List<CaptureResult> popPartialResults(long frameNumber) {
return mPartialResults.remove(frameNumber);
}
public long getCompletedFrameNumber() {
return mCompletedFrameNumber;
}
@@ -1244,12 +1296,6 @@ public class CameraDeviceImpl extends CameraDevice {
boolean isPartialResult =
(resultExtras.getPartialResultCount() < mTotalPartialCount);
// Update tracker (increment counter) when it's not a partial result.
if (!isPartialResult) {
mFrameNumberTracker.updateTracker(frameNumber,
/*error*/false);
}
// Check if we have a listener for this
if (holder == null) {
if (DEBUG) {
@@ -1257,6 +1303,9 @@ public class CameraDeviceImpl extends CameraDevice {
"holder is null, early return at frame "
+ frameNumber);
}
mFrameNumberTracker.updateTracker(frameNumber, /*result*/null, isPartialResult);
return;
}
@@ -1266,6 +1315,8 @@ public class CameraDeviceImpl extends CameraDevice {
"camera is closed, early return at frame "
+ frameNumber);
}
mFrameNumberTracker.updateTracker(frameNumber, /*result*/null, isPartialResult);
return;
}
@@ -1273,6 +1324,8 @@ public class CameraDeviceImpl extends CameraDevice {
Runnable resultDispatch = null;
CaptureResult finalResult;
// Either send a partial result or the final capture completed result
if (isPartialResult) {
final CaptureResult resultAsCapture =
@@ -1290,9 +1343,14 @@ public class CameraDeviceImpl extends CameraDevice {
}
}
};
finalResult = resultAsCapture;
} else {
List<CaptureResult> partialResults =
mFrameNumberTracker.popPartialResults(frameNumber);
final TotalCaptureResult resultAsCapture =
new TotalCaptureResult(result, request, resultExtras);
new TotalCaptureResult(result, request, resultExtras, partialResults);
// Final capture result
resultDispatch = new Runnable() {
@@ -1306,10 +1364,15 @@ public class CameraDeviceImpl extends CameraDevice {
}
}
};
finalResult = resultAsCapture;
}
holder.getHandler().post(resultDispatch);
// Collect the partials for a total result; or mark the frame as totally completed
mFrameNumberTracker.updateTracker(frameNumber, finalResult, isPartialResult);
// Fire onCaptureSequenceCompleted
if (!isPartialResult) {
checkAndFireSequenceComplete();