Merge "Camera2: Add support for partial result metadata quirk" into klp-dev

This commit is contained in:
Eino-Ville Talvala
2013-11-12 18:27:06 +00:00
committed by Android (Google) Code Review
4 changed files with 105 additions and 5 deletions

View File

@ -332,6 +332,27 @@ public final class CameraCharacteristics extends CameraMetadata {
public static final Key<Integer> LENS_FACING =
new Key<Integer>("android.lens.facing", int.class);
/**
* <p>
* If set to 1, the HAL will always split result
* metadata for a single capture into multiple buffers,
* returned using multiple process_capture_result calls.
* </p>
* <p>
* Does not need to be listed in static
* metadata. Support for partial results will be reworked in
* future versions of camera service. This quirk will stop
* working at that point; DO NOT USE without careful
* consideration of future support.
* </p>
*
* <b>Optional</b> - This value may be null on some devices.
*
* @hide
*/
public static final Key<Byte> QUIRKS_USE_PARTIAL_RESULT =
new Key<Byte>("android.quirks.usePartialResult", byte.class);
/**
* <p>
* How many output streams can be allocated at

View File

@ -630,6 +630,36 @@ public interface CameraDevice extends AutoCloseable {
// default empty implementation
}
/**
* This method is called when some results from an image capture are
* available.
*
* <p>The result provided here will contain some subset of the fields of
* a full result. Multiple onCapturePartial calls may happen per
* capture; a given result field will only be present in one partial
* capture at most. The final onCaptureCompleted call will always
* contain all the fields, whether onCapturePartial was called or
* not.</p>
*
* <p>The default implementation of this method does nothing.</p>
*
* @param camera The CameraDevice sending the callback.
* @param request The request that was given to the CameraDevice
* @param result The partial output metadata from the capture, which
* includes a subset of the CaptureResult fields.
*
* @see #capture
* @see #captureBurst
* @see #setRepeatingRequest
* @see #setRepeatingBurst
*
* @hide
*/
public void onCapturePartial(CameraDevice camera,
CaptureRequest request, CaptureResult result) {
// default empty implementation
}
/**
* This method is called when an image capture has completed and the
* result metadata is available.

View File

@ -589,6 +589,32 @@ public final class CaptureResult extends CameraMetadata {
public static final Key<Integer> NOISE_REDUCTION_MODE =
new Key<Integer>("android.noiseReduction.mode", int.class);
/**
* <p>
* Whether a result given to the framework is the
* final one for the capture, or only a partial that contains a
* subset of the full set of dynamic metadata
* values.
* </p>
* <p>
* The entries in the result metadata buffers for a
* single capture may not overlap, except for this entry. The
* FINAL buffers must retain FIFO ordering relative to the
* requests that generate them, so the FINAL buffer for frame 3 must
* always be sent to the framework after the FINAL buffer for frame 2, and
* before the FINAL buffer for frame 4. PARTIAL buffers may be returned
* in any order relative to other frames, but all PARTIAL buffers for a given
* capture must arrive before the FINAL buffer for that capture. This entry may
* only be used by the HAL if quirks.usePartialResult is set to 1.
* </p>
*
* <b>Optional</b> - This value may be null on some devices.
*
* @hide
*/
public static final Key<Boolean> QUIRKS_PARTIAL_RESULT =
new Key<Boolean>("android.quirks.partialResult", boolean.class);
/**
* <p>
* A frame counter set by the framework. This value monotonically

View File

@ -577,6 +577,9 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice {
}
final CaptureListenerHolder holder;
Boolean quirkPartial = result.get(CaptureResult.QUIRKS_PARTIAL_RESULT);
boolean quirkIsPartialResult = (quirkPartial != null && quirkPartial);
synchronized (mLock) {
// TODO: move this whole map into this class to make it more testable,
// exposing the methods necessary like subscribeToRequest, unsubscribe..
@ -585,7 +588,7 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice {
holder = CameraDevice.this.mCaptureListenerMap.get(requestId);
// Clean up listener once we no longer expect to see it.
if (holder != null && !holder.isRepeating()) {
if (holder != null && !holder.isRepeating() && !quirkIsPartialResult) {
CameraDevice.this.mCaptureListenerMap.remove(requestId);
}
@ -595,7 +598,7 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice {
// If we received a result for a repeating request and have
// prior repeating requests queued for deletion, remove those
// requests from mCaptureListenerMap.
if (holder != null && holder.isRepeating()
if (holder != null && holder.isRepeating() && !quirkIsPartialResult
&& mRepeatingRequestIdDeletedList.size() > 0) {
Iterator<Integer> iter = mRepeatingRequestIdDeletedList.iterator();
while (iter.hasNext()) {
@ -619,8 +622,25 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice {
final CaptureRequest request = holder.getRequest();
final CaptureResult resultAsCapture = new CaptureResult(result, request, requestId);
holder.getHandler().post(
new Runnable() {
Runnable resultDispatch = null;
// Either send a partial result or the final capture completed result
if (quirkIsPartialResult) {
// Partial result
resultDispatch = new Runnable() {
@Override
public void run() {
if (!CameraDevice.this.isClosed()){
holder.getListener().onCapturePartial(
CameraDevice.this,
request,
resultAsCapture);
}
}
};
} else {
// Final capture result
resultDispatch = new Runnable() {
@Override
public void run() {
if (!CameraDevice.this.isClosed()){
@ -630,7 +650,10 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice {
resultAsCapture);
}
}
});
};
}
holder.getHandler().post(resultDispatch);
}
}