summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2023-08-14 15:40:28 -0700
committerXin Li <delphij@google.com>2023-08-14 15:40:28 -0700
commit824677fd594bc9442ff7e0b32bb0572d60d56471 (patch)
treeda0417ebd1cd17c2ec214fb4e75bfb8c80d5b089
parented86b838842d3b3b111450ef47de08d588e82964 (diff)
parent036ec921b1119ea9796d996e642ed28d8723d40c (diff)
downloadex-824677fd594bc9442ff7e0b32bb0572d60d56471.tar.gz
Merge Android U (ab/10368041)
Bug: 291102124 Merged-In: I7dac45bdf2c5c00004f39a274f981c2c242c26a2 Change-Id: I582fccbfdd95520e0be118afda1a1436bce6d8e0
-rw-r--r--camera2/extensions/advancedSample/Android.bp2
-rw-r--r--camera2/extensions/advancedSample/jarjar-rules.txt1
-rwxr-xr-xcamera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java24
-rwxr-xr-xcamera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java5
-rwxr-xr-xcamera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java25
-rwxr-xr-xcamera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java5
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java24
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java5
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java50
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ExtenderStateListener.java17
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java4
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java25
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java5
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java55
-rwxr-xr-xcamera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java25
-rwxr-xr-xcamera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java5
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ProcessResultImpl.java17
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java31
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/BaseAdvancedExtenderImpl.java93
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java11
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java16
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java1
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java12
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java35
-rw-r--r--camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java115
-rwxr-xr-xcamera2/extensions/sample/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java51
-rwxr-xr-xcamera2/extensions/sample/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java6
-rwxr-xr-xcamera2/extensions/sample/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java51
-rwxr-xr-xcamera2/extensions/sample/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java6
-rw-r--r--camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java141
-rw-r--r--camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java6
-rw-r--r--camera2/extensions/sample/src/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java50
-rw-r--r--camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ExtenderStateListener.java17
-rw-r--r--camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java2
-rw-r--r--camera2/extensions/sample/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java70
-rw-r--r--camera2/extensions/sample/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java52
-rw-r--r--camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java56
-rwxr-xr-xcamera2/extensions/sample/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java51
-rwxr-xr-xcamera2/extensions/sample/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java6
-rw-r--r--camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ProcessResultImpl.java18
-rwxr-xr-xcamera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java24
-rwxr-xr-xcamera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java5
-rwxr-xr-xcamera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java25
-rwxr-xr-xcamera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java5
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java24
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java5
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java50
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java16
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java25
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java5
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java55
-rwxr-xr-xcamera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java25
-rwxr-xr-xcamera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java5
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ProcessResultImpl.java17
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java31
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java16
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/BeautyAdvancedExtenderImpl.java16
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/BokehAdvancedExtenderImpl.java16
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java12
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java16
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java16
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java16
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java35
-rw-r--r--camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java115
-rw-r--r--camera2/public/src/com/android/ex/camera2/blocking/BlockingCameraManager.java16
65 files changed, 1735 insertions, 47 deletions
diff --git a/camera2/extensions/advancedSample/Android.bp b/camera2/extensions/advancedSample/Android.bp
index bf5ca793..9f0df8e4 100644
--- a/camera2/extensions/advancedSample/Android.bp
+++ b/camera2/extensions/advancedSample/Android.bp
@@ -22,9 +22,11 @@ java_library {
static_libs: [
"androidx.annotation_annotation"
],
+ exclude_kotlinc_generated_files: true,
srcs: ["src/**/*.java"],
sdk_version: "current",
vendor: true,
+ jarjar_rules: "jarjar-rules.txt",
}
prebuilt_etc {
diff --git a/camera2/extensions/advancedSample/jarjar-rules.txt b/camera2/extensions/advancedSample/jarjar-rules.txt
new file mode 100644
index 00000000..7442cef5
--- /dev/null
+++ b/camera2/extensions/advancedSample/jarjar-rules.txt
@@ -0,0 +1 @@
+rule kotlin.** androidx.camera.extensions.impl.advanced.@0 \ No newline at end of file
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
index ccb0dacf..bd605708 100755
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
@@ -95,6 +95,11 @@ public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderI
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
@Nullable
@Override
public Range<Long> getEstimatedCaptureLatencyRange(@NonNull Size captureOutputSize) {
@@ -113,4 +118,23 @@ public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderI
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
index 100f6658..0c4577a4 100755
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
@@ -93,4 +93,9 @@ public final class AutoPreviewExtenderImpl implements PreviewExtenderImpl {
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
index 2d266390..50c80407 100755
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
@@ -95,6 +95,11 @@ public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtende
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
@Nullable
@Override
public Range<Long> getEstimatedCaptureLatencyRange(@NonNull Size captureOutputSize) {
@@ -112,4 +117,24 @@ public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtende
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
index bc3e48dd..1f501745 100755
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
@@ -93,4 +93,9 @@ public final class BeautyPreviewExtenderImpl implements PreviewExtenderImpl {
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
index 66c5839d..ee777cf9 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
@@ -95,6 +95,11 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
@Nullable
@Override
public Range<Long> getEstimatedCaptureLatencyRange(@NonNull Size captureOutputSize) {
@@ -113,4 +118,23 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
index ff588623..1dc5ed79 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
@@ -91,4 +91,9 @@ public final class BokehPreviewExtenderImpl implements PreviewExtenderImpl {
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
index 3eee146a..f4719b8b 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
@@ -21,6 +21,7 @@ import android.graphics.ImageFormat;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.util.Pair;
+import android.util.Size;
import android.view.Surface;
import java.util.Map;
@@ -46,6 +47,29 @@ public interface CaptureProcessorImpl extends ProcessorImpl {
void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
/**
+ * Informs the CaptureProcessorImpl where it should write the postview output to.
+ * This will only be invoked once if a valid postview surface was set.
+ *
+ * @param surface A valid {@link ImageFormat#YUV_420_888} {@link Surface}
+ * that the CaptureProcessorImpl should write data into.
+ * @since 1.4
+ */
+ void onPostviewOutputSurface(Surface surface);
+
+ /**
+ * Invoked when the Camera Framework changes the configured output resolution for
+ * still capture and postview.
+ *
+ * <p>After this call, {@link CaptureProcessorImpl} should expect any {@link Image} received as
+ * input for still capture and postview to be at the specified resolutions.
+ *
+ * @param size for the surface for still capture.
+ * @param postviewSize for the surface for postview.
+ * @since 1.4
+ */
+ void onResolutionUpdate(Size size, Size postviewSize);
+
+ /**
* Process a set images captured that were requested.
*
* <p> The result of the processing step should be written to the {@link Surface} that was
@@ -63,4 +87,30 @@ public interface CaptureProcessorImpl extends ProcessorImpl {
*/
void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
ProcessResultImpl resultCallback, Executor executor);
+
+ /**
+ * Process a set images captured that were requested for both postview and
+ * still capture.
+ *
+ * <p> This processing method will be called if a postview was requested, therefore the
+ * processed postview should be written to the
+ * {@link Surface} received by {@link #onPostviewOutputSurface(Surface, int)}.
+ * The final result of the processing step should be written to the {@link Surface} that was
+ * received by {@link #onOutputSurface(Surface, int)}. Since postview should be available
+ * before the capture, it should be processed and written to the surface before
+ * the final capture is processed.
+ *
+ * @param results The map of {@link ImageFormat#YUV_420_888} format images and
+ * metadata to process. The {@link Image} that are contained within
+ * the map will become invalid after this method completes, so no
+ * references to them should be kept.
+ * @param resultCallback Capture result callback to be called once the capture result
+ * values of the processed image are ready.
+ * @param executor The executor to run the callback on. If null then the callback
+ * will run on any arbitrary executor.
+ * @throws RuntimeException if postview feature is not supported
+ * @since 1.4
+ */
+ void processWithPostview(Map<Integer, Pair<Image, TotalCaptureResult>> results,
+ ProcessResultImpl resultCallback, Executor executor);
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ExtenderStateListener.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ExtenderStateListener.java
index 2879568f..3a88ab2e 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ExtenderStateListener.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ExtenderStateListener.java
@@ -80,4 +80,21 @@ public interface ExtenderStateListener {
* @return The request information to customize the session.
*/
CaptureStageImpl onDisableSession();
+
+ /**
+ * This will be invoked before the {@link android.hardware.camera2.CameraCaptureSession} is
+ * initialized and must return a valid camera session type
+ * {@link android.hardware.camera2.params.SessionConfiguration#getSessionType}
+ * to be used to configure camera capture session. Both the preview and the image capture
+ * extender must return the same session type value for a specific extension type. If there
+ * is inconsistency between the session type values from preview and image extenders, then
+ * the session configuration will fail.
+ *
+ *
+ * @since 1.4
+ * @return Camera capture session type. Regular and vendor specific types are supported but
+ * not high speed values. The extension can return -1 in which case the camera capture session
+ * will be configured to use the default regular type.
+ */
+ int onSessionType();
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
index e3dc9932..1f285720 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
@@ -29,7 +29,7 @@ import android.util.Log;
*/
public class ExtensionVersionImpl {
private static final String TAG = "ExtenderVersionImpl";
- private static final String VERSION = "1.3.0";
+ private static final String VERSION = "1.4.0";
/**
* @hide
@@ -71,4 +71,4 @@ public class ExtensionVersionImpl {
public boolean isAdvancedExtenderImplemented() {
return true;
}
-} \ No newline at end of file
+}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
index f1191dcf..f3fd2f3b 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
@@ -95,6 +95,11 @@ public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderIm
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
@Nullable
@Override
public Range<Long> getEstimatedCaptureLatencyRange(@NonNull Size captureOutputSize) {
@@ -112,4 +117,24 @@ public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderIm
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
index 0eb4a610..af484646 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
@@ -93,4 +93,9 @@ public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl {
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
index 88bd105a..70c1804e 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
@@ -85,6 +85,21 @@ public interface ImageCaptureExtenderImpl extends ExtenderStateListener {
List<Pair<Integer, Size[]>> getSupportedResolutions();
/**
+ * Returns the customized supported postview resolutions for a still capture using
+ * its size.
+ *
+ * <p>Pair list composed with {@link ImageFormat} and {@link Size} array will be returned.
+ *
+ * <p>The returned resolutions should be subset of the supported sizes retrieved from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap} for the camera device.
+ *
+ * @return the customized supported resolutions, or null to support all sizes retrieved from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap}.
+ * @since 1.4
+ */
+ List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize);
+
+ /**
* Returns the estimated capture latency range in milliseconds for the target capture
* resolution.
*
@@ -159,4 +174,44 @@ public interface ImageCaptureExtenderImpl extends ExtenderStateListener {
* @since 1.3
*/
List<CaptureResult.Key> getAvailableCaptureResultKeys();
+
+ /**
+ * Advertise support for {@link ProcessResultImpl#onCaptureProcessProgressed}.
+ *
+ * @return {@code true} in case the process progress callback is supported and is expected to
+ * be triggered, {@code false} otherwise.
+ * @since 1.4
+ */
+ boolean isCaptureProcessProgressAvailable();
+
+ /**
+ * Returns the dynamically calculated capture latency pair in milliseconds.
+ *
+ * <p>In contrast to {@link #getEstimatedCaptureLatencyRange} this method is guaranteed to be
+ * called after the camera capture session is initialized and camera preview is enabled.
+ * The measurement is expected to take in to account dynamic parameters such as the current
+ * scene, the state of 3A algorithms, the state of internal HW modules and return a more
+ * accurate assessment of the still capture latency.</p>
+ *
+ * @return pair that includes the estimated input frame/frames camera capture latency as the
+ * first field and the estimated post-processing latency {@link CaptureProcessorImpl#process}
+ * as the second pair field. Both first and second fields will be in milliseconds. The total
+ * still capture latency will be the sum of both the first and second values.
+ * The pair is expected to be null if the dynamic latency estimation is not supported.
+ * If clients have not configured a still capture output, then this method can also return a
+ * null pair.
+ * @since 1.4
+ */
+ Pair<Long, Long> getRealtimeCaptureLatency();
+
+ /**
+ * Indicates whether the extension supports the postview for still capture feature.
+ * If the extension is using HAL processing, false should be returned since the
+ * postview feature is not currently supported for this case.
+ *
+ * @return {@code true} in case postview for still capture is supported
+ * {@code false} otherwise.
+ * @since 1.4
+ */
+ boolean isPostviewAvailable();
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
index c8ac9788..6f0eaef9 100755
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
@@ -95,6 +95,11 @@ public final class NightImageCaptureExtenderImpl implements ImageCaptureExtender
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
@Nullable
@Override
public Range<Long> getEstimatedCaptureLatencyRange(@NonNull Size captureOutputSize) {
@@ -112,4 +117,24 @@ public final class NightImageCaptureExtenderImpl implements ImageCaptureExtender
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
index a5809f6b..825994f5 100755
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
@@ -93,4 +93,9 @@ public final class NightPreviewExtenderImpl implements PreviewExtenderImpl {
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ProcessResultImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ProcessResultImpl.java
index d0e3605d..0e154450 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ProcessResultImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/ProcessResultImpl.java
@@ -25,7 +25,6 @@ import java.util.List;
/**
* Allows clients to receive information about the capture result values of processed frames.
*
- * @since 1.3
*/
@SuppressLint("UnknownNullness")
public interface ProcessResultImpl {
@@ -40,6 +39,22 @@ public interface ProcessResultImpl {
* must also be passed as part of this callback. Both Camera2 and
* CameraX guarantee that those two settings and results are always
* supported and applied by the corresponding framework.
+ * @since 1.3
*/
void onCaptureCompleted(long shutterTimestamp, List<Pair<CaptureResult.Key, Object>> result);
+
+ /**
+ * Capture progress callback that needs to be called when the process capture is
+ * ongoing and includes the estimated progress of the processing.
+ *
+ * <p>Extensions must ensure that they always call this callback with monotonically increasing
+ * values.</p>
+ *
+ * <p>Extensions are allowed to trigger this callback multiple times but at the minimum the
+ * callback is expected to be called once when processing is done with value 100.</p>
+ *
+ * @param progress Value between 0 and 100.
+ * @since 1.4
+ */
+ void onCaptureProcessProgressed(int progress);
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
index f5335e05..abcbf5fd 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
@@ -124,6 +124,17 @@ public interface AdvancedExtenderImpl {
Map<Integer, List<Size>> getSupportedCaptureOutputResolutions(String cameraId);
/**
+ * Returns supported output format/size map for postview image. OEM is required to support
+ * both JPEG and YUV_420_888 format output.
+ *
+ * <p>The surface created with this supported format/size could configure
+ * intermediate surfaces(YUV/RAW..) and write the output to the output surface.</p>
+ *
+ * @since 1.4
+ */
+ Map<Integer, List<Size>> getSupportedPostviewResolutions(Size captureSize);
+
+ /**
* Returns supported output sizes for Image Analysis (YUV_420_888 format).
*
* <p>OEM can optionally support a YUV surface for ImageAnalysis along with Preview/ImageCapture
@@ -185,4 +196,24 @@ public interface AdvancedExtenderImpl {
* @since 1.3
*/
List<CaptureResult.Key> getAvailableCaptureResultKeys();
+
+ /**
+ * Advertise support for {@link SessionProcessorImpl#onCaptureProcessProgressed}.
+ *
+ * @return {@code true} in case the process progress callback is supported and is expected to
+ * be triggered, {@code false} otherwise.
+ * @since 1.4
+ */
+ boolean isCaptureProcessProgressAvailable();
+
+ /**
+ * Indicates whether the extension supports the postview for still capture feature.
+ * If the extension is using HAL processing, false should be returned since the
+ * postview feature is not currently supported for this case.
+ *
+ * @return {@code true} in case postview for still capture is supported
+ * {@code false} otherwise.
+ * @since 1.4
+ */
+ boolean isPostviewAvailable();
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/BaseAdvancedExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/BaseAdvancedExtenderImpl.java
index 6758a325..00b57058 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/BaseAdvancedExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/BaseAdvancedExtenderImpl.java
@@ -116,6 +116,11 @@ public abstract class BaseAdvancedExtenderImpl implements AdvancedExtenderImpl {
}
@Override
+ public Map<Integer, List<Size>> getSupportedPostviewResolutions(Size captureSize) {
+ return new HashMap<>();
+ }
+
+ @Override
public List<Size> getSupportedYuvAnalysisResolutions(
String cameraId) {
return null;
@@ -161,14 +166,12 @@ public abstract class BaseAdvancedExtenderImpl implements AdvancedExtenderImpl {
public Camera2SessionConfigImpl initSession(@NonNull String cameraId,
@NonNull Map<String, CameraCharacteristics> cameraCharacteristicsMap,
@NonNull Context context,
- @NonNull OutputSurfaceImpl previewSurfaceConfig,
- @NonNull OutputSurfaceImpl imageCaptureSurfaceConfig,
- @Nullable OutputSurfaceImpl imageAnalysisSurfaceConfig) {
+ @NonNull OutputSurfaceConfigurationImpl surfaceConfigs) {
Log.d(TAG, "initSession cameraId=" + cameraId);
- mPreviewOutputSurfaceConfig = previewSurfaceConfig;
- mCaptureOutputSurfaceConfig = imageCaptureSurfaceConfig;
+ mPreviewOutputSurfaceConfig = surfaceConfigs.getPreviewOutputSurface();
+ mCaptureOutputSurfaceConfig = surfaceConfigs.getImageCaptureOutputSurface();
Camera2SessionConfigImplBuilder builder =
new Camera2SessionConfigImplBuilder()
@@ -180,7 +183,7 @@ public abstract class BaseAdvancedExtenderImpl implements AdvancedExtenderImpl {
previewOutputConfigBuilder =
Camera2OutputConfigImplBuilder.newSurfaceConfig(
- previewSurfaceConfig.getSurface());
+ mPreviewOutputSurfaceConfig.getSurface());
mPreviewOutputConfig = previewOutputConfigBuilder.build();
@@ -193,7 +196,7 @@ public abstract class BaseAdvancedExtenderImpl implements AdvancedExtenderImpl {
captureOutputConfigBuilder =
Camera2OutputConfigImplBuilder.newImageReaderConfig(
- imageCaptureSurfaceConfig.getSize(),
+ mCaptureOutputSurfaceConfig.getSize(),
ImageFormat.YUV_420_888,
BASIC_CAPTURE_PROCESS_MAX_IMAGES);
@@ -207,6 +210,24 @@ public abstract class BaseAdvancedExtenderImpl implements AdvancedExtenderImpl {
return builder.build();
}
+ @Override
+ public Camera2SessionConfigImpl initSession(@NonNull String cameraId,
+ @NonNull Map<String, CameraCharacteristics> cameraCharacteristicsMap,
+ @NonNull Context context,
+ @NonNull OutputSurfaceImpl previewSurfaceConfig,
+ @NonNull OutputSurfaceImpl imageCaptureSurfaceConfig,
+ @Nullable OutputSurfaceImpl imageAnalysisSurfaceConfig) {
+
+ // Since this sample impl uses version 1.4, the other initSession method will be
+ // called. This is just a sample for earlier versions if wanting to redirect this call.
+ OutputSurfaceConfigurationImplImpl surfaceConfigs =
+ new OutputSurfaceConfigurationImplImpl(previewSurfaceConfig,
+ imageCaptureSurfaceConfig, imageAnalysisSurfaceConfig,
+ null /*postviewSurfaceConfig*/);
+
+ return initSession(cameraId, cameraCharacteristicsMap, context, surfaceConfigs);
+ }
+
protected void addSessionParameter(Camera2SessionConfigImplBuilder builder) {
// default empty implementation
}
@@ -437,6 +458,11 @@ public abstract class BaseAdvancedExtenderImpl implements AdvancedExtenderImpl {
}
@Override
+ public int startCaptureWithPostview(@NonNull CaptureCallback captureCallback) {
+ return startCapture(captureCallback);
+ }
+
+ @Override
public int startCapture(@NonNull CaptureCallback captureCallback) {
List<RequestProcessorImpl.Request> requestList = new ArrayList<>();
addCaptureRequestParameters(requestList);
@@ -484,6 +510,7 @@ public abstract class BaseAdvancedExtenderImpl implements AdvancedExtenderImpl {
@Override
public void onCaptureSequenceCompleted(int sequenceId, long frameNumber) {
captureCallback.onCaptureSequenceCompleted(seqId);
+ captureCallback.onCaptureProcessProgressed(100);
}
@Override
@@ -599,6 +626,48 @@ public abstract class BaseAdvancedExtenderImpl implements AdvancedExtenderImpl {
public void abortCapture(int captureSequenceId) {
}
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ return null;
+ }
+ }
+
+ public static class OutputSurfaceConfigurationImplImpl implements OutputSurfaceConfigurationImpl {
+ private OutputSurfaceImpl mOutputPreviewSurfaceImpl;
+ private OutputSurfaceImpl mOutputImageCaptureSurfaceImpl;
+ private OutputSurfaceImpl mOutputImageAnalysisSurfaceImpl;
+ private OutputSurfaceImpl mOutputPostviewSurfaceImpl;
+
+ public OutputSurfaceConfigurationImplImpl(OutputSurfaceImpl previewSurfaceConfig,
+ OutputSurfaceImpl imageCaptureSurfaceConfig,
+ OutputSurfaceImpl imageAnalysisSurfaceConfig,
+ OutputSurfaceImpl postviewSurfaceConfig) {
+ mOutputPreviewSurfaceImpl = previewSurfaceConfig;
+ mOutputImageCaptureSurfaceImpl = imageCaptureSurfaceConfig;
+ mOutputImageAnalysisSurfaceImpl = imageAnalysisSurfaceConfig;
+ mOutputPostviewSurfaceImpl = postviewSurfaceConfig;
+ }
+
+ @Override
+ public OutputSurfaceImpl getPreviewOutputSurface() {
+ return mOutputPreviewSurfaceImpl;
+ }
+
+ @Override
+ public OutputSurfaceImpl getImageCaptureOutputSurface() {
+ return mOutputImageCaptureSurfaceImpl;
+ }
+
+ @Override
+ public OutputSurfaceImpl getImageAnalysisOutputSurface() {
+ return mOutputImageAnalysisSurfaceImpl;
+ }
+
+ @Override
+ public OutputSurfaceImpl getPostviewOutputSurface() {
+ return mOutputPostviewSurfaceImpl;
+ }
}
@Override
@@ -617,4 +686,14 @@ public abstract class BaseAdvancedExtenderImpl implements AdvancedExtenderImpl {
CaptureResult.JPEG_ORIENTATION};
return Arrays.asList(CAPTURE_RESULT_SET);
}
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ return true;
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ return false;
+ }
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
index 47a0d226..6fb45bca 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
@@ -43,4 +43,15 @@ public interface Camera2SessionConfigImpl {
* {@link android.hardware.camera2.params.SessionConfiguration#setSessionParameters}.
*/
int getSessionTemplateId();
+
+ /**
+ * Retrieves the session type to be used when initializing the
+ * {@link android.hardware.camera2.CameraCaptureSession}.
+ *
+ * @since 1.4
+ * @return Camera capture session type. Regular and vendor specific types are supported but
+ * not high speed values. The extension can return -1 in which case the camera capture session
+ * will be configured to use the default regular type.
+ */
+ int getSessionType();
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
index a3011666..dc1feccd 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
@@ -20,6 +20,7 @@ package androidx.camera.extensions.impl.advanced;
import android.annotation.SuppressLint;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.SessionConfiguration;
import java.util.ArrayList;
import java.util.HashMap;
@@ -32,6 +33,7 @@ import java.util.Map;
@SuppressLint("UnknownNullness")
public class Camera2SessionConfigImplBuilder {
private int mSessionTemplateId = CameraDevice.TEMPLATE_PREVIEW;
+ private int mSessionType = SessionConfiguration.SESSION_REGULAR;
Map<CaptureRequest.Key<?>, Object> mSessionParameters = new HashMap<>();
List<Camera2OutputConfigImpl> mCamera2OutputConfigs = new ArrayList<>();
@@ -86,6 +88,13 @@ public class Camera2SessionConfigImplBuilder {
}
/**
+ * Gets the camera capture session type.
+ */
+ public int getSessionType() {
+ return mSessionType;
+ }
+
+ /**
* Builds a {@link Camera2SessionConfigImpl} instance.
*/
public Camera2SessionConfigImpl build() {
@@ -95,6 +104,7 @@ public class Camera2SessionConfigImplBuilder {
private static class Camera2SessionConfigImplImpl implements
Camera2SessionConfigImpl {
int mSessionTemplateId;
+ int mSessionType;
Map<CaptureRequest.Key<?>, Object> mSessionParameters;
List<Camera2OutputConfigImpl> mCamera2OutputConfigs;
@@ -102,6 +112,7 @@ public class Camera2SessionConfigImplBuilder {
mSessionTemplateId = builder.getSessionTemplateId();
mSessionParameters = builder.getSessionParameters();
mCamera2OutputConfigs = builder.getCamera2OutputConfigs();
+ mSessionType = builder.getSessionType();
}
@Override
@@ -118,6 +129,11 @@ public class Camera2SessionConfigImplBuilder {
public int getSessionTemplateId() {
return mSessionTemplateId;
}
+
+ @Override
+ public int getSessionType() {
+ return mSessionType;
+ }
}
}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
index 6d9e013d..d8b99289 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
@@ -176,6 +176,7 @@ public class HdrAdvancedExtenderImpl extends BaseAdvancedExtenderImpl {
@Override
public void onCaptureSequenceCompleted(int sequenceId, long frameNumber) {
captureCallback.onCaptureSequenceCompleted(seqId);
+ captureCallback.onCaptureProcessProgressed(100);
}
@Override
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
index 31c79404..82940635 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
@@ -86,14 +86,12 @@ public class NightAdvancedExtenderImpl extends BaseAdvancedExtenderImpl {
public Camera2SessionConfigImpl initSession(@NonNull String cameraId,
@NonNull Map<String, CameraCharacteristics> cameraCharacteristicsMap,
@NonNull Context context,
- @NonNull OutputSurfaceImpl previewSurfaceConfig,
- @NonNull OutputSurfaceImpl imageCaptureSurfaceConfig,
- @Nullable OutputSurfaceImpl imageAnalysisSurfaceConfig) {
+ @NonNull OutputSurfaceConfigurationImpl surfaceConfigs) {
Log.d(TAG, "initSession cameraId=" + cameraId);
- mPreviewOutputSurfaceConfig = previewSurfaceConfig;
- mCaptureOutputSurfaceConfig = imageCaptureSurfaceConfig;
+ mPreviewOutputSurfaceConfig = surfaceConfigs.getPreviewOutputSurface();
+ mCaptureOutputSurfaceConfig = surfaceConfigs.getImageCaptureOutputSurface();
Camera2SessionConfigImplBuilder builder =
new Camera2SessionConfigImplBuilder()
@@ -105,7 +103,7 @@ public class NightAdvancedExtenderImpl extends BaseAdvancedExtenderImpl {
previewOutputConfigBuilder =
Camera2OutputConfigImplBuilder.newImageReaderConfig(
- previewSurfaceConfig.getSize(),
+ mPreviewOutputSurfaceConfig.getSize(),
ImageFormat.YUV_420_888,
BASIC_CAPTURE_PROCESS_MAX_IMAGES);
@@ -120,7 +118,7 @@ public class NightAdvancedExtenderImpl extends BaseAdvancedExtenderImpl {
captureOutputConfigBuilder =
Camera2OutputConfigImplBuilder.newImageReaderConfig(
- imageCaptureSurfaceConfig.getSize(),
+ mCaptureOutputSurfaceConfig.getSize(),
ImageFormat.YUV_420_888,
BASIC_CAPTURE_PROCESS_MAX_IMAGES);
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java
new file mode 100644
index 00000000..ca3832e3
--- /dev/null
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl.advanced;
+
+import android.annotation.SuppressLint;
+
+/**
+ * For specifying the output surface configurations for the extension.
+ *
+ * since 1.4
+ */
+@SuppressLint("UnknownNullness")
+public interface OutputSurfaceConfigurationImpl {
+ public OutputSurfaceImpl getPreviewOutputSurface();
+
+ public OutputSurfaceImpl getImageCaptureOutputSurface();
+
+ public OutputSurfaceImpl getImageAnalysisOutputSurface();
+
+ public OutputSurfaceImpl getPostviewOutputSurface();
+}
diff --git a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java
index fabfc2bf..8dbfadc2 100644
--- a/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java
+++ b/camera2/extensions/advancedSample/src/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
+import android.util.Pair;
import android.view.Surface;
import java.util.Map;
@@ -64,9 +65,59 @@ public interface SessionProcessorImpl {
* preparing a CameraCaptureSession. After initSession() is called, the camera ID,
* cameraCharacteristics and context will not change until deInitSession() has been called.
*
- * <p>CameraX specifies the output surface configurations for preview, image capture and image
- * analysis[optional]. And OEM returns a {@link Camera2SessionConfigImpl} which consists of a
- * list of {@link Camera2OutputConfigImpl} and session parameters. The
+ * <p>CameraX / Camera2 specifies the output surface configurations for preview using
+ * {@link OutputSurfaceConfigurationImpl#getPreviewOutputSurface}, image capture using
+ * {@link OutputSurfaceConfigurationImpl#getImageCaptureOutputSurface}, and image analysis
+ * [optional] using {@link OutputSurfaceConfigurationImpl#getImageAnalysisOutputSurface}.
+ * And OEM returns a {@link Camera2SessionConfigImpl} which consists of a list of
+ * {@link Camera2OutputConfigImpl} and session parameters. The {@link Camera2SessionConfigImpl}
+ * will be used to configure the CameraCaptureSession.
+ *
+ * <p>OEM is responsible for outputting correct camera images output to these output surfaces.
+ * OEM can have the following options to enable the output:
+ * <pre>
+ * (1) Add these output surfaces in CameraCaptureSession directly using
+ * {@link Camera2OutputConfigImplBuilder#newSurfaceConfig(Surface)} }. Processing is done in
+ * HAL.
+ *
+ * (2) Use surface sharing with other surface by calling
+ * {@link Camera2OutputConfigImplBuilder#addSurfaceSharingOutputConfig(Camera2OutputConfigImpl)}
+ * to add the output surface to the other {@link Camera2OutputConfigImpl}.
+ *
+ * (3) Process output from other surfaces (RAW, YUV..) and write the result to the output
+ * surface. The output surface won't be contained in the returned
+ * {@link Camera2SessionConfigImpl}.
+ * </pre>
+ *
+ * <p>{@link Camera2OutputConfigImplBuilder} and {@link Camera2SessionConfigImplBuilder}
+ * implementations are provided in the stub for OEM to construct the
+ * {@link Camera2OutputConfigImpl} and {@link Camera2SessionConfigImpl} instances.
+ *
+ * @param surfaceConfigs contains output surfaces for preview, image capture, and an
+ * optional output config for image analysis (YUV_420_888).
+ * @return a {@link Camera2SessionConfigImpl} consisting of a list of
+ * {@link Camera2OutputConfigImpl} and session parameters which will decide the
+ * {@link android.hardware.camera2.params.SessionConfiguration} for configuring the
+ * CameraCaptureSession. Please note that the OutputConfiguration list may not be part of any
+ * supported or mandatory stream combination BUT OEM must ensure this list will always
+ * produce a valid camera capture session.
+ *
+ * @since 1.4
+ */
+ Camera2SessionConfigImpl initSession(
+ String cameraId,
+ Map<String, CameraCharacteristics> cameraCharacteristicsMap,
+ Context context,
+ OutputSurfaceConfigurationImpl surfaceConfigs);
+
+ /**
+ * Initializes the session for the extension. This is where the OEMs allocate resources for
+ * preparing a CameraCaptureSession. After initSession() is called, the camera ID,
+ * cameraCharacteristics and context will not change until deInitSession() has been called.
+ *
+ * <p>CameraX / Camera2 specifies the output surface configurations for preview, image capture
+ * and image analysis[optional]. And OEM returns a {@link Camera2SessionConfigImpl} which
+ * consists of a list of {@link Camera2OutputConfigImpl} and session parameters. The
* {@link Camera2SessionConfigImpl} will be used to configure the CameraCaptureSession.
*
* <p>OEM is responsible for outputting correct camera images output to these output surfaces.
@@ -173,6 +224,26 @@ public interface SessionProcessorImpl {
void stopRepeating();
/**
+ * Start a multi-frame capture with a postview. {@link #startCapture(CaptureCallback)}
+ * will be used for captures without a postview request.
+ *
+ * Postview will be available before the capture. Upon postview completion,
+ * {@code OnImageAvailableListener#onImageAvailable} will be called on the ImageReader
+ * that creates the postview output surface. When the capture is completed,
+ * {@link CaptureCallback#onCaptureSequenceCompleted} is called and
+ * {@code OnImageAvailableListener#onImageAvailable} will also be called on the ImageReader
+ * that creates the image capture output surface.
+ *
+ * <p>Only one capture can perform at a time. Starting a capture when another capture is
+ * running will cause onCaptureFailed to be called immediately.
+ *
+ * @param callback a callback to report the status.
+ * @return the id of the capture sequence.
+ * @since 1.4
+ */
+ int startCaptureWithPostview(CaptureCallback callback);
+
+ /**
* Start a multi-frame capture.
*
* When the capture is completed, {@link CaptureCallback#onCaptureSequenceCompleted}
@@ -193,6 +264,29 @@ public interface SessionProcessorImpl {
void abortCapture(int captureSequenceId);
/**
+ * Returns the dynamically calculated capture latency pair in milliseconds.
+ *
+ * <p>In contrast to {@link AdvancedExtenderImpl#getEstimatedCaptureLatencyRange} this method is
+ * guaranteed to be called after {@link #onCaptureSessionStart}.
+ * The measurement is expected to take in to account dynamic parameters such as the current
+ * scene, the state of 3A algorithms, the state of internal HW modules and return a more
+ * accurate assessment of the still capture latency.</p>
+ *
+ * @return pair that includes the estimated input frame/frames camera capture latency as the
+ * first field. This is the time between {@link #onCaptureStarted} and
+ * {@link #onCaptureProcessStarted}. The second field value includes the estimated
+ * post-processing latency. This is the time between {@link #onCaptureProcessStarted} until
+ * the processed frame returns back to the client registered surface.
+ * Both first and second values will be in milliseconds. The total still capture latency will be
+ * the sum of both the first and second values of the pair.
+ * The pair is expected to be null if the dynamic latency estimation is not supported.
+ * If clients have not configured a still capture output, then this method can also return a
+ * null pair.
+ * @since 1.4
+ */
+ Pair<Long, Long> getRealtimeCaptureLatency();
+
+ /**
* Callback for notifying the status of {@link #startCapture(CaptureCallback)} and
* {@link #startRepeating(CaptureCallback)}.
*/
@@ -277,5 +371,20 @@ public interface SessionProcessorImpl {
*/
void onCaptureCompleted(long timestamp, int captureSequenceId,
Map<CaptureResult.Key, Object> result);
+
+ /**
+ * Capture progress callback that needs to be called when the process capture is
+ * ongoing and includes the estimated progress of the processing.
+ *
+ * <p>Extensions must ensure that they always call this callback with monotonically
+ * increasing values.</p>
+ *
+ * <p>Extensions are allowed to trigger this callback multiple times but at the minimum the
+ * callback is expected to be called once when processing is done with value 100.</p>
+ *
+ * @param progress Value between 0 and 100.
+ * @since 1.4
+ */
+ void onCaptureProcessProgressed(int progress);
}
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
index 5f6cb2ba..30a79a6b 100755
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
@@ -20,6 +20,7 @@ import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.SessionConfiguration;
import android.media.Image;
import android.media.ImageWriter;
import android.os.Build;
@@ -116,6 +117,26 @@ public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderI
}
@Override
+ public void onPostviewOutputSurface(Surface surface) {
+
+ }
+
+ @Override
+ public void processWithPostview(
+ Map<Integer, Pair<Image, TotalCaptureResult>> results,
+ ProcessResultImpl resultCallback, Executor executor) {
+ if (!isPostviewAvailable()) {
+ throw new RuntimeException("The extension doesn't support postview");
+ }
+
+ if (resultCallback != null) {
+ process(results, resultCallback, executor);
+ } else {
+ process(results);
+ }
+ }
+
+ @Override
public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
ProcessResultImpl resultCallback, Executor executor) {
throw new RuntimeException("The extension doesn't support capture " +
@@ -164,6 +185,11 @@ public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderI
}
@Override
+ public void onResolutionUpdate(Size size, Size postviewSize) {
+
+ }
+
+ @Override
public void onImageFormatUpdate(int imageFormat) {
}
@@ -244,6 +270,11 @@ public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderI
}
@Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ return new ArrayList<>();
+ }
+
+ @Override
public Range<Long> getEstimatedCaptureLatencyRange(Size captureOutputSize) {
return null;
}
@@ -257,4 +288,24 @@ public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderI
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
return new ArrayList<>();
}
+
+ @Override
+ public int onSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ return false;
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ return null;
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ return false;
+ }
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
index 5018df8a..aa95a4a7 100755
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
@@ -18,6 +18,7 @@ package androidx.camera.extensions.impl;
import android.content.Context;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.SessionConfiguration;
import android.util.Pair;
import android.util.Size;
@@ -162,4 +163,9 @@ public final class AutoPreviewExtenderImpl implements PreviewExtenderImpl {
return captureStage;
}
+
+ @Override
+ public int onSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
index 5c9b2d39..c9b24206 100755
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
@@ -21,6 +21,7 @@ import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageWriter;
@@ -118,6 +119,26 @@ public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtende
}
@Override
+ public void onPostviewOutputSurface(Surface surface) {
+
+ }
+
+ @Override
+ public void processWithPostview(
+ Map<Integer, Pair<Image, TotalCaptureResult>> results,
+ ProcessResultImpl resultCallback, Executor executor) {
+ if (!isPostviewAvailable()) {
+ throw new RuntimeException("The extension doesn't support postview");
+ }
+
+ if (resultCallback != null) {
+ process(results, resultCallback, executor);
+ } else {
+ process(results);
+ }
+ }
+
+ @Override
public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
ProcessResultImpl resultCallback, Executor executor) {
throw new RuntimeException("The extension doesn't support capture " +
@@ -166,6 +187,11 @@ public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtende
}
@Override
+ public void onResolutionUpdate(Size size, Size postviewSize) {
+
+ }
+
+ @Override
public void onImageFormatUpdate(int imageFormat) {
}
@@ -267,6 +293,11 @@ public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtende
}
@Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ return new ArrayList<>();
+ }
+
+ @Override
public Range<Long> getEstimatedCaptureLatencyRange(Size captureOutputSize) {
return null;
}
@@ -280,4 +311,24 @@ public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtende
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
return new ArrayList<>();
}
+
+ @Override
+ public int onSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ return false;
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ return null;
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ return false;
+ }
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
index fcc78d55..2ef357c3 100755
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
@@ -19,6 +19,7 @@ import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.util.Pair;
import android.util.Size;
@@ -183,4 +184,9 @@ public final class BeautyPreviewExtenderImpl implements PreviewExtenderImpl {
return captureStage;
}
+
+ @Override
+ public int onSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
index 5c3882b8..a72deef6 100644
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
@@ -16,10 +16,13 @@
package androidx.camera.extensions.impl;
import android.content.Context;
+import android.graphics.ImageFormat;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.SessionConfiguration;
+import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageWriter;
import android.os.Build;
@@ -51,6 +54,8 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
private static final int SESSION_STAGE_ID = 101;
private static final int MODE = CaptureRequest.CONTROL_AWB_MODE_SHADE;
+ private CameraCharacteristics mCameraCharacteristics;
+
/**
* @hide
*/
@@ -62,6 +67,7 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
*/
@Override
public void init(String cameraId, CameraCharacteristics cameraCharacteristics) {
+ mCameraCharacteristics = cameraCharacteristics;
}
/**
@@ -104,6 +110,7 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
CaptureProcessorImpl captureProcessor =
new CaptureProcessorImpl() {
private ImageWriter mImageWriter;
+ private ImageWriter mImageWriterPostview;
@Override
public void onOutputSurface(Surface surface, int imageFormat) {
@@ -113,6 +120,61 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
}
@Override
+ public void onPostviewOutputSurface(Surface surface) {
+ if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) &&
+ mImageWriterPostview == null) {
+ mImageWriterPostview = ImageWriter.newInstance(surface, 1);
+ }
+ }
+
+ @Override
+ public void processWithPostview(
+ Map<Integer, Pair<Image, TotalCaptureResult>> results,
+ ProcessResultImpl resultCallback, Executor executor) {
+
+ Pair<Image, TotalCaptureResult> result = results.get(DEFAULT_STAGE_ID);
+ if (result == null) {
+ Log.w(TAG,
+ "Unable to process since images does not contain all " +
+ "stages.");
+ return;
+ } else {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ Image image = mImageWriterPostview.dequeueInputImage();
+
+ // Postview processing here
+ ByteBuffer yByteBuffer = image.getPlanes()[0].getBuffer();
+ ByteBuffer uByteBuffer = image.getPlanes()[2].getBuffer();
+ ByteBuffer vByteBuffer = image.getPlanes()[1].getBuffer();
+
+ // For sample, allocate empty buffer to match postview size
+ yByteBuffer.put(ByteBuffer.allocate(image.getPlanes()[0]
+ .getBuffer().capacity()));
+ uByteBuffer.put(ByteBuffer.allocate(image.getPlanes()[2]
+ .getBuffer().capacity()));
+ vByteBuffer.put(ByteBuffer.allocate(image.getPlanes()[1]
+ .getBuffer().capacity()));
+ Long sensorTimestamp =
+ result.second.get(CaptureResult.SENSOR_TIMESTAMP);
+ if (sensorTimestamp != null) {
+ image.setTimestamp(sensorTimestamp);
+ } else {
+ Log.e(TAG, "Sensor timestamp absent using default!");
+ }
+
+ mImageWriterPostview.queueInputImage(image);
+ }
+ }
+
+ // Process still capture
+ if (resultCallback != null) {
+ process(results, resultCallback, executor);
+ } else {
+ process(results);
+ }
+ }
+
+ @Override
public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
ProcessResultImpl resultCallback, Executor executor) {
Pair<Image, TotalCaptureResult> result = results.get(DEFAULT_STAGE_ID);
@@ -241,6 +303,11 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
}
@Override
+ public void onResolutionUpdate(Size size, Size postviewSize) {
+
+ }
+
+ @Override
public void onImageFormatUpdate(int imageFormat) {
}
@@ -317,7 +384,59 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
*/
@Override
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
- return null;
+ List<Pair<Integer, Size[]>> formatResolutionsPairList = new ArrayList<>();
+
+ StreamConfigurationMap map =
+ mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+
+ if (map != null) {
+ // The sample implementation only retrieves originally supported resolutions from
+ // CameraCharacteristics for JPEG and YUV_420_888 formats to return.
+ Size[] outputSizes = map.getOutputSizes(ImageFormat.JPEG);
+
+ if (outputSizes != null) {
+ formatResolutionsPairList.add(Pair.create(ImageFormat.JPEG, outputSizes));
+ }
+
+ outputSizes = map.getOutputSizes(ImageFormat.YUV_420_888);
+
+ if (outputSizes != null) {
+ formatResolutionsPairList.add(Pair.create(ImageFormat.YUV_420_888, outputSizes));
+ }
+ }
+
+ return formatResolutionsPairList;
+ }
+
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ // Sample for supported postview sizes, returns subset of supported resolutions for
+ // still capture that are less than its size and match the aspect ratio
+ List<Pair<Integer, Size[]>> res = new ArrayList<>();
+ List<Pair<Integer, Size[]>> captureSupportedResolutions = getSupportedResolutions();
+ float targetAr = ((float) captureSize.getWidth()) / captureSize.getHeight();
+
+ for (Pair<Integer, Size[]> elem : captureSupportedResolutions) {
+ Integer currFormat = elem.first;
+ Size[] currFormatSizes = elem.second;
+ List<Size> postviewSizes = new ArrayList<>();
+
+ for (Size s : currFormatSizes) {
+ if ((s.equals(captureSize)) || (s.getWidth() > captureSize.getWidth())
+ || (s.getHeight() > captureSize.getHeight())) continue;
+ float currentAr = ((float) s.getWidth()) / s.getHeight();
+ if (Math.abs(targetAr - currentAr) < 0.01) {
+ postviewSizes.add(s);
+ }
+ }
+
+ if (!postviewSizes.isEmpty()) {
+ res.add(new Pair<Integer, Size[]>(currFormat,
+ postviewSizes.toArray(new Size[postviewSizes.size()])));
+ }
+ }
+
+ return res;
}
@Override
@@ -341,4 +460,24 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
CaptureResult.FLASH_STATE};
return Arrays.asList(CAPTURE_RESULT_SET);
}
+
+ @Override
+ public int onSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ return false;
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ return null;
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ return true;
+ }
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
index 45c7f47c..ace54c8b 100644
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
@@ -19,6 +19,7 @@ import android.content.Context;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.SessionConfiguration;
import android.util.Pair;
import android.util.Size;
import android.view.Surface;
@@ -202,4 +203,9 @@ public final class BokehPreviewExtenderImpl implements PreviewExtenderImpl {
return captureStage;
}
+
+ @Override
+ public int onSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
index 3eee146a..f4719b8b 100644
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
@@ -21,6 +21,7 @@ import android.graphics.ImageFormat;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.util.Pair;
+import android.util.Size;
import android.view.Surface;
import java.util.Map;
@@ -46,6 +47,29 @@ public interface CaptureProcessorImpl extends ProcessorImpl {
void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
/**
+ * Informs the CaptureProcessorImpl where it should write the postview output to.
+ * This will only be invoked once if a valid postview surface was set.
+ *
+ * @param surface A valid {@link ImageFormat#YUV_420_888} {@link Surface}
+ * that the CaptureProcessorImpl should write data into.
+ * @since 1.4
+ */
+ void onPostviewOutputSurface(Surface surface);
+
+ /**
+ * Invoked when the Camera Framework changes the configured output resolution for
+ * still capture and postview.
+ *
+ * <p>After this call, {@link CaptureProcessorImpl} should expect any {@link Image} received as
+ * input for still capture and postview to be at the specified resolutions.
+ *
+ * @param size for the surface for still capture.
+ * @param postviewSize for the surface for postview.
+ * @since 1.4
+ */
+ void onResolutionUpdate(Size size, Size postviewSize);
+
+ /**
* Process a set images captured that were requested.
*
* <p> The result of the processing step should be written to the {@link Surface} that was
@@ -63,4 +87,30 @@ public interface CaptureProcessorImpl extends ProcessorImpl {
*/
void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
ProcessResultImpl resultCallback, Executor executor);
+
+ /**
+ * Process a set images captured that were requested for both postview and
+ * still capture.
+ *
+ * <p> This processing method will be called if a postview was requested, therefore the
+ * processed postview should be written to the
+ * {@link Surface} received by {@link #onPostviewOutputSurface(Surface, int)}.
+ * The final result of the processing step should be written to the {@link Surface} that was
+ * received by {@link #onOutputSurface(Surface, int)}. Since postview should be available
+ * before the capture, it should be processed and written to the surface before
+ * the final capture is processed.
+ *
+ * @param results The map of {@link ImageFormat#YUV_420_888} format images and
+ * metadata to process. The {@link Image} that are contained within
+ * the map will become invalid after this method completes, so no
+ * references to them should be kept.
+ * @param resultCallback Capture result callback to be called once the capture result
+ * values of the processed image are ready.
+ * @param executor The executor to run the callback on. If null then the callback
+ * will run on any arbitrary executor.
+ * @throws RuntimeException if postview feature is not supported
+ * @since 1.4
+ */
+ void processWithPostview(Map<Integer, Pair<Image, TotalCaptureResult>> results,
+ ProcessResultImpl resultCallback, Executor executor);
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ExtenderStateListener.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ExtenderStateListener.java
index f926cff9..23570c4b 100644
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ExtenderStateListener.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ExtenderStateListener.java
@@ -84,4 +84,21 @@ public interface ExtenderStateListener {
* @hide
*/
CaptureStageImpl onDisableSession();
+
+ /**
+ * This will be invoked before the {@link android.hardware.camera2.CameraCaptureSession} is
+ * initialized and must return a valid camera session type
+ * {@link android.hardware.camera2.params.SessionConfiguration#getSessionType}
+ * to be used to configure camera capture session. Both the preview and the image capture
+ * extender must return the same session type value for a specific extension type. If there
+ * is inconsistency between the session type values from preview and image extenders, then
+ * the session configuration will fail.
+ *
+ *
+ * @since 1.4
+ * @return Camera capture session type. Regular and vendor specific types are supported but
+ * not high speed values. The extension can return -1 in which case the camera capture session
+ * will be configured to use the default regular type.
+ */
+ int onSessionType();
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
index af147ed7..75739ce0 100644
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ExtensionVersionImpl.java
@@ -29,7 +29,7 @@ import android.util.Log;
*/
public class ExtensionVersionImpl {
private static final String TAG = "ExtenderVersionImpl";
- private static final String VERSION = "1.3.0";
+ private static final String VERSION = "1.4.0";
/**
* @hide
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
index 57b7fe65..25232635 100644
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
@@ -17,10 +17,12 @@ package androidx.camera.extensions.impl;
import android.content.Context;
import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraExtensionCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.MeteringRectangle;
+import android.hardware.camera2.params.SessionConfiguration;
import android.media.Image;
import android.media.ImageWriter;
import android.os.Build;
@@ -130,6 +132,26 @@ public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderIm
}
@Override
+ public void onPostviewOutputSurface(Surface surface) {
+
+ }
+
+ @Override
+ public void processWithPostview(
+ Map<Integer, Pair<Image, TotalCaptureResult>> results,
+ ProcessResultImpl resultCallback, Executor executor) {
+ if (!isPostviewAvailable()) {
+ throw new RuntimeException("The extension doesn't support postview");
+ }
+
+ if (resultCallback != null) {
+ process(results, resultCallback, executor);
+ } else {
+ process(results);
+ }
+ }
+
+ @Override
public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
ProcessResultImpl resultCallback, Executor executor) {
Pair<Image, TotalCaptureResult> result = results.get(NORMAL_STAGE_ID);
@@ -184,12 +206,25 @@ public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderIm
jpegOrientation));
}
+ Integer strength = result.second.get(
+ CaptureResult.EXTENSION_STRENGTH);
+ if (strength != null) {
+ captureResults.add(new Pair<>(CaptureResult.EXTENSION_STRENGTH,
+ strength));
+ }
+
+ captureResults.add(new Pair<>(CaptureResult.EXTENSION_CURRENT_TYPE,
+ CameraExtensionCharacteristics.EXTENSION_HDR));
+
if (executor != null) {
executor.execute(() -> resultCallback.onCaptureCompleted(
shutterTimestamp, captureResults));
+ executor.execute(() ->
+ resultCallback.onCaptureProcessProgressed(100));
} else {
resultCallback.onCaptureCompleted(shutterTimestamp,
captureResults);
+ resultCallback.onCaptureProcessProgressed(100);
}
}
}
@@ -264,6 +299,11 @@ public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderIm
}
@Override
+ public void onResolutionUpdate(Size size, Size postviewSize) {
+
+ }
+
+ @Override
public void onImageFormatUpdate(int imageFormat) {
}
@@ -332,6 +372,11 @@ public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderIm
}
@Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ return new ArrayList<>();
+ }
+
+ @Override
public Range<Long> getEstimatedCaptureLatencyRange(Size captureOutputSize) {
return null;
}
@@ -340,7 +385,7 @@ public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderIm
public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() {
final CaptureRequest.Key [] CAPTURE_REQUEST_SET = {CaptureRequest.CONTROL_ZOOM_RATIO,
CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_REGIONS,
- CaptureRequest.CONTROL_AF_TRIGGER};
+ CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.EXTENSION_STRENGTH};
return Arrays.asList(CAPTURE_REQUEST_SET);
}
@@ -348,7 +393,28 @@ public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderIm
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
final CaptureResult.Key [] CAPTURE_RESULT_SET = {CaptureResult.CONTROL_ZOOM_RATIO,
CaptureResult.CONTROL_AF_MODE, CaptureResult.CONTROL_AF_REGIONS,
- CaptureResult.CONTROL_AF_TRIGGER, CaptureResult.CONTROL_AF_STATE};
+ CaptureResult.CONTROL_AF_TRIGGER, CaptureResult.CONTROL_AF_STATE,
+ CaptureResult.EXTENSION_CURRENT_TYPE, CaptureResult.EXTENSION_STRENGTH};
return Arrays.asList(CAPTURE_RESULT_SET);
}
+
+ @Override
+ public int onSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ return true;
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ return null;
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ return false;
+ }
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
index 78b0a9d0..7777bfa2 100644
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
@@ -18,15 +18,18 @@ package androidx.camera.extensions.impl;
import android.content.Context;
import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraExtensionCharacteristics;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.MeteringRectangle;
+import android.hardware.camera2.params.SessionConfiguration;
import android.media.ImageWriter;
import android.media.Image;
import android.util.Pair;
import android.util.Size;
import android.view.Surface;
+import java.io.Closeable;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import java.util.List;
@@ -43,8 +46,6 @@ import java.util.List;
public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl {
private static final int DEFAULT_STAGE_ID = 0;
- ImageWriter mWriter;
-
/**
* @hide
*/
@@ -109,17 +110,32 @@ public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl {
return null;
}
- private PreviewImageProcessorImpl mProcessor = new PreviewImageProcessorImpl() {
+ private HdrPreviewProcessor mProcessor = new HdrPreviewProcessor();
+
+ private static class HdrPreviewProcessor implements PreviewImageProcessorImpl, Closeable {
Surface mSurface;
int mFormat = -1;
+ final Object mLock = new Object(); // Synchronize access to 'mWriter'
+ ImageWriter mWriter;
- private void setWindowSurface() {
- if (mSurface != null && mFormat >= 0) {
+ public void close() {
+ synchronized(mLock) {
if (mWriter != null) {
mWriter.close();
+ mWriter = null;
}
+ }
+ }
- mWriter = ImageWriter.newInstance(mSurface, 2, mFormat);
+ private void setWindowSurface() {
+ synchronized(mLock) {
+ if (mSurface != null && mFormat >= 0) {
+ if (mWriter != null) {
+ mWriter.close();
+ }
+
+ mWriter = ImageWriter.newInstance(mSurface, 2, mFormat);
+ }
}
}
@@ -132,7 +148,11 @@ public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl {
@Override
public void process(Image image, TotalCaptureResult result) {
- mWriter.queueInputImage(image);
+ synchronized(mLock) {
+ if (mWriter != null) {
+ mWriter.queueInputImage(image);
+ }
+ }
}
@Override
@@ -175,6 +195,14 @@ public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl {
jpegOrientation));
}
+ Integer strength = result.get(CaptureResult.EXTENSION_STRENGTH);
+ if (strength != null) {
+ captureResults.add(new Pair<>(CaptureResult.EXTENSION_STRENGTH, strength));
+ }
+
+ captureResults.add(new Pair<>(CaptureResult.EXTENSION_CURRENT_TYPE,
+ CameraExtensionCharacteristics.EXTENSION_HDR));
+
if (executor != null) {
executor.execute(() -> resultCallback.onCaptureCompleted(shutterTimestamp,
captureResults));
@@ -209,10 +237,7 @@ public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl {
*/
@Override
public void onDeInit() {
- if (mWriter != null) {
- mWriter.close();
- mWriter = null;
- }
+ mProcessor.close();
}
/**
@@ -238,4 +263,9 @@ public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl {
public CaptureStageImpl onDisableSession() {
return null;
}
+
+ @Override
+ public int onSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
index c27a5dbb..37e7baf3 100644
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
@@ -91,6 +91,21 @@ public interface ImageCaptureExtenderImpl extends ExtenderStateListener {
List<Pair<Integer, Size[]>> getSupportedResolutions();
/**
+ * Returns the customized supported postview resolutions for a still capture using
+ * its size.
+ *
+ * <p>Pair list composed with {@link ImageFormat} and {@link Size} array will be returned.
+ *
+ * <p>The returned resolutions should be subset of the supported sizes retrieved from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap} for the camera device.
+ *
+ * @return the customized supported resolutions, or null to support all sizes retrieved from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap}.
+ * @since 1.4
+ */
+ List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize);
+
+ /**
* Returns the estimated capture latency range in milliseconds for the target capture
* resolution.
*
@@ -138,5 +153,44 @@ public interface ImageCaptureExtenderImpl extends ExtenderStateListener {
* @since 1.3
*/
List<CaptureResult.Key> getAvailableCaptureResultKeys();
-}
+ /**
+ * Advertise support for {@link ProcessResultImpl#onCaptureProcessProgressed}.
+ *
+ * @return {@code true} in case the process progress callback is supported and is expected to
+ * be triggered, {@code false} otherwise.
+ * @since 1.4
+ */
+ boolean isCaptureProcessProgressAvailable();
+
+ /**
+ * Returns the dynamically calculated capture latency pair in milliseconds.
+ *
+ * <p>In contrast to {@link #getEstimatedCaptureLatencyRange} this method is guaranteed to be
+ * called after the camera capture session is initialized and camera preview is enabled.
+ * The measurement is expected to take in to account dynamic parameters such as the current
+ * scene, the state of 3A algorithms, the state of internal HW modules and return a more
+ * accurate assessment of the still capture latency.</p>
+ *
+ * @return pair that includes the estimated input frame/frames camera capture latency as the
+ * first field and the estimated post-processing latency {@link CaptureProcessorImpl#process}
+ * as the second pair field. Both first and second fields will be in milliseconds. The total
+ * still capture latency will be the sum of both the first and second values.
+ * The pair is expected to be null if the dynamic latency estimation is not supported.
+ * If clients have not configured a still capture output, then this method can also return a
+ * null pair.
+ * @since 1.4
+ */
+ Pair<Long, Long> getRealtimeCaptureLatency();
+
+ /**
+ * Indicates whether the extension supports the postview for still capture feature.
+ * If the extension is using HAL processing, false should be returned since the
+ * postview feature is not currently supported for this case.
+ *
+ * @return {@code true} in case postview for still capture is supported
+ * {@code false} otherwise.
+ * @since 1.4
+ */
+ boolean isPostviewAvailable();
+}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
index f0821ed7..e3317d94 100755
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
@@ -20,6 +20,7 @@ import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.SessionConfiguration;
import android.media.Image;
import android.media.ImageWriter;
import android.os.Build;
@@ -116,6 +117,26 @@ public final class NightImageCaptureExtenderImpl implements ImageCaptureExtender
}
@Override
+ public void onPostviewOutputSurface(Surface surface) {
+
+ }
+
+ @Override
+ public void processWithPostview(
+ Map<Integer, Pair<Image, TotalCaptureResult>> results,
+ ProcessResultImpl resultCallback, Executor executor) {
+ if (!isPostviewAvailable()) {
+ throw new RuntimeException("The extension doesn't support postview");
+ }
+
+ if (resultCallback != null) {
+ process(results, resultCallback, executor);
+ } else {
+ process(results);
+ }
+ }
+
+ @Override
public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
ProcessResultImpl resultCallback, Executor executor) {
throw new RuntimeException("The extension doesn't support capture " +
@@ -164,6 +185,11 @@ public final class NightImageCaptureExtenderImpl implements ImageCaptureExtender
}
@Override
+ public void onResolutionUpdate(Size size, Size postviewSize) {
+
+ }
+
+ @Override
public void onImageFormatUpdate(int imageFormat) {
}
@@ -244,6 +270,11 @@ public final class NightImageCaptureExtenderImpl implements ImageCaptureExtender
}
@Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ return new ArrayList<>();
+ }
+
+ @Override
public Range<Long> getEstimatedCaptureLatencyRange(Size captureOutputSize) {
return null;
}
@@ -257,4 +288,24 @@ public final class NightImageCaptureExtenderImpl implements ImageCaptureExtender
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
return new ArrayList<>();
}
+
+ @Override
+ public int onSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ return false;
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ return null;
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ return false;
+ }
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
index e29abec1..46be86ab 100755
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
@@ -18,6 +18,7 @@ package androidx.camera.extensions.impl;
import android.content.Context;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.SessionConfiguration;
import android.util.Pair;
import android.util.Size;
@@ -162,4 +163,9 @@ public final class NightPreviewExtenderImpl implements PreviewExtenderImpl {
return captureStage;
}
+
+ @Override
+ public int onSessionType() {
+ return SessionConfiguration.SESSION_REGULAR;
+ }
}
diff --git a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ProcessResultImpl.java b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ProcessResultImpl.java
index d4c2014d..518942e9 100644
--- a/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ProcessResultImpl.java
+++ b/camera2/extensions/sample/src/java/androidx/camera/extensions/impl/ProcessResultImpl.java
@@ -24,7 +24,6 @@ import java.util.List;
/**
* Allows clients to receive information about the capture result values of processed frames.
*
- * @since 1.3
*/
public interface ProcessResultImpl {
/**
@@ -38,6 +37,23 @@ public interface ProcessResultImpl {
* must also be passed as part of this callback. Both Camera2 and
* CameraX guarantee that those two settings and results are always
* supported and applied by the corresponding framework.
+ * @since 1.3
*/
void onCaptureCompleted(long shutterTimestamp, List<Pair<CaptureResult.Key, Object>> result);
+
+
+ /**
+ * Capture progress callback that needs to be called when the process capture is
+ * ongoing and includes the estimated progress of the processing.
+ *
+ * <p>Extensions must ensure that they always call this callback with monotonically increasing
+ * values.</p>
+ *
+ * <p>Extensions are allowed to trigger this callback multiple times but at the minimum the
+ * callback is expected to be called once when processing is done with value 100.</p>
+ *
+ * @param progress Value between 0 and 100.
+ * @since 1.4
+ */
+ void onCaptureProcessProgressed(int progress);
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
index ccb0dacf..bd605708 100755
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java
@@ -95,6 +95,11 @@ public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderI
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
@Nullable
@Override
public Range<Long> getEstimatedCaptureLatencyRange(@NonNull Size captureOutputSize) {
@@ -113,4 +118,23 @@ public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderI
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
index 100f6658..0c4577a4 100755
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java
@@ -93,4 +93,9 @@ public final class AutoPreviewExtenderImpl implements PreviewExtenderImpl {
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
index 2d266390..50c80407 100755
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java
@@ -95,6 +95,11 @@ public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtende
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
@Nullable
@Override
public Range<Long> getEstimatedCaptureLatencyRange(@NonNull Size captureOutputSize) {
@@ -112,4 +117,24 @@ public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtende
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
index bc3e48dd..1f501745 100755
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java
@@ -93,4 +93,9 @@ public final class BeautyPreviewExtenderImpl implements PreviewExtenderImpl {
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
index 66c5839d..ee777cf9 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java
@@ -95,6 +95,11 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
@Nullable
@Override
public Range<Long> getEstimatedCaptureLatencyRange(@NonNull Size captureOutputSize) {
@@ -113,4 +118,23 @@ public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtender
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
index ff588623..1dc5ed79 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java
@@ -91,4 +91,9 @@ public final class BokehPreviewExtenderImpl implements PreviewExtenderImpl {
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
index 3eee146a..f4719b8b 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/CaptureProcessorImpl.java
@@ -21,6 +21,7 @@ import android.graphics.ImageFormat;
import android.hardware.camera2.TotalCaptureResult;
import android.media.Image;
import android.util.Pair;
+import android.util.Size;
import android.view.Surface;
import java.util.Map;
@@ -46,6 +47,29 @@ public interface CaptureProcessorImpl extends ProcessorImpl {
void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
/**
+ * Informs the CaptureProcessorImpl where it should write the postview output to.
+ * This will only be invoked once if a valid postview surface was set.
+ *
+ * @param surface A valid {@link ImageFormat#YUV_420_888} {@link Surface}
+ * that the CaptureProcessorImpl should write data into.
+ * @since 1.4
+ */
+ void onPostviewOutputSurface(Surface surface);
+
+ /**
+ * Invoked when the Camera Framework changes the configured output resolution for
+ * still capture and postview.
+ *
+ * <p>After this call, {@link CaptureProcessorImpl} should expect any {@link Image} received as
+ * input for still capture and postview to be at the specified resolutions.
+ *
+ * @param size for the surface for still capture.
+ * @param postviewSize for the surface for postview.
+ * @since 1.4
+ */
+ void onResolutionUpdate(Size size, Size postviewSize);
+
+ /**
* Process a set images captured that were requested.
*
* <p> The result of the processing step should be written to the {@link Surface} that was
@@ -63,4 +87,30 @@ public interface CaptureProcessorImpl extends ProcessorImpl {
*/
void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
ProcessResultImpl resultCallback, Executor executor);
+
+ /**
+ * Process a set images captured that were requested for both postview and
+ * still capture.
+ *
+ * <p> This processing method will be called if a postview was requested, therefore the
+ * processed postview should be written to the
+ * {@link Surface} received by {@link #onPostviewOutputSurface(Surface, int)}.
+ * The final result of the processing step should be written to the {@link Surface} that was
+ * received by {@link #onOutputSurface(Surface, int)}. Since postview should be available
+ * before the capture, it should be processed and written to the surface before
+ * the final capture is processed.
+ *
+ * @param results The map of {@link ImageFormat#YUV_420_888} format images and
+ * metadata to process. The {@link Image} that are contained within
+ * the map will become invalid after this method completes, so no
+ * references to them should be kept.
+ * @param resultCallback Capture result callback to be called once the capture result
+ * values of the processed image are ready.
+ * @param executor The executor to run the callback on. If null then the callback
+ * will run on any arbitrary executor.
+ * @throws RuntimeException if postview feature is not supported
+ * @since 1.4
+ */
+ void processWithPostview(Map<Integer, Pair<Image, TotalCaptureResult>> results,
+ ProcessResultImpl resultCallback, Executor executor);
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java
index 2879568f..4a3b01cd 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ExtenderStateListener.java
@@ -80,4 +80,20 @@ public interface ExtenderStateListener {
* @return The request information to customize the session.
*/
CaptureStageImpl onDisableSession();
+
+ /**
+ * This will be invoked before the {@link android.hardware.camera2.CameraCaptureSession} is
+ * initialized and must return a valid camera session type
+ * {@link android.hardware.camera2.params.SessionConfiguration#getSessionType}
+ * to be used to configure camera capture session. Both the preview and the image capture
+ * extender must return the same session type value for a specific extension type. If there
+ * is inconsistency between the session type values from preview and image extenders, then
+ * the session configuration will fail.
+ *
+ * @since 1.4
+ * @return Camera capture session type. Regular and vendor specific types are supported but
+ * not high speed values. The extension can return -1 in which case the camera capture session
+ * will be configured to use the default regular type.
+ */
+ int onSessionType();
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
index f1191dcf..f3fd2f3b 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java
@@ -95,6 +95,11 @@ public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderIm
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
@Nullable
@Override
public Range<Long> getEstimatedCaptureLatencyRange(@NonNull Size captureOutputSize) {
@@ -112,4 +117,24 @@ public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderIm
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
index 0eb4a610..af484646 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java
@@ -93,4 +93,9 @@ public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl {
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
index 88bd105a..70c1804e 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ImageCaptureExtenderImpl.java
@@ -85,6 +85,21 @@ public interface ImageCaptureExtenderImpl extends ExtenderStateListener {
List<Pair<Integer, Size[]>> getSupportedResolutions();
/**
+ * Returns the customized supported postview resolutions for a still capture using
+ * its size.
+ *
+ * <p>Pair list composed with {@link ImageFormat} and {@link Size} array will be returned.
+ *
+ * <p>The returned resolutions should be subset of the supported sizes retrieved from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap} for the camera device.
+ *
+ * @return the customized supported resolutions, or null to support all sizes retrieved from
+ * {@link android.hardware.camera2.params.StreamConfigurationMap}.
+ * @since 1.4
+ */
+ List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize);
+
+ /**
* Returns the estimated capture latency range in milliseconds for the target capture
* resolution.
*
@@ -159,4 +174,44 @@ public interface ImageCaptureExtenderImpl extends ExtenderStateListener {
* @since 1.3
*/
List<CaptureResult.Key> getAvailableCaptureResultKeys();
+
+ /**
+ * Advertise support for {@link ProcessResultImpl#onCaptureProcessProgressed}.
+ *
+ * @return {@code true} in case the process progress callback is supported and is expected to
+ * be triggered, {@code false} otherwise.
+ * @since 1.4
+ */
+ boolean isCaptureProcessProgressAvailable();
+
+ /**
+ * Returns the dynamically calculated capture latency pair in milliseconds.
+ *
+ * <p>In contrast to {@link #getEstimatedCaptureLatencyRange} this method is guaranteed to be
+ * called after the camera capture session is initialized and camera preview is enabled.
+ * The measurement is expected to take in to account dynamic parameters such as the current
+ * scene, the state of 3A algorithms, the state of internal HW modules and return a more
+ * accurate assessment of the still capture latency.</p>
+ *
+ * @return pair that includes the estimated input frame/frames camera capture latency as the
+ * first field and the estimated post-processing latency {@link CaptureProcessorImpl#process}
+ * as the second pair field. Both first and second fields will be in milliseconds. The total
+ * still capture latency will be the sum of both the first and second values.
+ * The pair is expected to be null if the dynamic latency estimation is not supported.
+ * If clients have not configured a still capture output, then this method can also return a
+ * null pair.
+ * @since 1.4
+ */
+ Pair<Long, Long> getRealtimeCaptureLatency();
+
+ /**
+ * Indicates whether the extension supports the postview for still capture feature.
+ * If the extension is using HAL processing, false should be returned since the
+ * postview feature is not currently supported for this case.
+ *
+ * @return {@code true} in case postview for still capture is supported
+ * {@code false} otherwise.
+ * @since 1.4
+ */
+ boolean isPostviewAvailable();
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
index c8ac9788..6f0eaef9 100755
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java
@@ -95,6 +95,11 @@ public final class NightImageCaptureExtenderImpl implements ImageCaptureExtender
throw new RuntimeException("Stub, replace with implementation.");
}
+ @Override
+ public List<Pair<Integer, Size[]>> getSupportedPostviewResolutions(Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
@Nullable
@Override
public Range<Long> getEstimatedCaptureLatencyRange(@NonNull Size captureOutputSize) {
@@ -112,4 +117,24 @@ public final class NightImageCaptureExtenderImpl implements ImageCaptureExtender
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public Pair<Long, Long> getRealtimeCaptureLatency() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
index a5809f6b..825994f5 100755
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java
@@ -93,4 +93,9 @@ public final class NightPreviewExtenderImpl implements PreviewExtenderImpl {
public List<Pair<Integer, Size[]>> getSupportedResolutions() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public int onSessionType() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ProcessResultImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ProcessResultImpl.java
index d0e3605d..0e154450 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ProcessResultImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/ProcessResultImpl.java
@@ -25,7 +25,6 @@ import java.util.List;
/**
* Allows clients to receive information about the capture result values of processed frames.
*
- * @since 1.3
*/
@SuppressLint("UnknownNullness")
public interface ProcessResultImpl {
@@ -40,6 +39,22 @@ public interface ProcessResultImpl {
* must also be passed as part of this callback. Both Camera2 and
* CameraX guarantee that those two settings and results are always
* supported and applied by the corresponding framework.
+ * @since 1.3
*/
void onCaptureCompleted(long shutterTimestamp, List<Pair<CaptureResult.Key, Object>> result);
+
+ /**
+ * Capture progress callback that needs to be called when the process capture is
+ * ongoing and includes the estimated progress of the processing.
+ *
+ * <p>Extensions must ensure that they always call this callback with monotonically increasing
+ * values.</p>
+ *
+ * <p>Extensions are allowed to trigger this callback multiple times but at the minimum the
+ * callback is expected to be called once when processing is done with value 100.</p>
+ *
+ * @param progress Value between 0 and 100.
+ * @since 1.4
+ */
+ void onCaptureProcessProgressed(int progress);
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
index 465bfe88..d13efc85 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AdvancedExtenderImpl.java
@@ -124,6 +124,17 @@ public interface AdvancedExtenderImpl {
Map<Integer, List<Size>> getSupportedCaptureOutputResolutions(String cameraId);
/**
+ * Returns supported output format/size map for postview image. OEM is required to support
+ * both JPEG and YUV_420_888 format output.
+ *
+ * <p>The surface created with this supported format/size could configure
+ * intermediate surfaces(YUV/RAW..) and write the output to the output surface.</p>
+ *
+ * @since 1.4
+ */
+ Map<Integer, List<Size>> getSupportedPostviewResolutions(Size captureSize);
+
+ /**
* Returns supported output sizes for Image Analysis (YUV_420_888 format).
*
* <p>OEM can optionally support a YUV surface for ImageAnalysis along with Preview/ImageCapture
@@ -185,4 +196,24 @@ public interface AdvancedExtenderImpl {
* @since 1.3
*/
List<CaptureResult.Key> getAvailableCaptureResultKeys();
+
+ /**
+ * Advertise support for {@link SessionProcessorImpl#onCaptureProcessProgressed}.
+ *
+ * @return {@code true} in case the process progress callback is supported and is expected to
+ * be triggered, {@code false} otherwise.
+ * @since 1.4
+ */
+ public boolean isCaptureProcessProgressAvailable();
+
+ /**
+ * Indicates whether the extension supports the postview for still capture feature.
+ * If the extension is using HAL processing, false should be returned since the
+ * postview feature is not currently supported for this case.
+ *
+ * @return {@code true} in case postview for still capture is supported
+ * {@code false} otherwise.
+ * @since 1.4
+ */
+ boolean isPostviewAvailable();
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java
index 0d3bd4a0..8c3ac11c 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/AutoAdvancedExtenderImpl.java
@@ -69,6 +69,12 @@ public class AutoAdvancedExtenderImpl implements AdvancedExtenderImpl {
}
@Override
+ public Map<Integer, List<Size>> getSupportedPostviewResolutions(
+ Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
public List<Size> getSupportedYuvAnalysisResolutions(
String cameraId) {
throw new RuntimeException("Stub, replace with implementation.");
@@ -88,4 +94,14 @@ public class AutoAdvancedExtenderImpl implements AdvancedExtenderImpl {
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/BeautyAdvancedExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/BeautyAdvancedExtenderImpl.java
index 1dec3266..135306c8 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/BeautyAdvancedExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/BeautyAdvancedExtenderImpl.java
@@ -69,6 +69,12 @@ public class BeautyAdvancedExtenderImpl implements AdvancedExtenderImpl {
}
@Override
+ public Map<Integer, List<Size>> getSupportedPostviewResolutions(
+ Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
public List<Size> getSupportedYuvAnalysisResolutions(
String cameraId) {
throw new RuntimeException("Stub, replace with implementation.");
@@ -88,4 +94,14 @@ public class BeautyAdvancedExtenderImpl implements AdvancedExtenderImpl {
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/BokehAdvancedExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/BokehAdvancedExtenderImpl.java
index bc41b4e0..fa4ad0dc 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/BokehAdvancedExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/BokehAdvancedExtenderImpl.java
@@ -69,6 +69,12 @@ public class BokehAdvancedExtenderImpl implements AdvancedExtenderImpl {
}
@Override
+ public Map<Integer, List<Size>> getSupportedPostviewResolutions(
+ Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
public List<Size> getSupportedYuvAnalysisResolutions(
String cameraId) {
throw new RuntimeException("Stub, replace with implementation.");
@@ -88,4 +94,14 @@ public class BokehAdvancedExtenderImpl implements AdvancedExtenderImpl {
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
index d1217177..850f0e1b 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImpl.java
@@ -43,4 +43,16 @@ public interface Camera2SessionConfigImpl {
* {@link android.hardware.camera2.params.SessionConfiguration#setSessionParameters}.
*/
int getSessionTemplateId();
+
+
+ /**
+ * Retrieves the session type to be used when initializing the
+ * {@link android.hardware.camera2.CameraCaptureSession}.
+ *
+ * @since 1.4
+ * @return Camera capture session type. Regular and vendor specific types are supported but
+ * not high speed values. The extension can return -1 in which case the camera capture session
+ * will be configured to use the default regular type.
+ */
+ int getSessionType();
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
index a3011666..dc1feccd 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/Camera2SessionConfigImplBuilder.java
@@ -20,6 +20,7 @@ package androidx.camera.extensions.impl.advanced;
import android.annotation.SuppressLint;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.params.SessionConfiguration;
import java.util.ArrayList;
import java.util.HashMap;
@@ -32,6 +33,7 @@ import java.util.Map;
@SuppressLint("UnknownNullness")
public class Camera2SessionConfigImplBuilder {
private int mSessionTemplateId = CameraDevice.TEMPLATE_PREVIEW;
+ private int mSessionType = SessionConfiguration.SESSION_REGULAR;
Map<CaptureRequest.Key<?>, Object> mSessionParameters = new HashMap<>();
List<Camera2OutputConfigImpl> mCamera2OutputConfigs = new ArrayList<>();
@@ -86,6 +88,13 @@ public class Camera2SessionConfigImplBuilder {
}
/**
+ * Gets the camera capture session type.
+ */
+ public int getSessionType() {
+ return mSessionType;
+ }
+
+ /**
* Builds a {@link Camera2SessionConfigImpl} instance.
*/
public Camera2SessionConfigImpl build() {
@@ -95,6 +104,7 @@ public class Camera2SessionConfigImplBuilder {
private static class Camera2SessionConfigImplImpl implements
Camera2SessionConfigImpl {
int mSessionTemplateId;
+ int mSessionType;
Map<CaptureRequest.Key<?>, Object> mSessionParameters;
List<Camera2OutputConfigImpl> mCamera2OutputConfigs;
@@ -102,6 +112,7 @@ public class Camera2SessionConfigImplBuilder {
mSessionTemplateId = builder.getSessionTemplateId();
mSessionParameters = builder.getSessionParameters();
mCamera2OutputConfigs = builder.getCamera2OutputConfigs();
+ mSessionType = builder.getSessionType();
}
@Override
@@ -118,6 +129,11 @@ public class Camera2SessionConfigImplBuilder {
public int getSessionTemplateId() {
return mSessionTemplateId;
}
+
+ @Override
+ public int getSessionType() {
+ return mSessionType;
+ }
}
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
index 06157dc3..dc5b2b60 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/HdrAdvancedExtenderImpl.java
@@ -70,6 +70,12 @@ public class HdrAdvancedExtenderImpl implements AdvancedExtenderImpl {
}
@Override
+ public Map<Integer, List<Size>> getSupportedPostviewResolutions(
+ Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
public List<Size> getSupportedYuvAnalysisResolutions(
String cameraId) {
throw new RuntimeException("Stub, replace with implementation.");
@@ -89,4 +95,14 @@ public class HdrAdvancedExtenderImpl implements AdvancedExtenderImpl {
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
index 97da5c14..5b0ed8ee 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/NightAdvancedExtenderImpl.java
@@ -69,6 +69,12 @@ public class NightAdvancedExtenderImpl implements AdvancedExtenderImpl {
}
@Override
+ public Map<Integer, List<Size>> getSupportedPostviewResolutions(
+ Size captureSize) {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
public List<Size> getSupportedYuvAnalysisResolutions(
String cameraId) {
throw new RuntimeException("Stub, replace with implementation.");
@@ -88,4 +94,14 @@ public class NightAdvancedExtenderImpl implements AdvancedExtenderImpl {
public List<CaptureResult.Key> getAvailableCaptureResultKeys() {
throw new RuntimeException("Stub, replace with implementation.");
}
+
+ @Override
+ public boolean isCaptureProcessProgressAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
+
+ @Override
+ public boolean isPostviewAvailable() {
+ throw new RuntimeException("Stub, replace with implementation.");
+ }
}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java
new file mode 100644
index 00000000..723f0f4e
--- /dev/null
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/OutputSurfaceConfigurationImpl.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.extensions.impl.advanced;
+
+import android.annotation.SuppressLint;
+
+/**
+ * For specifying the output surface configurations for the extension.
+ *
+ * @since 1.4
+ */
+@SuppressLint("UnknownNullness")
+public interface OutputSurfaceConfigurationImpl {
+ public OutputSurfaceImpl getPreviewOutputSurface();
+
+ public OutputSurfaceImpl getImageCaptureOutputSurface();
+
+ public OutputSurfaceImpl getImageAnalysisOutputSurface();
+
+ public OutputSurfaceImpl getPostviewOutputSurface();
+}
diff --git a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java
index fabfc2bf..06270812 100644
--- a/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java
+++ b/camera2/extensions/stub/src/main/java/androidx/camera/extensions/impl/advanced/SessionProcessorImpl.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
+import android.util.Pair;
import android.view.Surface;
import java.util.Map;
@@ -64,9 +65,59 @@ public interface SessionProcessorImpl {
* preparing a CameraCaptureSession. After initSession() is called, the camera ID,
* cameraCharacteristics and context will not change until deInitSession() has been called.
*
- * <p>CameraX specifies the output surface configurations for preview, image capture and image
- * analysis[optional]. And OEM returns a {@link Camera2SessionConfigImpl} which consists of a
- * list of {@link Camera2OutputConfigImpl} and session parameters. The
+ * <p>CameraX / Camera2 specifies the output surface configurations for preview using
+ * {@link OutputSurfaceConfigurationImpl#getPreviewOutputSurface}, image capture using
+ * {@link OutputSurfaceConfigurationImpl#getImageCaptureOutputSurface}, and image analysis
+ * [optional] using {@link OutputSurfaceConfigurationImpl#getImageAnalysisOutputSurface}.
+ * And OEM returns a {@link Camera2SessionConfigImpl} which consists of a list of
+ * {@link Camera2OutputConfigImpl} and session parameters. The {@link Camera2SessionConfigImpl}
+ * will be used to configure the CameraCaptureSession.
+ *
+ * <p>OEM is responsible for outputting correct camera images output to these output surfaces.
+ * OEM can have the following options to enable the output:
+ * <pre>
+ * (1) Add these output surfaces in CameraCaptureSession directly using
+ * {@link Camera2OutputConfigImplBuilder#newSurfaceConfig(Surface)} }. Processing is done in
+ * HAL.
+ *
+ * (2) Use surface sharing with other surface by calling
+ * {@link Camera2OutputConfigImplBuilder#addSurfaceSharingOutputConfig(Camera2OutputConfigImpl)}
+ * to add the output surface to the other {@link Camera2OutputConfigImpl}.
+ *
+ * (3) Process output from other surfaces (RAW, YUV..) and write the result to the output
+ * surface. The output surface won't be contained in the returned
+ * {@link Camera2SessionConfigImpl}.
+ * </pre>
+ *
+ * <p>{@link Camera2OutputConfigImplBuilder} and {@link Camera2SessionConfigImplBuilder}
+ * implementations are provided in the stub for OEM to construct the
+ * {@link Camera2OutputConfigImpl} and {@link Camera2SessionConfigImpl} instances.
+ *
+ * @param surfaceConfigs contains output surfaces for preview, image capture, and an
+ * optional output config for image analysis (YUV_420_888).
+ * @return a {@link Camera2SessionConfigImpl} consisting of a list of
+ * {@link Camera2OutputConfigImpl} and session parameters which will decide the
+ * {@link android.hardware.camera2.params.SessionConfiguration} for configuring the
+ * CameraCaptureSession. Please note that the OutputConfiguration list may not be part of any
+ * supported or mandatory stream combination BUT OEM must ensure this list will always
+ * produce a valid camera capture session.
+ *
+ * @since 1.4
+ */
+ Camera2SessionConfigImpl initSession(
+ String cameraId,
+ Map<String, CameraCharacteristics> cameraCharacteristicsMap,
+ Context context,
+ OutputSurfaceConfigurationImpl surfaceConfigs);
+
+ /**
+ * Initializes the session for the extension. This is where the OEMs allocate resources for
+ * preparing a CameraCaptureSession. After initSession() is called, the camera ID,
+ * cameraCharacteristics and context will not change until deInitSession() has been called.
+ *
+ * <p>CameraX / Camera 2 specifies the output surface configurations for preview, image capture
+ * and image analysis[optional]. And OEM returns a {@link Camera2SessionConfigImpl} which
+ * consists of a list of {@link Camera2OutputConfigImpl} and session parameters. The
* {@link Camera2SessionConfigImpl} will be used to configure the CameraCaptureSession.
*
* <p>OEM is responsible for outputting correct camera images output to these output surfaces.
@@ -188,11 +239,54 @@ public interface SessionProcessorImpl {
int startCapture(CaptureCallback callback);
/**
+ * Start a multi-frame capture with a postview. {@link #startCapture(CaptureCallback)}
+ * will be used for captures without a postview request.
+ *
+ * Postview will be available before the capture. Upon postview completion,
+ * {@code OnImageAvailableListener#onImageAvailable} will be called on the ImageReader
+ * that creates the postview output surface. When the capture is completed,
+ * {@link CaptureCallback#onCaptureSequenceCompleted} is called and
+ * {@code OnImageAvailableListener#onImageAvailable} will also be called on the ImageReader
+ * that creates the image capture output surface.
+ *
+ * <p>Only one capture can perform at a time. Starting a capture when another capture is
+ * running will cause onCaptureFailed to be called immediately.
+ *
+ * @param callback a callback to report the status.
+ * @return the id of the capture sequence.
+ * @since 1.4
+ */
+ int startCaptureWithPostview(CaptureCallback callback);
+
+ /**
* Abort all capture tasks.
*/
void abortCapture(int captureSequenceId);
/**
+ * Returns the dynamically calculated capture latency pair in milliseconds.
+ *
+ * <p>In contrast to {@link AdvancedExtenderImpl#getEstimatedCaptureLatencyRange} this method is
+ * guaranteed to be called after {@link #onCaptureSessionStart}.
+ * The measurement is expected to take in to account dynamic parameters such as the current
+ * scene, the state of 3A algorithms, the state of internal HW modules and return a more
+ * accurate assessment of the still capture latency.</p>
+ *
+ * @return pair that includes the estimated input frame/frames camera capture latency as the
+ * first field. This is the time between {@link #onCaptureStarted} and
+ * {@link #onCaptureProcessStarted}. The second field value includes the estimated
+ * post-processing latency. This is the time between {@link #onCaptureProcessStarted} until
+ * the processed frame returns back to the client registered surface.
+ * Both first and second values will be in milliseconds. The total still capture latency will be
+ * the sum of both the first and second values of the pair.
+ * The pair is expected to be null if the dynamic latency estimation is not supported.
+ * If clients have not configured a still capture output, then this method can also return a
+ * null pair.
+ * @since 1.4
+ */
+ Pair<Long, Long> getRealtimeCaptureLatency();
+
+ /**
* Callback for notifying the status of {@link #startCapture(CaptureCallback)} and
* {@link #startRepeating(CaptureCallback)}.
*/
@@ -277,5 +371,20 @@ public interface SessionProcessorImpl {
*/
void onCaptureCompleted(long timestamp, int captureSequenceId,
Map<CaptureResult.Key, Object> result);
+
+ /**
+ * Capture progress callback that needs to be called when the process capture is
+ * ongoing and includes the estimated progress of the processing.
+ *
+ * <p>Extensions must ensure that they always call this callback with monotonically
+ * increasing values.</p>
+ *
+ * <p>Extensions are allowed to trigger this callback multiple times but at the minimum the
+ * callback is expected to be called once when processing is done with value 100.</p>
+ *
+ * @param progress Value between 0 and 100.
+ * @since 1.4
+ */
+ void onCaptureProcessProgressed(int progress);
}
}
diff --git a/camera2/public/src/com/android/ex/camera2/blocking/BlockingCameraManager.java b/camera2/public/src/com/android/ex/camera2/blocking/BlockingCameraManager.java
index 21014d03..5b5a38d9 100644
--- a/camera2/public/src/com/android/ex/camera2/blocking/BlockingCameraManager.java
+++ b/camera2/public/src/com/android/ex/camera2/blocking/BlockingCameraManager.java
@@ -89,7 +89,7 @@ public class BlockingCameraManager {
}
}
- private final CameraManager mManager;
+ protected final CameraManager mManager;
/**
* Create a new blocking camera manager.
@@ -168,7 +168,7 @@ public class BlockingCameraManager {
* <p>Time out after {@link #OPEN_TIME_OUT_MS} and unblock. Clean up camera if it arrives
* later.</p>
*/
- private class OpenListener extends CameraDevice.StateCallback {
+ protected class OpenListener extends CameraDevice.StateCallback {
private static final int ERROR_UNINITIALIZED = -1;
private final String mCameraId;
@@ -186,9 +186,13 @@ public class BlockingCameraManager {
private boolean mNoReply = true; // Start with no reply until proven otherwise
private boolean mTimedOut = false;
- OpenListener(CameraManager manager, String cameraId,
- CameraDevice.StateCallback listener, Handler handler)
- throws CameraAccessException {
+ protected OpenListener(String cameraId, CameraDevice.StateCallback listener) {
+ mCameraId = cameraId;
+ mProxy = listener;
+ }
+
+ OpenListener(CameraManager manager, String cameraId, CameraDevice.StateCallback listener,
+ Handler handler) throws CameraAccessException {
mCameraId = cameraId;
mProxy = listener;
manager.openCamera(cameraId, this, handler);
@@ -281,7 +285,7 @@ public class BlockingCameraManager {
if (mProxy != null) mProxy.onClosed(camera);
}
- CameraDevice blockUntilOpen() throws BlockingOpenException {
+ public CameraDevice blockUntilOpen() throws BlockingOpenException {
/**
* Block until onOpened, onError, or onDisconnected
*/