Loading core/java/android/hardware/camera2/CameraCharacteristics.java +21 −0 Original line number Diff line number Diff line Loading @@ -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 Loading core/java/android/hardware/camera2/CameraDevice.java +30 −0 Original line number Diff line number Diff line Loading @@ -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. Loading core/java/android/hardware/camera2/CaptureResult.java +26 −0 Original line number Diff line number Diff line Loading @@ -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 Loading core/java/android/hardware/camera2/impl/CameraDevice.java +28 −5 Original line number Diff line number Diff line Loading @@ -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.. Loading @@ -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); } Loading @@ -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()) { Loading @@ -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()){ Loading @@ -630,7 +650,10 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { resultAsCapture); } } }); }; } holder.getHandler().post(resultDispatch); } } Loading Loading
core/java/android/hardware/camera2/CameraCharacteristics.java +21 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/android/hardware/camera2/CameraDevice.java +30 −0 Original line number Diff line number Diff line Loading @@ -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. Loading
core/java/android/hardware/camera2/CaptureResult.java +26 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/android/hardware/camera2/impl/CameraDevice.java +28 −5 Original line number Diff line number Diff line Loading @@ -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.. Loading @@ -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); } Loading @@ -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()) { Loading @@ -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()){ Loading @@ -630,7 +650,10 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice { resultAsCapture); } } }); }; } holder.getHandler().post(resultDispatch); } } Loading