OSDN Git Service

Camera2: Add CameraDevice#flush()
authorEino-Ville Talvala <etalvala@google.com>
Tue, 13 Aug 2013 19:09:44 +0000 (12:09 -0700)
committerEino-Ville Talvala <etalvala@google.com>
Fri, 23 Aug 2013 21:20:35 +0000 (14:20 -0700)
- For quickly clearing out all pending and in-progress captures

Bug: 9758581
Change-Id: Ie4123fcc4d4b648a11d4a6257c531f07182bab39

api/current.txt
core/java/android/hardware/camera2/CameraDevice.java
core/java/android/hardware/camera2/ICameraDeviceUser.aidl
core/java/android/hardware/camera2/impl/CameraDevice.java
media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java

index 936eb39..585912e 100644 (file)
@@ -10715,6 +10715,7 @@ package android.hardware.camera2 {
     method public abstract void close() throws java.lang.Exception;
     method public abstract void configureOutputs(java.util.List<android.view.Surface>) throws android.hardware.camera2.CameraAccessException;
     method public abstract android.hardware.camera2.CaptureRequest createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
+    method public abstract void flush() throws android.hardware.camera2.CameraAccessException;
     method public abstract android.hardware.camera2.CameraProperties getProperties() throws android.hardware.camera2.CameraAccessException;
     method public abstract void setErrorListener(android.hardware.camera2.CameraDevice.ErrorListener);
     method public abstract void setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener) throws android.hardware.camera2.CameraAccessException;
index 848d7bc..a4a56d7 100644 (file)
@@ -303,7 +303,8 @@ public interface CameraDevice extends AutoCloseable {
      * preview or other continuous stream of frames, without having to submit
      * requests through {@link #capture} at video rates.</p>
      *
-     * <p>To stop the repeating capture, call {@link #stopRepeating}</p>
+     * <p>To stop the repeating capture, call {@link #stopRepeating}. Calling
+     * {@link #flush} will also clear the request.</p>
      *
      * <p>Calling repeat will replace a burst set up by {@link
      * #setRepeatingBurst}, although any in-progress burst will be
@@ -323,6 +324,8 @@ public interface CameraDevice extends AutoCloseable {
      * @see #capture
      * @see #captureBurst
      * @see #setRepeatingBurst
+     * @see #stopRepeating
+     * @see #flush
      */
     public void setRepeatingRequest(CaptureRequest request, CaptureListener listener)
             throws CameraAccessException;
@@ -348,7 +351,8 @@ public interface CameraDevice extends AutoCloseable {
      * requests through {@link #capture} at video rates.</p>
      *
      * <p>To stop the repeating capture, call {@link #stopRepeating}. Any
-     * ongoing burst will still be completed, however.</p>
+     * ongoing burst will still be completed, however. Calling
+     * {@link #flush} will also clear the request.</p>
      *
      * <p>Calling repeatBurst will replace a repeating request set up by
      * {@link #setRepeatingRequest}, although any in-progress capture will be completed
@@ -367,6 +371,8 @@ public interface CameraDevice extends AutoCloseable {
      * @see #capture
      * @see #captureBurst
      * @see #setRepeatingRequest
+     * @see #stopRepeating
+     * @see #flush
      */
     public void setRepeatingBurst(List<CaptureRequest> requests, CaptureListener listener)
             throws CameraAccessException;
@@ -435,6 +441,38 @@ public interface CameraDevice extends AutoCloseable {
     public void setErrorListener(ErrorListener listener);
 
     /**
+     * Flush all captures currently pending and in-progress as fast as
+     * possible.
+     *
+     * <p>The camera device will discard all of its current work as fast as
+     * possible. Some in-flight captures may complete successfully and call
+     * {@link CaptureListener#onCaptureComplete}, while others will trigger
+     * their {@link CaptureListener#onCaptureFailed} callbacks. If a repeating
+     * request or a repeating burst is set, it will be cleared by the flush.</p>
+     *
+     * <p>This method is the fastest way to idle the camera device for
+     * reconfiguration with {@link #configureOutputs}, at the cost of discarding
+     * in-progress work. Once the flush is complete, the idle callback will be
+     * called.</p>
+     *
+     * <p>Flushing will introduce at least a brief pause in the stream of data
+     * from the camera device, since once the flush is complete, the first new
+     * request has to make it through the entire camera pipeline before new
+     * output buffers are produced.</p>
+     *
+     * <p>This means that using {@code flush()} to simply remove pending
+     * requests is not recommended; it's best used for quickly switching output
+     * configurations, or for cancelling long in-progress requests (such as a
+     * multi-second capture).</p>
+     *
+     * @throws CameraAccessException if the camera device is no longer connected
+     * @see #setRepeatingRequest
+     * @see #setRepeatingBurst
+     * @see #configureOutputs
+     */
+    public void flush() throws CameraAccessException;
+
+    /**
      * Close the connection to this camera device. After this call, all calls to
      * the camera device interface will throw a {@link IllegalStateException},
      * except for calls to close().
index 5a9b72f..b1724de 100644 (file)
@@ -45,4 +45,6 @@ interface ICameraDeviceUser
     int getCameraInfo(out CameraMetadata info);
 
     int waitUntilIdle();
+
+    int flush();
 }
index e7495d3..ee199bc 100644 (file)
@@ -242,6 +242,20 @@ public class CameraDevice implements android.hardware.camera2.CameraDevice {
     }
 
     @Override
+    public void flush() throws CameraAccessException {
+        synchronized (mLock) {
+            try {
+                mRemoteDevice.flush();
+            } catch (CameraRuntimeException e) {
+                throw e.asChecked();
+            } catch (RemoteException e) {
+                // impossible
+                return;
+            }
+        }
+    }
+
+    @Override
     public void close() throws Exception {
 
         // TODO: every method should throw IllegalStateException after close has been called
index 722087c..2f271bb 100644 (file)
@@ -309,4 +309,34 @@ public class CameraDeviceBinderTest extends AndroidTestCase {
                         argThat(matcher));
         request.close();
     }
+
+    @SmallTest
+    public void testFlush() throws Exception {
+        int status;
+
+        // Initial flush should work
+        status = mCameraUser.flush();
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+        // Then set up a stream
+        CaptureRequest request = createDefaultRequest(/* needStream */true);
+
+        // Flush should still be a no-op, really
+        status = mCameraUser.flush();
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+        // Submit a few capture requests
+        int requestId1 = submitCameraRequest(request, /* streaming */false);
+        int requestId2 = submitCameraRequest(request, /* streaming */false);
+        int requestId3 = submitCameraRequest(request, /* streaming */false);
+        int requestId4 = submitCameraRequest(request, /* streaming */false);
+        int requestId5 = submitCameraRequest(request, /* streaming */false);
+
+        // Then flush
+        status = mCameraUser.flush();
+        assertEquals(CameraBinderTestUtils.NO_ERROR, status);
+
+        // TODO: When errors are hooked up, count that errors + successful
+        // requests equal to 5.
+    }
 }