From 14c09fa3c5371b977c77e5813eabb81941040627 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Wed, 15 Jul 2015 16:04:04 -0700 Subject: Camera2: Add hidden experimental tearDown method Bug: 18949148 Change-Id: I6264d95a26ebf51cce6114c9a86b9561f7c60ab5 --- .../hardware/camera2/CameraCaptureSession.java | 39 ++++++++++++++++++++++ .../hardware/camera2/ICameraDeviceUser.aidl | 2 ++ .../camera2/impl/CameraCaptureSessionImpl.java | 5 +++ ...meraConstrainedHighSpeedCaptureSessionImpl.java | 5 +++ .../hardware/camera2/impl/CameraDeviceImpl.java | 25 ++++++++++++++ .../camera2/legacy/CameraDeviceUserShim.java | 14 ++++++++ 6 files changed, 90 insertions(+) (limited to 'core/java/android/hardware') diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index 46cafad..46ffe36 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -138,6 +138,45 @@ public abstract class CameraCaptureSession implements AutoCloseable { */ public abstract void prepare(@NonNull Surface surface) throws CameraAccessException; + + /** + *

Free all buffers allocated for an output Surface.

+ * + *

Normally, once allocated, the image buffers for a given output Surface remain allocated + * for the lifetime of the capture session, to minimize latency of captures and to reduce + * memory allocation overhead.

+ * + *

However, in some cases, it may be desirable for allocated buffers to be freed to reduce + * the application's memory consumption, if the particular output Surface will not be used by + * the application for some time.

+ * + *

The tearDown() method can be used to perform this operation. After the call finishes, all + * unfilled image buffers will have been freed. Any future use of the target Surface may require + * allocation of additional buffers, as if the session had just been created. Buffers being + * held by the application (either explicitly as Image objects from ImageReader, or implicitly + * as the current texture in a SurfaceTexture or the current contents of a RS Allocation, will + * remain valid and allocated even when tearDown is invoked.

+ * + *

A Surface that has had tearDown() called on it is eligible to have prepare() invoked on it + * again even if it was used as a request target before the tearDown() call, as long as it + * doesn't get used as a target of a request between the tearDown() and prepare() calls.

+ * + * @param surface the output Surface for which buffers should be freed. Must be one of the + * the output Surfaces used to create this session. + * + * @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. + * @throws IllegalArgumentException if the Surface is invalid, not part of this Session, or has + * already been used as a target of a CaptureRequest in this + * session or immediately prior sessions. + * + * @hide + */ + public abstract void tearDown(@NonNull Surface surface) throws CameraAccessException; + /** *

Submit a request for an image to be captured by the camera device.

* diff --git a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl index 1574f93..7cb3673 100644 --- a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl +++ b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl @@ -100,4 +100,6 @@ interface ICameraDeviceUser int flush(out LongParcelable lastFrameNumber); int prepare(int streamId); + + int tearDown(int streamId); } diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java index 3c19cd2..d325c77 100644 --- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java @@ -146,6 +146,11 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession } @Override + public void tearDown(Surface surface) throws CameraAccessException { + mDeviceImpl.tearDown(surface); + } + + @Override public synchronized int capture(CaptureRequest request, CaptureCallback callback, Handler handler) throws CameraAccessException { if (request == null) { diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java index d732535..a920e2b 100644 --- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java @@ -169,6 +169,11 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl } @Override + public void tearDown(Surface surface) throws CameraAccessException { + mSessionImpl.tearDown(surface); + } + + @Override public int capture(CaptureRequest request, CaptureCallback listener, Handler handler) throws CameraAccessException { throw new UnsupportedOperationException("Constrained high speed session doesn't support" diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index c594228..91d623e 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -679,6 +679,31 @@ public class CameraDeviceImpl extends CameraDevice { } } + public void tearDown(Surface surface) throws CameraAccessException { + if (surface == null) throw new IllegalArgumentException("Surface is null"); + + synchronized(mInterfaceLock) { + int streamId = -1; + for (int i = 0; i < mConfiguredOutputs.size(); i++) { + if (surface == mConfiguredOutputs.valueAt(i).getSurface()) { + streamId = mConfiguredOutputs.keyAt(i); + break; + } + } + if (streamId == -1) { + throw new IllegalArgumentException("Surface is not part of this session"); + } + try { + mRemoteDevice.tearDown(streamId); + } catch (CameraRuntimeException e) { + throw e.asChecked(); + } catch (RemoteException e) { + // impossible + return; + } + } + } + public int capture(CaptureRequest request, CaptureCallback callback, Handler handler) throws CameraAccessException { if (DEBUG) { diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java index f5314da..e20eaa7 100644 --- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java +++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java @@ -636,6 +636,20 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { return CameraBinderDecorator.NO_ERROR; } + public int tearDown(int streamId) { + if (DEBUG) { + Log.d(TAG, "tearDown called."); + } + if (mLegacyDevice.isClosed()) { + Log.e(TAG, "Cannot tear down stream, device has been closed."); + return CameraBinderDecorator.ENODEV; + } + + // LEGACY doesn't support actual teardown, so just a no-op + + return CameraBinderDecorator.NO_ERROR; + } + @Override public IBinder asBinder() { // This is solely intended to be used for in-process binding. -- cgit v1.1