Loading core/java/android/hardware/camera2/CameraCaptureSession.java +48 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.hardware.camera2; import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.camera2.params.OutputConfiguration; import android.os.Handler; import android.view.Surface; Loading Loading @@ -219,6 +220,53 @@ public abstract class CameraCaptureSession implements AutoCloseable { */ public abstract void tearDown(@NonNull Surface surface) throws CameraAccessException; /** * <p> * Finish the deferred output configurations where the output Surface was not configured before. * </p> * <p> * For camera use cases where a preview and other output configurations need to be configured, * it can take some time for the preview Surface to be ready (e.g., if the preview Surface is * obtained from {@link android.view.SurfaceView}, the SurfaceView is ready after the UI layout * is done, then it takes some time to get the preview Surface). * </p> * <p> * To speed up camera startup time, the application can configure the * {@link CameraCaptureSession} with the desired preview size, and defer the preview output * configuration until the Surface is ready. After the {@link CameraCaptureSession} is created * successfully with this deferred configuration and other normal configurations, the * application can submit requests that don't include deferred output Surfaces. Once the * deferred Surface is ready, the application can set the Surface to the same deferred output * configuration with the {@link OutputConfiguration#setDeferredSurface} method, and then finish * the deferred output configuration via this method, before it can submit requests with this * output target. * </p> * <p> * The output Surfaces included by this list of deferred {@link OutputConfiguration * OutputConfigurations} can be used as {@link CaptureRequest} targets as soon as this call * returns; * </p> * <p> * This method is not supported by Legacy devices. * </p> * * @param deferredOutputConfigs a list of {@link OutputConfiguration OutputConfigurations} that * have had {@link OutputConfiguration#setDeferredSurface setDeferredSurface} invoked * with a valid output Surface. * @throws CameraAccessException if the camera device is no longer connected or has encountered * a fatal error. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created or the camera device has * been closed. Or if this output configuration was already finished with the * included surface before. * @throws IllegalArgumentException for invalid output configurations, including ones where the * source of the Surface is no longer valid or the Surface is from a unsupported * source. * @hide */ public abstract void finishDeferredConfiguration( List<OutputConfiguration> deferredOutputConfigs) throws CameraAccessException; /** * <p>Submit a request for an image to be captured by the camera device.</p> * Loading core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java +7 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.hardware.camera2.dispatch.BroadcastDispatcher; import android.hardware.camera2.dispatch.DuckTypingDispatcher; import android.hardware.camera2.dispatch.HandlerDispatcher; import android.hardware.camera2.dispatch.InvokeDispatcher; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.utils.TaskDrainer; import android.hardware.camera2.utils.TaskSingleDrainer; import android.os.Handler; Loading Loading @@ -155,6 +156,12 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession mDeviceImpl.tearDown(surface); } @Override public void finishDeferredConfiguration( List<OutputConfiguration> deferredOutputConfigs) throws CameraAccessException { mDeviceImpl.finishDeferredConfig(deferredOutputConfigs); } @Override public synchronized int capture(CaptureRequest request, CaptureCallback callback, Handler handler) throws CameraAccessException { Loading core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java +13 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.params.StreamConfigurationMap; import android.hardware.camera2.utils.SurfaceUtils; import android.os.Handler; Loading Loading @@ -256,6 +257,12 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl return mSessionImpl.isAborting(); } @Override public void finishDeferredConfiguration(List<OutputConfiguration> deferredOutputConfigs) throws CameraAccessException { mSessionImpl.finishDeferredConfiguration(deferredOutputConfigs); } private class WrapperCallback extends StateCallback { private final StateCallback mCallback; Loading @@ -263,26 +270,32 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl mCallback = callback; } @Override public void onConfigured(CameraCaptureSession session) { mCallback.onConfigured(CameraConstrainedHighSpeedCaptureSessionImpl.this); } @Override public void onConfigureFailed(CameraCaptureSession session) { mCallback.onConfigureFailed(CameraConstrainedHighSpeedCaptureSessionImpl.this); } @Override public void onReady(CameraCaptureSession session) { mCallback.onReady(CameraConstrainedHighSpeedCaptureSessionImpl.this); } @Override public void onActive(CameraCaptureSession session) { mCallback.onActive(CameraConstrainedHighSpeedCaptureSessionImpl.this); } @Override public void onClosed(CameraCaptureSession session) { mCallback.onClosed(CameraConstrainedHighSpeedCaptureSessionImpl.this); } @Override public void onSurfacePrepared(CameraCaptureSession session, Surface surface) { mCallback.onSurfacePrepared(CameraConstrainedHighSpeedCaptureSessionImpl.this, surface); Loading core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +36 −1 Original line number Diff line number Diff line Loading @@ -407,7 +407,10 @@ public class CameraDeviceImpl extends CameraDevice int streamId = mConfiguredOutputs.keyAt(i); OutputConfiguration outConfig = mConfiguredOutputs.valueAt(i); if (!outputs.contains(outConfig)) { if (!outputs.contains(outConfig) || outConfig.isDeferredConfiguration()) { // Always delete the deferred output configuration when the session // is created, as the deferred output configuration doesn't have unique surface // related identifies. deleteList.add(streamId); } else { addSet.remove(outConfig); // Don't create a stream previously created Loading Loading @@ -744,6 +747,37 @@ public class CameraDeviceImpl extends CameraDevice } } public void finishDeferredConfig(List<OutputConfiguration> deferredConfigs) throws CameraAccessException { if (deferredConfigs == null || deferredConfigs.size() == 0) { throw new IllegalArgumentException("deferred config is null or empty"); } synchronized(mInterfaceLock) { for (OutputConfiguration config : deferredConfigs) { int streamId = -1; for (int i = 0; i < mConfiguredOutputs.size(); i++) { // Have to use equal here, as createCaptureSessionByOutputConfigurations() and // createReprocessableCaptureSessionByConfigurations() do a copy of the configs. if (config.equals(mConfiguredOutputs.valueAt(i))) { streamId = mConfiguredOutputs.keyAt(i); break; } } if (streamId == -1) { throw new IllegalArgumentException("Deferred config is not part of this " + "session"); } if (config.getSurface() == null) { throw new IllegalArgumentException("The deferred config for stream " + streamId + " must have a non-null surface"); } mRemoteDevice.setDeferredConfiguration(streamId, config); } } } public int capture(CaptureRequest request, CaptureCallback callback, Handler handler) throws CameraAccessException { if (DEBUG) { Loading Loading @@ -2037,6 +2071,7 @@ public class CameraDeviceImpl extends CameraDevice * * <p> Handle binder death for ICameraDeviceUser. Trigger onError.</p> */ @Override public void binderDied() { Log.w(TAG, "CameraDevice " + mCameraId + " died unexpectedly"); Loading core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java +9 −0 Original line number Diff line number Diff line Loading @@ -215,5 +215,14 @@ public class ICameraDeviceUserWrapper { } } public void setDeferredConfiguration(int streamId, OutputConfiguration deferredConfig) throws CameraAccessException { try { mRemoteDevice.setDeferredConfiguration(streamId, deferredConfig); } catch (Throwable t) { CameraManager.throwAsPublicException(t); throw new UnsupportedOperationException("Unexpected exception", t); } } } Loading
core/java/android/hardware/camera2/CameraCaptureSession.java +48 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.hardware.camera2; import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.camera2.params.OutputConfiguration; import android.os.Handler; import android.view.Surface; Loading Loading @@ -219,6 +220,53 @@ public abstract class CameraCaptureSession implements AutoCloseable { */ public abstract void tearDown(@NonNull Surface surface) throws CameraAccessException; /** * <p> * Finish the deferred output configurations where the output Surface was not configured before. * </p> * <p> * For camera use cases where a preview and other output configurations need to be configured, * it can take some time for the preview Surface to be ready (e.g., if the preview Surface is * obtained from {@link android.view.SurfaceView}, the SurfaceView is ready after the UI layout * is done, then it takes some time to get the preview Surface). * </p> * <p> * To speed up camera startup time, the application can configure the * {@link CameraCaptureSession} with the desired preview size, and defer the preview output * configuration until the Surface is ready. After the {@link CameraCaptureSession} is created * successfully with this deferred configuration and other normal configurations, the * application can submit requests that don't include deferred output Surfaces. Once the * deferred Surface is ready, the application can set the Surface to the same deferred output * configuration with the {@link OutputConfiguration#setDeferredSurface} method, and then finish * the deferred output configuration via this method, before it can submit requests with this * output target. * </p> * <p> * The output Surfaces included by this list of deferred {@link OutputConfiguration * OutputConfigurations} can be used as {@link CaptureRequest} targets as soon as this call * returns; * </p> * <p> * This method is not supported by Legacy devices. * </p> * * @param deferredOutputConfigs a list of {@link OutputConfiguration OutputConfigurations} that * have had {@link OutputConfiguration#setDeferredSurface setDeferredSurface} invoked * with a valid output Surface. * @throws CameraAccessException if the camera device is no longer connected or has encountered * a fatal error. * @throws IllegalStateException if this session is no longer active, either because the session * was explicitly closed, a new session has been created or the camera device has * been closed. Or if this output configuration was already finished with the * included surface before. * @throws IllegalArgumentException for invalid output configurations, including ones where the * source of the Surface is no longer valid or the Surface is from a unsupported * source. * @hide */ public abstract void finishDeferredConfiguration( List<OutputConfiguration> deferredOutputConfigs) throws CameraAccessException; /** * <p>Submit a request for an image to be captured by the camera device.</p> * Loading
core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java +7 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.hardware.camera2.dispatch.BroadcastDispatcher; import android.hardware.camera2.dispatch.DuckTypingDispatcher; import android.hardware.camera2.dispatch.HandlerDispatcher; import android.hardware.camera2.dispatch.InvokeDispatcher; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.utils.TaskDrainer; import android.hardware.camera2.utils.TaskSingleDrainer; import android.os.Handler; Loading Loading @@ -155,6 +156,12 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession mDeviceImpl.tearDown(surface); } @Override public void finishDeferredConfiguration( List<OutputConfiguration> deferredOutputConfigs) throws CameraAccessException { mDeviceImpl.finishDeferredConfig(deferredOutputConfigs); } @Override public synchronized int capture(CaptureRequest request, CaptureCallback callback, Handler handler) throws CameraAccessException { Loading
core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java +13 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.params.StreamConfigurationMap; import android.hardware.camera2.utils.SurfaceUtils; import android.os.Handler; Loading Loading @@ -256,6 +257,12 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl return mSessionImpl.isAborting(); } @Override public void finishDeferredConfiguration(List<OutputConfiguration> deferredOutputConfigs) throws CameraAccessException { mSessionImpl.finishDeferredConfiguration(deferredOutputConfigs); } private class WrapperCallback extends StateCallback { private final StateCallback mCallback; Loading @@ -263,26 +270,32 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl mCallback = callback; } @Override public void onConfigured(CameraCaptureSession session) { mCallback.onConfigured(CameraConstrainedHighSpeedCaptureSessionImpl.this); } @Override public void onConfigureFailed(CameraCaptureSession session) { mCallback.onConfigureFailed(CameraConstrainedHighSpeedCaptureSessionImpl.this); } @Override public void onReady(CameraCaptureSession session) { mCallback.onReady(CameraConstrainedHighSpeedCaptureSessionImpl.this); } @Override public void onActive(CameraCaptureSession session) { mCallback.onActive(CameraConstrainedHighSpeedCaptureSessionImpl.this); } @Override public void onClosed(CameraCaptureSession session) { mCallback.onClosed(CameraConstrainedHighSpeedCaptureSessionImpl.this); } @Override public void onSurfacePrepared(CameraCaptureSession session, Surface surface) { mCallback.onSurfacePrepared(CameraConstrainedHighSpeedCaptureSessionImpl.this, surface); Loading
core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +36 −1 Original line number Diff line number Diff line Loading @@ -407,7 +407,10 @@ public class CameraDeviceImpl extends CameraDevice int streamId = mConfiguredOutputs.keyAt(i); OutputConfiguration outConfig = mConfiguredOutputs.valueAt(i); if (!outputs.contains(outConfig)) { if (!outputs.contains(outConfig) || outConfig.isDeferredConfiguration()) { // Always delete the deferred output configuration when the session // is created, as the deferred output configuration doesn't have unique surface // related identifies. deleteList.add(streamId); } else { addSet.remove(outConfig); // Don't create a stream previously created Loading Loading @@ -744,6 +747,37 @@ public class CameraDeviceImpl extends CameraDevice } } public void finishDeferredConfig(List<OutputConfiguration> deferredConfigs) throws CameraAccessException { if (deferredConfigs == null || deferredConfigs.size() == 0) { throw new IllegalArgumentException("deferred config is null or empty"); } synchronized(mInterfaceLock) { for (OutputConfiguration config : deferredConfigs) { int streamId = -1; for (int i = 0; i < mConfiguredOutputs.size(); i++) { // Have to use equal here, as createCaptureSessionByOutputConfigurations() and // createReprocessableCaptureSessionByConfigurations() do a copy of the configs. if (config.equals(mConfiguredOutputs.valueAt(i))) { streamId = mConfiguredOutputs.keyAt(i); break; } } if (streamId == -1) { throw new IllegalArgumentException("Deferred config is not part of this " + "session"); } if (config.getSurface() == null) { throw new IllegalArgumentException("The deferred config for stream " + streamId + " must have a non-null surface"); } mRemoteDevice.setDeferredConfiguration(streamId, config); } } } public int capture(CaptureRequest request, CaptureCallback callback, Handler handler) throws CameraAccessException { if (DEBUG) { Loading Loading @@ -2037,6 +2071,7 @@ public class CameraDeviceImpl extends CameraDevice * * <p> Handle binder death for ICameraDeviceUser. Trigger onError.</p> */ @Override public void binderDied() { Log.w(TAG, "CameraDevice " + mCameraId + " died unexpectedly"); Loading
core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java +9 −0 Original line number Diff line number Diff line Loading @@ -215,5 +215,14 @@ public class ICameraDeviceUserWrapper { } } public void setDeferredConfiguration(int streamId, OutputConfiguration deferredConfig) throws CameraAccessException { try { mRemoteDevice.setDeferredConfiguration(streamId, deferredConfig); } catch (Throwable t) { CameraManager.throwAsPublicException(t); throw new UnsupportedOperationException("Unexpected exception", t); } } }