diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2023-04-02 08:49:16 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2023-04-02 08:49:16 +0000 |
commit | 35e5cbbfa78c4bb78cf02c38fc5bc91a2e166603 (patch) | |
tree | 3495a87fc207965d48a85d7f19a7ad5661436cf5 | |
parent | d187a93f4d37ce1041f381515eb8e201e1026f10 (diff) | |
parent | 9ed126c9d076ee4a4ee344d8324dda5392fd83a5 (diff) | |
download | ex-35e5cbbfa78c4bb78cf02c38fc5bc91a2e166603.tar.gz |
Merge "[service_based_sample] support basic extender implementation."
29 files changed, 1568 insertions, 754 deletions
diff --git a/camera2/extensions/service_based_sample/README.txt b/camera2/extensions/service_based_sample/README.txt new file mode 100644 index 00000000..a212a39a --- /dev/null +++ b/camera2/extensions/service_based_sample/README.txt @@ -0,0 +1,26 @@ +Service-Based reference implementation +This reference implementation demonstrates how to implement the Extensions in a standalone service. + +It contains the following components: +1) oem_library: + A Camera Extensions OEM library that implements the Extensions-Interface to enable both Camera2 + and CameraX Extensions APIS. It is basically a pass-through that forwards all calls from + Extensions-Interface to the service. If it works well for you, you don't have to modify it. + + It also contains the AIDL and wrapper classes for communicating with the service. AIDL and + wrapper classes are located in androidx.camera.extensions.impl.service package. + + Both Advanced Extender and Basic Extender is supported, however, Advanced Extender is enabled + by default. If you want to use Basic Extender to implement, change + ExtensionsVersionImpl#isAdvancedExtenderImplemented to return false. + +2) extensions_service: + A sample implementation of extensions service is provided. You should add your real implementation + here. The sample service is built using Android.bp, but you can transform it into a gradle + project by adding the stub jar of oem_library (located in + out/target/common/obj/JAVA_LIBRARIES/service_based_camera_extensions_intermediates/) to the + dependencies. + +In this service-based architecture, all functionalities of the Extensions-Interface are supposed to +be implemented in extensions_service except for ExtensionVersionImpl#checkApiVersion and +#isAdvancedExtenderImplemented which require you to implement it in the oem_library.
\ No newline at end of file diff --git a/camera2/extensions/service_based_sample/extensions_service/src/com/android/oemextensions/ExtensionsService.java b/camera2/extensions/service_based_sample/extensions_service/src/com/android/oemextensions/ExtensionsService.java index c3d62351..3a279716 100644 --- a/camera2/extensions/service_based_sample/extensions_service/src/com/android/oemextensions/ExtensionsService.java +++ b/camera2/extensions/service_based_sample/extensions_service/src/com/android/oemextensions/ExtensionsService.java @@ -23,10 +23,13 @@ import android.os.RemoteException; import android.util.Log; import androidx.annotation.NonNull; +import androidx.camera.extensions.impl.PreviewExtenderImpl; import androidx.camera.extensions.impl.service.IAdvancedExtenderImpl; import androidx.camera.extensions.impl.service.IExtensionsService; import androidx.camera.extensions.impl.service.IOnExtensionsDeinitializedCallback; import androidx.camera.extensions.impl.service.IOnExtensionsInitializedCallback; +import androidx.camera.extensions.impl.service.IImageCaptureExtenderImpl; +import androidx.camera.extensions.impl.service.IPreviewExtenderImpl; public class ExtensionsService extends Service { private static final String TAG = "ExtensionsService"; @@ -66,5 +69,15 @@ public class ExtensionsService extends Service { Log.d(TAG, "initializeAdvancedExtension"); return new AdvancedExtenderImplStub(ExtensionsService.this, extensionType); } + + @Override + public IPreviewExtenderImpl initializePreviewExtension(int extensionType) { + return new PreviewExtenderImplStub(ExtensionsService.this, extensionType); + } + + @Override + public IImageCaptureExtenderImpl initializeImageCaptureExtension(int extensionType) { + return new ImageCaptureExtenderImplStub(ExtensionsService.this, extensionType); + } } -}
\ No newline at end of file +} diff --git a/camera2/extensions/service_based_sample/extensions_service/src/com/android/oemextensions/ImageCaptureExtenderImplStub.java b/camera2/extensions/service_based_sample/extensions_service/src/com/android/oemextensions/ImageCaptureExtenderImplStub.java new file mode 100644 index 00000000..75cd99c9 --- /dev/null +++ b/camera2/extensions/service_based_sample/extensions_service/src/com/android/oemextensions/ImageCaptureExtenderImplStub.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2023 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 com.android.oemextensions; + +import android.content.Context; +import android.hardware.camera2.CameraAccessException; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraManager; +import android.hardware.camera2.CaptureRequest; +import android.hardware.camera2.CaptureResult; +import android.hardware.camera2.TotalCaptureResult; +import android.media.Image; +import android.media.ImageWriter; +import android.os.RemoteException; +import android.util.Log; +import android.view.Surface; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.service.CameraMetadataWrapper; +import androidx.camera.extensions.impl.service.CaptureBundle; +import androidx.camera.extensions.impl.service.CaptureStageImplWrapper; +import androidx.camera.extensions.impl.service.ICaptureProcessorImpl; +import androidx.camera.extensions.impl.service.IImageCaptureExtenderImpl; +import androidx.camera.extensions.impl.service.IProcessResultImpl; +import androidx.camera.extensions.impl.service.LatencyRange; +import androidx.camera.extensions.impl.service.Size; +import androidx.camera.extensions.impl.service.SizeList; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.List; + +public class ImageCaptureExtenderImplStub extends IImageCaptureExtenderImpl.Stub { + private static final String TAG = "ImageCaptureExtenderImplStub"; + + private static final int DEFAULT_STAGE_ID = 0; + private static final int SESSION_STAGE_ID = 101; + private static final int MODE = CaptureRequest.CONTROL_AWB_MODE_SHADE; + + private final Context mContext; + private final List<CaptureResult.Key> mResultKeyList = Arrays.asList( + CaptureResult.CONTROL_AE_MODE, + CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER, + CaptureResult.CONTROL_AE_LOCK, + CaptureResult.CONTROL_AE_STATE, + CaptureResult.FLASH_MODE, + CaptureResult.FLASH_STATE, + CaptureResult.JPEG_QUALITY, + CaptureResult.JPEG_ORIENTATION + ); + + private CameraCharacteristics mCameraCharacteristics; + ICaptureProcessorImpl mCaptureProcessor = + new ICaptureProcessorImpl.Stub() { + private ImageWriter mImageWriter; + + @Override + public void onOutputSurface(Surface surface, int imageFormat) { + mImageWriter = ImageWriter.newInstance(surface, 1); + } + + @Override + public void process(List<CaptureBundle> captureList, + IProcessResultImpl resultCallback) { + CaptureBundle captureBundle = captureList.get(0); + TotalCaptureResult captureResult = + captureBundle.captureResult.toTotalCaptureResult(); + + if (resultCallback != null) { + CameraMetadataWrapper cameraMetadataWrapper = + new CameraMetadataWrapper(mCameraCharacteristics); + Long shutterTimestamp = captureResult.get(CaptureResult.SENSOR_TIMESTAMP); + if (shutterTimestamp != null) { + for (CaptureResult.Key key : mResultKeyList) { + if (captureResult.get(key) != null) { + cameraMetadataWrapper.set(key, captureResult.get(key)); + } + } + try { + resultCallback.onCaptureCompleted(shutterTimestamp, + cameraMetadataWrapper); + } catch (RemoteException e) { + + } + } + } + Image image = mImageWriter.dequeueInputImage(); + + // Do processing here + ByteBuffer yByteBuffer = image.getPlanes()[0].getBuffer(); + ByteBuffer uByteBuffer = image.getPlanes()[2].getBuffer(); + ByteBuffer vByteBuffer = image.getPlanes()[1].getBuffer(); + + Image captureImage = captureBundle.captureImage.get(); + + // Sample here just simply copy/paste the capture image result + yByteBuffer.put(captureImage.getPlanes()[0].getBuffer()); + uByteBuffer.put(captureImage.getPlanes()[2].getBuffer()); + vByteBuffer.put(captureImage.getPlanes()[1].getBuffer()); + Long sensorTimestamp = + captureResult.get(CaptureResult.SENSOR_TIMESTAMP); + if (sensorTimestamp != null) { + image.setTimestamp(sensorTimestamp); + } else { + Log.e(TAG, "Sensor timestamp absent using default!"); + } + + mImageWriter.queueInputImage(image); + + for (CaptureBundle bundle : captureList) { + bundle.captureImage.decrement(); + } + } + + @Override + public void onResolutionUpdate(androidx.camera.extensions.impl.service.Size size) { + + } + + @Override + public void onImageFormatUpdate(int imageFormat) { + + } + }; + + public ImageCaptureExtenderImplStub(@NonNull Context context, int extensionType) { + mContext = context; + + } + + @Override + public void onInit(String cameraId) { + + } + + @Override + public void onDeInit() { + + } + + @Override + @Nullable + public CaptureStageImplWrapper onPresetSession() { + return null; + } + + @Override + @Nullable + public CaptureStageImplWrapper onEnableSession() { + return null; + } + + @Override + @Nullable + public CaptureStageImplWrapper onDisableSession() { + return null; + } + + @Override + public boolean isExtensionAvailable(String cameraId) { + return true; + } + + @Override + public void init(String cameraId) { + try { + CameraManager cameraManager = mContext.getSystemService(CameraManager.class); + mCameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId); + } catch (CameraAccessException e) { + Log.e(TAG, "Cannot get CameraCharacteristics", e); + } + + } + + @Override + public ICaptureProcessorImpl getCaptureProcessor() { + return mCaptureProcessor; + } + + @Override + public List<CaptureStageImplWrapper> getCaptureStages() { + CaptureStageImplWrapper captureStage = new CaptureStageImplWrapper(); + captureStage.id = DEFAULT_STAGE_ID; + captureStage.parameters = new CameraMetadataWrapper(mCameraCharacteristics); + return Arrays.asList(captureStage); + } + + @Override + public int getMaxCaptureStage() { + return 1; + } + + @Override + public List<SizeList> getSupportedResolutions() { + return null; + } + + @Override + @Nullable + public LatencyRange getEstimatedCaptureLatencyRange(Size outputSize) { + return null; + } + + @Override + public CameraMetadataWrapper getAvailableCaptureRequestKeys() { + return null; + } + + @Override + public CameraMetadataWrapper getAvailableCaptureResultKeys() { + return null; + } +} diff --git a/camera2/extensions/service_based_sample/extensions_service/src/com/android/oemextensions/PreviewExtenderImplStub.java b/camera2/extensions/service_based_sample/extensions_service/src/com/android/oemextensions/PreviewExtenderImplStub.java new file mode 100644 index 00000000..c9add1c7 --- /dev/null +++ b/camera2/extensions/service_based_sample/extensions_service/src/com/android/oemextensions/PreviewExtenderImplStub.java @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2023 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 com.android.oemextensions; + +import android.content.Context; +import android.hardware.camera2.CameraAccessException; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraExtensionCharacteristics; +import android.hardware.camera2.CameraManager; +import android.hardware.camera2.CaptureRequest; +import android.media.ImageWriter; +import android.util.Log; +import android.util.Size; +import android.view.Surface; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.service.CameraMetadataWrapper; +import androidx.camera.extensions.impl.service.CaptureStageImplWrapper; +import androidx.camera.extensions.impl.service.IPreviewExtenderImpl; +import androidx.camera.extensions.impl.service.IPreviewImageProcessorImpl; +import androidx.camera.extensions.impl.service.IProcessResultImpl; +import androidx.camera.extensions.impl.service.IRequestUpdateProcessorImpl; +import androidx.camera.extensions.impl.service.ImageWrapper; +import androidx.camera.extensions.impl.service.SizeList; +import androidx.camera.extensions.impl.service.TotalCaptureResultWrapper; + +import java.util.List; + +public class PreviewExtenderImplStub extends IPreviewExtenderImpl.Stub { + private static final String TAG = "PreviewExtenderImplStub"; + + private static final int DEFAULT_STAGE_ID = 0; + private static final int SESSION_STAGE_ID = 101; + private static final int MODE = CaptureRequest.CONTROL_AWB_MODE_SHADE; + private final int mProcessorType; + private final Context mContext; + private CaptureStageImplWrapper mCaptureStage; + private CameraCharacteristics mCameraCharacteristics; + private final SimplePreviewImageProcessor mPreviewImageProcessor; + private final SimpleRequestUpdateProcessor mRequestUpdateProcessor; + + public PreviewExtenderImplStub(@NonNull Context context, int extensionType) { + mContext = context; + switch (extensionType) { + case CameraExtensionCharacteristics.EXTENSION_AUTOMATIC: + case CameraExtensionCharacteristics.EXTENSION_BOKEH: + mRequestUpdateProcessor = new SimpleRequestUpdateProcessor(); + mPreviewImageProcessor = null; + mProcessorType = IPreviewExtenderImpl.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY; + break; + case CameraExtensionCharacteristics.EXTENSION_HDR: + case CameraExtensionCharacteristics.EXTENSION_NIGHT: + mRequestUpdateProcessor = null; + mPreviewImageProcessor = new SimplePreviewImageProcessor(); + mProcessorType = IPreviewExtenderImpl.PROCESSOR_TYPE_IMAGE_PROCESSOR; + break; + case CameraExtensionCharacteristics.EXTENSION_FACE_RETOUCH: + default: + mRequestUpdateProcessor = null; + mPreviewImageProcessor = null; + mProcessorType = IPreviewExtenderImpl.PROCESSOR_TYPE_NONE; + break; + } + } + + private class SimpleRequestUpdateProcessor extends IRequestUpdateProcessorImpl.Stub { + private int mFrameCount = 0; + private Integer mWBMode = CaptureRequest.CONTROL_AWB_MODE_AUTO; + + @Override + public CaptureStageImplWrapper process(TotalCaptureResultWrapper result) { + mFrameCount++; + if (mFrameCount % 90 == 0) { + mCaptureStage = new CaptureStageImplWrapper(); + mCaptureStage.id = DEFAULT_STAGE_ID; + switch (mWBMode) { + case CaptureRequest.CONTROL_AWB_MODE_AUTO: + mWBMode = MODE; + break; + case MODE: + mWBMode = CaptureRequest.CONTROL_AWB_MODE_AUTO; + break; default: + } + mCaptureStage.parameters = new CameraMetadataWrapper( + mCameraCharacteristics); + mCaptureStage.parameters.set(CaptureRequest.CONTROL_AWB_MODE, + mWBMode); + mFrameCount = 0; + + return mCaptureStage; + } + return null; + } + }; + private static class SimplePreviewImageProcessor extends IPreviewImageProcessorImpl.Stub { + private ImageWriter mWriter; + + public void close() { + if (mWriter != null) { + mWriter.close(); + } + } + @Override + public void onOutputSurface(Surface surface, int imageFormat) { + mWriter = ImageWriter.newInstance(surface, imageFormat); + } + + @Override + public void onResolutionUpdate( + androidx.camera.extensions.impl.service.Size size) { + } + + @Override + public void onImageFormatUpdate(int imageFormat) { + } + + @Override + public void process(ImageWrapper image, TotalCaptureResultWrapper result, + IProcessResultImpl resultCallback) { + mWriter.queueInputImage(image.get()); + image.decrement(); + } + } + + @Override + public void onInit(String cameraId) { + + } + + @Override + public void onDeInit() { + if (mPreviewImageProcessor != null) { + mPreviewImageProcessor.close(); + } + } + + @Override + @Nullable + public CaptureStageImplWrapper onPresetSession() { + CaptureStageImplWrapper captureStage = new CaptureStageImplWrapper(); + captureStage.id = SESSION_STAGE_ID; + captureStage.parameters = new CameraMetadataWrapper(mCameraCharacteristics); + captureStage.parameters.set(CaptureRequest.CONTROL_AWB_MODE, MODE); + return captureStage; + } + + @Override + @Nullable + public CaptureStageImplWrapper onEnableSession() { + CaptureStageImplWrapper captureStage = new CaptureStageImplWrapper(); + captureStage.id = SESSION_STAGE_ID; + captureStage.parameters = new CameraMetadataWrapper(mCameraCharacteristics); + captureStage.parameters.set(CaptureRequest.CONTROL_AWB_MODE, MODE); + return captureStage; + } + + @Override + @Nullable + public CaptureStageImplWrapper onDisableSession() { + CaptureStageImplWrapper captureStage = new CaptureStageImplWrapper(); + captureStage.id = SESSION_STAGE_ID; + captureStage.parameters = new CameraMetadataWrapper(mCameraCharacteristics); + captureStage.parameters.set(CaptureRequest.CONTROL_AWB_MODE, MODE); + return captureStage; + } + + @Override + public boolean isExtensionAvailable(String cameraId) { + return true; + } + + @Override + public void init(String cameraId) { + try { + CameraManager cameraManager = mContext.getSystemService(CameraManager.class); + mCameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId); + } catch (CameraAccessException e) { + Log.e(TAG, "Cannot get CameraCharacteristics", e); + } + + mCaptureStage = new CaptureStageImplWrapper(); + mCaptureStage.id = DEFAULT_STAGE_ID; + mCaptureStage.parameters = new CameraMetadataWrapper(mCameraCharacteristics); + mCaptureStage.parameters.set(CaptureRequest.CONTROL_AWB_MODE, + CaptureRequest.CONTROL_AWB_MODE_AUTO); + } + + @Override + public CaptureStageImplWrapper getCaptureStage() { + return mCaptureStage; + } + + @Override + public int getProcessorType() { + return mProcessorType; + } + + @Override + @Nullable + public IPreviewImageProcessorImpl getPreviewImageProcessor() { + return mPreviewImageProcessor; + } + + @Override + @Nullable + public IRequestUpdateProcessorImpl getRequestUpdateProcessor() { + return mRequestUpdateProcessor; + } + + @Override + @Nullable + public List<SizeList> getSupportedResolutions() { + return null; + } +}
\ No newline at end of file diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java index 514ca3b5..55486a3c 100755 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/AutoImageCaptureExtenderImpl.java @@ -17,6 +17,7 @@ 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.util.Pair; @@ -25,6 +26,7 @@ import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.serviceforward.ForwardImageCaptureExtender; import java.util.List; @@ -35,90 +37,8 @@ import java.util.List; * * @since 1.0 */ -public final class AutoImageCaptureExtenderImpl implements ImageCaptureExtenderImpl { - public AutoImageCaptureExtenderImpl() {} - - @Override - public boolean isExtensionAvailable(@NonNull String cameraId, - @Nullable CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void init(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureProcessorImpl getCaptureProcessor() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<CaptureStageImpl> getCaptureStages() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public int getMaxCaptureStage() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onInit(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics, - @NonNull Context context) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onDeInit() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onPresetSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onEnableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onDisableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<Pair<Integer, Size[]>> getSupportedResolutions() { - throw new RuntimeException("Stub, replace with implementation."); +public final class AutoImageCaptureExtenderImpl extends ForwardImageCaptureExtender { + public AutoImageCaptureExtenderImpl() { + super(CameraExtensionCharacteristics.EXTENSION_AUTOMATIC); } - - @Nullable - @Override - public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public List<CaptureResult.Key> getAvailableCaptureResultKeys() { - throw new RuntimeException("Stub, replace with implementation."); - } - } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java index 85b63df7..94b8808a 100755 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/AutoPreviewExtenderImpl.java @@ -18,11 +18,13 @@ package androidx.camera.extensions.impl; import android.content.Context; import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraExtensionCharacteristics; import android.util.Pair; import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.serviceforward.ForwardPreviewExtender; import java.util.List; @@ -33,73 +35,8 @@ import java.util.List; * * @since 1.0 */ -public final class AutoPreviewExtenderImpl implements PreviewExtenderImpl { +public final class AutoPreviewExtenderImpl extends ForwardPreviewExtender { public AutoPreviewExtenderImpl() { - } - - @Override - public boolean isExtensionAvailable(@NonNull String cameraId, - @Nullable CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void init(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public CaptureStageImpl getCaptureStage() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public ProcessorType getProcessorType() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public ProcessorImpl getProcessor() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onInit(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics, - @NonNull Context context) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onDeInit() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onPresetSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onEnableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onDisableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<Pair<Integer, Size[]>> getSupportedResolutions() { - throw new RuntimeException("Stub, replace with implementation."); + super(CameraExtensionCharacteristics.EXTENSION_AUTOMATIC); } } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java index c547f772..ce9e9ea1 100755 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BeautyImageCaptureExtenderImpl.java @@ -17,6 +17,7 @@ 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.util.Pair; @@ -25,6 +26,7 @@ import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.serviceforward.ForwardImageCaptureExtender; import java.util.List; @@ -35,89 +37,8 @@ import java.util.List; * * @since 1.0 */ -public final class BeautyImageCaptureExtenderImpl implements ImageCaptureExtenderImpl { - public BeautyImageCaptureExtenderImpl() {} - - @Override - public boolean isExtensionAvailable(@NonNull String cameraId, - @Nullable CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void init(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureProcessorImpl getCaptureProcessor() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<CaptureStageImpl> getCaptureStages() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public int getMaxCaptureStage() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onInit(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics, - @NonNull Context context) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onDeInit() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onPresetSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onEnableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onDisableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<Pair<Integer, Size[]>> getSupportedResolutions() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public List<CaptureResult.Key> getAvailableCaptureResultKeys() { - throw new RuntimeException("Stub, replace with implementation."); +public final class BeautyImageCaptureExtenderImpl extends ForwardImageCaptureExtender { + public BeautyImageCaptureExtenderImpl() { + super(CameraExtensionCharacteristics.EXTENSION_FACE_RETOUCH); } } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java index da5748cc..0a452c33 100755 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BeautyPreviewExtenderImpl.java @@ -18,11 +18,13 @@ package androidx.camera.extensions.impl; import android.content.Context; import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraExtensionCharacteristics; import android.util.Pair; import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.serviceforward.ForwardPreviewExtender; import java.util.List; @@ -33,73 +35,8 @@ import java.util.List; * * @since 1.0 */ -public final class BeautyPreviewExtenderImpl implements PreviewExtenderImpl { +public final class BeautyPreviewExtenderImpl extends ForwardPreviewExtender { public BeautyPreviewExtenderImpl() { - } - - @Override - public boolean isExtensionAvailable(@NonNull String cameraId, - @Nullable CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void init(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public CaptureStageImpl getCaptureStage() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public ProcessorType getProcessorType() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public ProcessorImpl getProcessor() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onInit(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics, - @NonNull Context context) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onDeInit() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onPresetSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onEnableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onDisableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<Pair<Integer, Size[]>> getSupportedResolutions() { - throw new RuntimeException("Stub, replace with implementation."); + super(CameraExtensionCharacteristics.EXTENSION_FACE_RETOUCH); } } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java index 6901e5f3..f24e9f1d 100644 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BokehImageCaptureExtenderImpl.java @@ -17,6 +17,7 @@ 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.util.Pair; @@ -25,6 +26,7 @@ import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.serviceforward.ForwardImageCaptureExtender; import java.util.List; @@ -35,87 +37,8 @@ import java.util.List; * * @since 1.0 */ -public final class BokehImageCaptureExtenderImpl implements ImageCaptureExtenderImpl { - public BokehImageCaptureExtenderImpl() {} - - @Override - public boolean isExtensionAvailable(@NonNull String cameraId, - @Nullable CameraCharacteristics cameraCharacteristics) { - return true; - } - - @Override - public void init(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics) { - } - - @Nullable - @Override - public CaptureProcessorImpl getCaptureProcessor() { - return null; - } - - @Nullable - @Override - public List<CaptureStageImpl> getCaptureStages() { - return null; - } - - @Override - public int getMaxCaptureStage() { - return 2; - } - - @Override - public void onInit(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics, - @NonNull Context context) { - } - - @Override - public void onDeInit() { - } - - @Nullable - @Override - public CaptureStageImpl onPresetSession() { - return null; - } - - @Nullable - @Override - public CaptureStageImpl onEnableSession() { - return null; - } - - @Nullable - @Override - public CaptureStageImpl onDisableSession() { - return null; - } - - @Nullable - @Override - public List<Pair<Integer, Size[]>> getSupportedResolutions() { - return null; +public final class BokehImageCaptureExtenderImpl extends ForwardImageCaptureExtender { + public BokehImageCaptureExtenderImpl() { + super(CameraExtensionCharacteristics.EXTENSION_BOKEH); } - - @Nullable - @Override - public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) { - return null; - } - - @NonNull - @Override - public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() { - return null; - } - - @NonNull - @Override - public List<CaptureResult.Key> getAvailableCaptureResultKeys() { - return null; - } - } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java index 55902f04..e17d9415 100644 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/BokehPreviewExtenderImpl.java @@ -17,11 +17,13 @@ package androidx.camera.extensions.impl; import android.content.Context; import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraExtensionCharacteristics; import android.util.Pair; import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.serviceforward.ForwardPreviewExtender; import java.util.List; @@ -32,69 +34,8 @@ import java.util.List; * * @since 1.0 */ -public final class BokehPreviewExtenderImpl implements PreviewExtenderImpl { - public BokehPreviewExtenderImpl() {} - - @Override - public boolean isExtensionAvailable(@NonNull String cameraId, - @Nullable CameraCharacteristics cameraCharacteristics) { - return true; - } - - @Override - public void init(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics) { - } - - @NonNull - @Override - public CaptureStageImpl getCaptureStage() { - return null; - } - - @NonNull - @Override - public ProcessorType getProcessorType() { - return ProcessorType.PROCESSOR_TYPE_NONE; - } - - @Nullable - @Override - public ProcessorImpl getProcessor() { - return null; - } - - @Override - public void onInit(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics, - @NonNull Context context) { - } - - @Override - public void onDeInit() { - } - - @Nullable - @Override - public CaptureStageImpl onPresetSession() { - return null; - } - - @Nullable - @Override - public CaptureStageImpl onEnableSession() { - return null; - } - - @Nullable - @Override - public CaptureStageImpl onDisableSession() { - return null; - } - - @Nullable - @Override - public List<Pair<Integer, Size[]>> getSupportedResolutions() { - return null; +public final class BokehPreviewExtenderImpl extends ForwardPreviewExtender { + public BokehPreviewExtenderImpl() { + super(CameraExtensionCharacteristics.EXTENSION_BOKEH); } } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java index 507f2143..264a714e 100644 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/HdrImageCaptureExtenderImpl.java @@ -17,6 +17,7 @@ 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.util.Pair; @@ -25,6 +26,7 @@ import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.serviceforward.ForwardImageCaptureExtender; import java.util.List; @@ -35,89 +37,8 @@ import java.util.List; * * @since 1.0 */ -public final class HdrImageCaptureExtenderImpl implements ImageCaptureExtenderImpl { - public HdrImageCaptureExtenderImpl() {} - - @Override - public boolean isExtensionAvailable(@NonNull String cameraId, - @Nullable CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void init(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureProcessorImpl getCaptureProcessor() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<CaptureStageImpl> getCaptureStages() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public int getMaxCaptureStage() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onInit(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics, - @NonNull Context context) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onDeInit() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onPresetSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onEnableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onDisableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<Pair<Integer, Size[]>> getSupportedResolutions() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public List<CaptureResult.Key> getAvailableCaptureResultKeys() { - throw new RuntimeException("Stub, replace with implementation."); +public final class HdrImageCaptureExtenderImpl extends ForwardImageCaptureExtender { + public HdrImageCaptureExtenderImpl() { + super(CameraExtensionCharacteristics.EXTENSION_HDR); } } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java index 83f1a348..8e7bbd85 100644 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/HdrPreviewExtenderImpl.java @@ -18,11 +18,13 @@ package androidx.camera.extensions.impl; import android.content.Context; import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraExtensionCharacteristics; import android.util.Pair; import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.serviceforward.ForwardPreviewExtender; import java.util.List; @@ -33,73 +35,8 @@ import java.util.List; * * @since 1.0 */ -public final class HdrPreviewExtenderImpl implements PreviewExtenderImpl { +public final class HdrPreviewExtenderImpl extends ForwardPreviewExtender { public HdrPreviewExtenderImpl() { - } - - @Override - public boolean isExtensionAvailable(@NonNull String cameraId, - @Nullable CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void init(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public CaptureStageImpl getCaptureStage() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public ProcessorType getProcessorType() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public ProcessorImpl getProcessor() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onInit(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics, - @NonNull Context context) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onDeInit() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onPresetSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onEnableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onDisableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<Pair<Integer, Size[]>> getSupportedResolutions() { - throw new RuntimeException("Stub, replace with implementation."); + super(CameraExtensionCharacteristics.EXTENSION_HDR); } } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java index 05a195e1..36c554fb 100755 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/NightImageCaptureExtenderImpl.java @@ -17,6 +17,7 @@ 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.util.Pair; @@ -25,6 +26,7 @@ import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.serviceforward.ForwardImageCaptureExtender; import java.util.List; @@ -35,89 +37,8 @@ import java.util.List; * * @since 1.0 */ -public final class NightImageCaptureExtenderImpl implements ImageCaptureExtenderImpl { - public NightImageCaptureExtenderImpl() {} - - @Override - public boolean isExtensionAvailable(@NonNull String cameraId, - @Nullable CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void init(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureProcessorImpl getCaptureProcessor() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<CaptureStageImpl> getCaptureStages() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public int getMaxCaptureStage() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onInit(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics, - @NonNull Context context) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onDeInit() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onPresetSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onEnableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onDisableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<Pair<Integer, Size[]>> getSupportedResolutions() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public Range<Long> getEstimatedCaptureLatencyRange(@Nullable Size captureOutputSize) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public List<CaptureResult.Key> getAvailableCaptureResultKeys() { - throw new RuntimeException("Stub, replace with implementation."); +public final class NightImageCaptureExtenderImpl extends ForwardImageCaptureExtender { + public NightImageCaptureExtenderImpl() { + super(CameraExtensionCharacteristics.EXTENSION_NIGHT); } } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java index eeb254b2..973e79cf 100755 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/NightPreviewExtenderImpl.java @@ -18,11 +18,13 @@ package androidx.camera.extensions.impl; import android.content.Context; import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraExtensionCharacteristics; import android.util.Pair; import android.util.Size; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.serviceforward.ForwardPreviewExtender; import java.util.List; @@ -33,73 +35,8 @@ import java.util.List; * * @since 1.0 */ -public final class NightPreviewExtenderImpl implements PreviewExtenderImpl { +public final class NightPreviewExtenderImpl extends ForwardPreviewExtender { public NightPreviewExtenderImpl() { - } - - @Override - public boolean isExtensionAvailable(@NonNull String cameraId, - @Nullable CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void init(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public CaptureStageImpl getCaptureStage() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @NonNull - @Override - public ProcessorType getProcessorType() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public ProcessorImpl getProcessor() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onInit(@NonNull String cameraId, - @NonNull CameraCharacteristics cameraCharacteristics, - @NonNull Context context) { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Override - public void onDeInit() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onPresetSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onEnableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public CaptureStageImpl onDisableSession() { - throw new RuntimeException("Stub, replace with implementation."); - } - - @Nullable - @Override - public List<Pair<Integer, Size[]>> getSupportedResolutions() { - throw new RuntimeException("Stub, replace with implementation."); + super(CameraExtensionCharacteristics.EXTENSION_NIGHT); } } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/CameraMetadataWrapper.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/CameraMetadataWrapper.java index 100203b2..02f83142 100644 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/CameraMetadataWrapper.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/CameraMetadataWrapper.java @@ -39,6 +39,10 @@ public class CameraMetadataWrapper implements Parcelable { } } + public CameraMetadataWrapper(CameraMetadataNative cameraMetadataNative) { + mCameraMetadataNative = cameraMetadataNative; + } + protected CameraMetadataWrapper(Parcel in) { mCameraMetadataNative = in.readParcelable(CameraMetadataNative.class.getClassLoader()); } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/CaptureBundle.aidl b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/CaptureBundle.aidl new file mode 100644 index 00000000..6b21485d --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/CaptureBundle.aidl @@ -0,0 +1,27 @@ + +/* + * Copyright 2023 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.service; + +import androidx.camera.extensions.impl.service.CameraMetadataWrapper; +import androidx.camera.extensions.impl.service.ImageWrapper; + +parcelable CaptureBundle +{ + int stageId; + CameraMetadataWrapper captureResult; + ImageWrapper captureImage; +} diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/CaptureStageImplWrapper.aidl b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/CaptureStageImplWrapper.aidl new file mode 100644 index 00000000..3092d766 --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/CaptureStageImplWrapper.aidl @@ -0,0 +1,24 @@ +/* + * Copyright 2023 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.service; + +import androidx.camera.extensions.impl.service.CameraMetadataWrapper; + +parcelable CaptureStageImplWrapper +{ + int id; + CameraMetadataWrapper parameters; +} diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/ICaptureProcessorImpl.aidl b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/ICaptureProcessorImpl.aidl new file mode 100644 index 00000000..d3d73589 --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/ICaptureProcessorImpl.aidl @@ -0,0 +1,30 @@ +/* + * Copyright 2023 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.service; + +import androidx.camera.extensions.impl.service.CaptureBundle; +import androidx.camera.extensions.impl.service.IProcessResultImpl; +import androidx.camera.extensions.impl.service.Size; + +import android.view.Surface; + +interface ICaptureProcessorImpl +{ + void onOutputSurface(in Surface surface, int imageFormat); + void onResolutionUpdate(in Size size); + void onImageFormatUpdate(int imageFormat); + void process(in List<CaptureBundle> capturelist, in IProcessResultImpl resultCallback); +} diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IExtensionsService.aidl b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IExtensionsService.aidl index db73ad00..5f0bc57d 100644 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IExtensionsService.aidl +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IExtensionsService.aidl @@ -19,11 +19,16 @@ package androidx.camera.extensions.impl.service; import androidx.camera.extensions.impl.service.IOnExtensionsInitializedCallback; import androidx.camera.extensions.impl.service.IOnExtensionsDeinitializedCallback; import androidx.camera.extensions.impl.service.IAdvancedExtenderImpl; +import androidx.camera.extensions.impl.service.IPreviewExtenderImpl; +import androidx.camera.extensions.impl.service.IImageCaptureExtenderImpl; + import androidx.camera.extensions.impl.service.Size; interface IExtensionsService { boolean isAdvancedExtenderImplemented(); void initialize(in String version, in IOnExtensionsInitializedCallback callback); void deInitialize(in IOnExtensionsDeinitializedCallback callback); - @nullable IAdvancedExtenderImpl initializeAdvancedExtension(int extensionType); + IAdvancedExtenderImpl initializeAdvancedExtension(int extensionType); + IPreviewExtenderImpl initializePreviewExtension(int extensionType); + IImageCaptureExtenderImpl initializeImageCaptureExtension(int extensionType); } diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IImageCaptureExtenderImpl.aidl b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IImageCaptureExtenderImpl.aidl new file mode 100644 index 00000000..0ce4856e --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IImageCaptureExtenderImpl.aidl @@ -0,0 +1,42 @@ +/* + * Copyright 2023 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.service; + +import androidx.camera.extensions.impl.service.CameraMetadataWrapper; +import androidx.camera.extensions.impl.service.SizeList; +import androidx.camera.extensions.impl.service.ICaptureProcessorImpl; +import androidx.camera.extensions.impl.service.CaptureStageImplWrapper; +import androidx.camera.extensions.impl.service.LatencyRange; +import androidx.camera.extensions.impl.service.Size; + + +interface IImageCaptureExtenderImpl +{ + void onInit(in String cameraId); + void onDeInit(); + @nullable CaptureStageImplWrapper onPresetSession(); + @nullable CaptureStageImplWrapper onEnableSession(); + @nullable CaptureStageImplWrapper onDisableSession(); + boolean isExtensionAvailable(in String cameraId); + void init(in String cameraId); + @nullable ICaptureProcessorImpl getCaptureProcessor(); + List<CaptureStageImplWrapper> getCaptureStages(); + int getMaxCaptureStage(); + @nullable List<SizeList> getSupportedResolutions(); + @nullable LatencyRange getEstimatedCaptureLatencyRange(in Size outputSize); + CameraMetadataWrapper getAvailableCaptureRequestKeys(); + CameraMetadataWrapper getAvailableCaptureResultKeys(); +} diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IPreviewExtenderImpl.aidl b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IPreviewExtenderImpl.aidl new file mode 100644 index 00000000..193c4dc7 --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IPreviewExtenderImpl.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2023 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.service; + +import androidx.camera.extensions.impl.service.CameraMetadataWrapper; +import androidx.camera.extensions.impl.service.SizeList; +import androidx.camera.extensions.impl.service.CaptureStageImplWrapper; +import androidx.camera.extensions.impl.service.IPreviewImageProcessorImpl; +import androidx.camera.extensions.impl.service.IRequestUpdateProcessorImpl; + +interface IPreviewExtenderImpl +{ + void onInit(in String cameraId); + void onDeInit(); + @nullable CaptureStageImplWrapper onPresetSession(); + @nullable CaptureStageImplWrapper onEnableSession(); + @nullable CaptureStageImplWrapper onDisableSession(); + boolean isExtensionAvailable(in String cameraId); + void init(in String cameraId); + @nullable CaptureStageImplWrapper getCaptureStage(); + const int PROCESSOR_TYPE_REQUEST_UPDATE_ONLY = 0; + const int PROCESSOR_TYPE_IMAGE_PROCESSOR = 1; + const int PROCESSOR_TYPE_NONE = 2; + int getProcessorType(); + @nullable IPreviewImageProcessorImpl getPreviewImageProcessor(); + @nullable IRequestUpdateProcessorImpl getRequestUpdateProcessor(); + @nullable List<SizeList> getSupportedResolutions(); +} diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IPreviewImageProcessorImpl.aidl b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IPreviewImageProcessorImpl.aidl new file mode 100644 index 00000000..22ccfd14 --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IPreviewImageProcessorImpl.aidl @@ -0,0 +1,33 @@ +/* + * Copyright 2023 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.service; + +import androidx.camera.extensions.impl.service.TotalCaptureResultWrapper; +import androidx.camera.extensions.impl.service.IProcessResultImpl; +import androidx.camera.extensions.impl.service.Size; +import androidx.camera.extensions.impl.service.ImageWrapper; +import android.view.Surface; + + +interface IPreviewImageProcessorImpl +{ + void onOutputSurface(in Surface surface, int imageFormat); + void onResolutionUpdate(in Size size); + void onImageFormatUpdate(int imageFormat); + void process(in ImageWrapper image, in TotalCaptureResultWrapper result, + in IProcessResultImpl resultCallback); + +} diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IProcessResultImpl.aidl b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IProcessResultImpl.aidl new file mode 100644 index 00000000..f921ea02 --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IProcessResultImpl.aidl @@ -0,0 +1,23 @@ +/* + * Copyright 2023 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.service; + +import androidx.camera.extensions.impl.service.CameraMetadataWrapper; + +interface IProcessResultImpl +{ + void onCaptureCompleted(long shutterTimestamp, in CameraMetadataWrapper results); +} diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IRequestUpdateProcessorImpl.aidl b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IRequestUpdateProcessorImpl.aidl new file mode 100644 index 00000000..f6e78d2b --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/service/IRequestUpdateProcessorImpl.aidl @@ -0,0 +1,27 @@ +/* + * Copyright 2023 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.service; + +import androidx.camera.extensions.impl.service.TotalCaptureResultWrapper; +import androidx.camera.extensions.impl.service.Size; +import androidx.camera.extensions.impl.service.CaptureStageImplWrapper; +import android.view.Surface; + + +interface IRequestUpdateProcessorImpl +{ + @nullable CaptureStageImplWrapper process(in TotalCaptureResultWrapper result); +} diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/CaptureStageImplAdapter.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/CaptureStageImplAdapter.java new file mode 100644 index 00000000..43ddf4a9 --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/CaptureStageImplAdapter.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 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.serviceforward; + +import android.hardware.camera2.CaptureRequest; +import android.util.Pair; + +import androidx.camera.extensions.impl.CaptureStageImpl; +import androidx.camera.extensions.impl.service.CaptureStageImplWrapper; + +import java.util.ArrayList; +import java.util.List; + +class CaptureStageImplAdapter implements CaptureStageImpl { + private final CaptureStageImplWrapper mCaptureStageImplWrapper; + CaptureStageImplAdapter(CaptureStageImplWrapper wrapper) { + mCaptureStageImplWrapper = wrapper; + } + + @Override + public int getId() { + return mCaptureStageImplWrapper.id; + } + + @Override + public List<Pair<CaptureRequest.Key, Object>> getParameters() { + CaptureRequest request = mCaptureStageImplWrapper.parameters.toCaptureRequest(); + List<Pair<CaptureRequest.Key, Object>> result = new ArrayList<>(); + for (CaptureRequest.Key<?> key : request.getKeys()) { + result.add(new Pair(key, request.get(key))); + } + return result; + } +}
\ No newline at end of file diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ForwardAdvancedExtender.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ForwardAdvancedExtender.java index 40f2c136..dc57590a 100644 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ForwardAdvancedExtender.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ForwardAdvancedExtender.java @@ -84,7 +84,6 @@ public class ForwardAdvancedExtender implements AdvancedExtenderImpl { throw new IllegalStateException("init failed", e); } } - @Override @Nullable public Range<Long> getEstimatedCaptureLatencyRange(@NonNull String cameraId, diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ForwardImageCaptureExtender.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ForwardImageCaptureExtender.java new file mode 100644 index 00000000..03de94bf --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ForwardImageCaptureExtender.java @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2023 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.serviceforward; + +import android.content.Context; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CaptureRequest; +import android.hardware.camera2.CaptureResult; +import android.hardware.camera2.TotalCaptureResult; +import android.media.Image; +import android.os.RemoteException; +import android.util.Log; +import android.util.Pair; +import android.util.Range; +import android.util.Size; +import android.view.Surface; + +import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.CaptureProcessorImpl; +import androidx.camera.extensions.impl.CaptureStageImpl; +import androidx.camera.extensions.impl.ImageCaptureExtenderImpl; +import androidx.camera.extensions.impl.ProcessResultImpl; +import androidx.camera.extensions.impl.service.CameraMetadataWrapper; +import androidx.camera.extensions.impl.service.CaptureBundle; +import androidx.camera.extensions.impl.service.CaptureStageImplWrapper; +import androidx.camera.extensions.impl.service.ICaptureProcessorImpl; +import androidx.camera.extensions.impl.service.IImageCaptureExtenderImpl; +import androidx.camera.extensions.impl.service.IProcessResultImpl; +import androidx.camera.extensions.impl.service.ImageWrapper; +import androidx.camera.extensions.impl.service.LatencyRange; +import androidx.camera.extensions.impl.service.SizeList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +public class ForwardImageCaptureExtender implements ImageCaptureExtenderImpl { + + private static final String TAG = "ForwardPreviewExtender"; + + private final int mExtensionType; + private IImageCaptureExtenderImpl mIImageCaptureExtender; + + public ForwardImageCaptureExtender(int extensionType) { + mExtensionType = extensionType; + mIImageCaptureExtender = ServiceManager.getInstance() + .createImageCaptureExtenderImpl(extensionType); + } + + @Nullable + private static CaptureStageImpl convertToCaptureStageImpl( + @Nullable CaptureStageImplWrapper wrapper) { + if (wrapper == null) { + return null; + } + + return new CaptureStageImplAdapter(wrapper); + } + + @Override + public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics, + Context context) { + try { + mIImageCaptureExtender.onInit(cameraId); + } catch (RemoteException e) { + Log.e(TAG, "onInit failed", e); + throw new IllegalStateException("onInit failed", e); + } + } + + @Override + public void onDeInit() { + try { + mIImageCaptureExtender.onDeInit(); + } catch (RemoteException e) { + Log.e(TAG, "onDeInit failed", e); + throw new IllegalStateException("onDeInit failed", e); + } + } + + @Override + public CaptureStageImpl onPresetSession() { + try { + return convertToCaptureStageImpl(mIImageCaptureExtender.onPresetSession()); + } catch (RemoteException e) { + Log.e(TAG, "onPresetSession failed", e); + throw new IllegalStateException("onPresetSession failed", e); + } + } + + @Override + public CaptureStageImpl onEnableSession() { + try { + return convertToCaptureStageImpl(mIImageCaptureExtender.onEnableSession()); + } catch (RemoteException e) { + Log.e(TAG, "onEnableSession failed", e); + throw new IllegalStateException("onEnableSession failed", e); + } + } + + @Override + public CaptureStageImpl onDisableSession() { + try { + return convertToCaptureStageImpl(mIImageCaptureExtender.onDisableSession()); + } catch (RemoteException e) { + Log.e(TAG, "onDisableSession failed", e); + throw new IllegalStateException("onDisableSession failed", e); + } + } + + @Override + public boolean isExtensionAvailable(String cameraId, + CameraCharacteristics cameraCharacteristics) { + try { + return mIImageCaptureExtender.isExtensionAvailable(cameraId); + } catch (RemoteException e) { + Log.e(TAG, "isExtensionAvailable failed", e); + throw new IllegalStateException("isExtensionAvailable failed", e); + } + } + + @Override + public void init(String cameraId, CameraCharacteristics cameraCharacteristics) { + try { + mIImageCaptureExtender.init(cameraId); + } catch (RemoteException e) { + Log.e(TAG, "init failed", e); + throw new IllegalStateException("init failed", e); + } + } + + @Override + public CaptureProcessorImpl getCaptureProcessor() { + try { + ICaptureProcessorImpl captureProcessor = mIImageCaptureExtender.getCaptureProcessor(); + if (captureProcessor == null) { + return null; + } + return new CaptureProcessorImplAdapter(captureProcessor); + } catch (RemoteException e) { + Log.e(TAG, "getCaptureProcessor failed", e); + throw new IllegalStateException("getCaptureProcessor failed", e); + } + } + + @Override + public List<CaptureStageImpl> getCaptureStages() { + try { + List<CaptureStageImpl> results = new ArrayList<>(); + for (CaptureStageImplWrapper wrapper : mIImageCaptureExtender.getCaptureStages()) { + results.add(convertToCaptureStageImpl(wrapper)); + } + return results; + } catch (RemoteException e) { + Log.e(TAG, "getCaptureStages failed", e); + throw new IllegalStateException("getCaptureStages failed", e); + } + } + + @Override + public int getMaxCaptureStage() { + try { + return mIImageCaptureExtender.getMaxCaptureStage(); + } catch (RemoteException e) { + Log.e(TAG, "getMaxCaptureStage failed", e); + throw new IllegalStateException("getMaxCaptureStage failed", e); + } + } + + @Override + public List<Pair<Integer, Size[]>> getSupportedResolutions() { + try { + List<SizeList> sizes = mIImageCaptureExtender.getSupportedResolutions(); + if (sizes == null) { + return null; + } + + List<Pair<Integer, Size[]>> list = new ArrayList<>(); + for (SizeList sizeList : sizes) { + Size[] sizeArray = new Size[sizeList.sizes.size()]; + for (int i = 0; i < sizeList.sizes.size(); i++) { + sizeArray[i] = new Size(sizeList.sizes.get(i).width, + sizeList.sizes.get(i).height); + } + list.add(new Pair(sizeList.format, sizeArray)); + } + return list; + } catch (RemoteException e) { + Log.e(TAG, "getSupportedResolutions failed", e); + throw new IllegalStateException("getSupportedResolutions failed", e); + } + } + + @Override + public Range<Long> getEstimatedCaptureLatencyRange(Size captureOutputSize) { + try { + androidx.camera.extensions.impl.service.Size size = null; + if (captureOutputSize != null) { + size = new androidx.camera.extensions.impl.service.Size(); + size.width = captureOutputSize.getWidth(); + size.height = captureOutputSize.getHeight(); + } + LatencyRange latencyRange = + mIImageCaptureExtender.getEstimatedCaptureLatencyRange(size); + if (latencyRange == null) { + return null; + } + + return new Range<Long>(latencyRange.min, latencyRange.max); + } catch (RemoteException e) { + Log.e(TAG, "getEstimatedCaptureLatencyRange failed", e); + throw new IllegalStateException("getEstimatedCaptureLatencyRange failed", e); + } + } + + @Override + public List<CaptureRequest.Key> getAvailableCaptureRequestKeys() { + try { + CameraMetadataWrapper cameraMetadataWrapper + = mIImageCaptureExtender.getAvailableCaptureRequestKeys(); + if (cameraMetadataWrapper == null) { + return null; + } + + CaptureRequest captureRequest = cameraMetadataWrapper.toCaptureRequest(); + List<CaptureRequest.Key> result = new ArrayList<>(); + for (CaptureRequest.Key<?> key : captureRequest.getKeys()) { + result.add(key); + } + return result; + } catch (RemoteException e) { + Log.e(TAG, "getAvailableCaptureRequestKeys failed", e); + throw new IllegalStateException("getAvailableCaptureRequestKeys failed", e); + } + } + + @Override + public List<CaptureResult.Key> getAvailableCaptureResultKeys() { + try { + CameraMetadataWrapper cameraMetadataWrapper + = mIImageCaptureExtender.getAvailableCaptureResultKeys(); + if (cameraMetadataWrapper == null) { + return null; + } + + TotalCaptureResult captureResult = cameraMetadataWrapper.toTotalCaptureResult(); + List<CaptureResult.Key> result = new ArrayList<>(); + for (CaptureResult.Key<?> key : captureResult.getKeys()) { + result.add(key); + } + return result; + } catch (RemoteException e) { + Log.e(TAG, "getAvailableCaptureResultKeys failed", e); + throw new IllegalStateException("getAvailableCaptureResultKeys failed", e); + } + } + + private static class CaptureProcessorImplAdapter implements CaptureProcessorImpl { + private ICaptureProcessorImpl mICaptureProcessor; + + private CaptureProcessorImplAdapter(ICaptureProcessorImpl iCaptureProcessor) { + mICaptureProcessor = iCaptureProcessor; + } + + @Override + public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results) { + process(results, null, null); + } + + @Override + public void process(Map<Integer, Pair<Image, TotalCaptureResult>> results, + ProcessResultImpl resultCallback, Executor executor) { + + try { + List<CaptureBundle> captureBundleList = new ArrayList<>(); + for (Integer captureStageId : results.keySet()) { + CaptureBundle bundle = new CaptureBundle(); + bundle.stageId = captureStageId; + Pair<Image, TotalCaptureResult> pair = results.get(captureStageId); + + bundle.captureResult = + new CameraMetadataWrapper(pair.second.getNativeMetadata()); + bundle.captureImage = new ImageWrapper(pair.first); + captureBundleList.add(bundle); + } + + IProcessResultImpl.Stub iProcessResultImpl = null; + if (resultCallback != null) { + iProcessResultImpl = new IProcessResultImpl.Stub() { + @Override + public void onCaptureCompleted(long shutterTimestamp, + CameraMetadataWrapper result) { + List<Pair<CaptureResult.Key, Object>> resultList = new ArrayList<>(); + TotalCaptureResult captureResult = result.toTotalCaptureResult(); + for (CaptureResult.Key<?> key : captureResult.getKeys()) { + resultList.add(new Pair(key, captureResult.get(key))); + } + if (executor == null) { + resultCallback.onCaptureCompleted(shutterTimestamp, + resultList); + } else { + executor.execute(() -> { + resultCallback.onCaptureCompleted(shutterTimestamp, + resultList); + }); + } + } + }; + } + mICaptureProcessor.process(captureBundleList, iProcessResultImpl); + } catch (RemoteException e) { + + } + } + + @Override + public void onOutputSurface(Surface surface, int imageFormat) { + try { + mICaptureProcessor.onOutputSurface(surface, imageFormat); + } catch (RemoteException e) { + Log.e(TAG, "CaptureProcessor onOutputSurface failed", e); + throw new IllegalStateException("CaptureProcessor onOutputSurface failed", e); + } + } + + @Override + public void onResolutionUpdate(Size size) { + try { + androidx.camera.extensions.impl.service.Size serviceSize + = new androidx.camera.extensions.impl.service.Size(); + serviceSize.width = size.getWidth(); + serviceSize.height = size.getHeight(); + mICaptureProcessor.onResolutionUpdate(serviceSize); + } catch (RemoteException e) { + Log.e(TAG, "CaptureProcessor onResolutionUpdate failed", e); + throw new IllegalStateException("CaptureProcessor onResolutionUpdate failed", e); + } + } + + @Override + public void onImageFormatUpdate(int imageFormat) { + try { + mICaptureProcessor.onImageFormatUpdate(imageFormat); + } catch (RemoteException e) { + Log.e(TAG, "CaptureProcessor imageFormat failed", e); + throw new IllegalStateException("CaptureProcessor imageFormat failed", e); + } + } + } +} diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ForwardPreviewExtender.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ForwardPreviewExtender.java new file mode 100644 index 00000000..81969ca4 --- /dev/null +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ForwardPreviewExtender.java @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2023 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.serviceforward; + +import android.content.Context; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CaptureResult; +import android.hardware.camera2.TotalCaptureResult; +import android.media.Image; +import android.os.RemoteException; +import android.util.Log; +import android.util.Pair; +import android.util.Size; +import android.view.Surface; + +import androidx.annotation.Nullable; +import androidx.camera.extensions.impl.CaptureStageImpl; +import androidx.camera.extensions.impl.PreviewExtenderImpl; +import androidx.camera.extensions.impl.PreviewImageProcessorImpl; +import androidx.camera.extensions.impl.ProcessResultImpl; +import androidx.camera.extensions.impl.ProcessorImpl; +import androidx.camera.extensions.impl.RequestUpdateProcessorImpl; +import androidx.camera.extensions.impl.service.CameraMetadataWrapper; +import androidx.camera.extensions.impl.service.CaptureStageImplWrapper; +import androidx.camera.extensions.impl.service.IPreviewExtenderImpl; +import androidx.camera.extensions.impl.service.IPreviewImageProcessorImpl; +import androidx.camera.extensions.impl.service.IProcessResultImpl; +import androidx.camera.extensions.impl.service.IRequestUpdateProcessorImpl; +import androidx.camera.extensions.impl.service.ImageWrapper; +import androidx.camera.extensions.impl.service.TotalCaptureResultWrapper; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executor; + +public class ForwardPreviewExtender implements PreviewExtenderImpl { + private static final String TAG = "ForwardPreviewExtender"; + + private final int mExtensionType; + private IPreviewExtenderImpl mIPreviewExtender; + + public ForwardPreviewExtender(int extensionType) { + mExtensionType = extensionType; + mIPreviewExtender = ServiceManager.getInstance().createPreviewExtenderImpl(extensionType); + } + + @Nullable + private static CaptureStageImpl convertToCaptureStageImpl( + @Nullable CaptureStageImplWrapper wrapper) { + if (wrapper == null) { + return null; + } + + return new CaptureStageImplAdapter(wrapper); + } + + @Override + public void onInit(String cameraId, CameraCharacteristics cameraCharacteristics, + Context context) { + try { + mIPreviewExtender.onInit(cameraId); + } catch (RemoteException e) { + Log.e(TAG, "onInit failed", e); + throw new IllegalStateException("onInit failed", e); + } + } + + @Override + public void onDeInit() { + try { + mIPreviewExtender.onDeInit(); + } catch (RemoteException e) { + Log.e(TAG, "onDeInit failed", e); + throw new IllegalStateException("onDeInit failed", e); + } + } + + @Override + public CaptureStageImpl onPresetSession() { + try { + return convertToCaptureStageImpl(mIPreviewExtender.onPresetSession()); + } catch (RemoteException e) { + Log.e(TAG, "onPresetSession failed", e); + throw new IllegalStateException("onDeInit failed", e); + } + } + + @Override + public CaptureStageImpl onEnableSession() { + try { + return convertToCaptureStageImpl(mIPreviewExtender.onEnableSession()); + } catch (RemoteException e) { + Log.e(TAG, "onEnableSession failed", e); + throw new IllegalStateException("onEnableSession failed", e); + } + } + + @Override + public CaptureStageImpl onDisableSession() { + try { + return convertToCaptureStageImpl(mIPreviewExtender.onDisableSession()); + } catch (RemoteException e) { + Log.e(TAG, "onDisableSession failed", e); + throw new IllegalStateException("onDisableSession failed", e); + } + } + + @Override + public boolean isExtensionAvailable(String cameraId, + CameraCharacteristics cameraCharacteristics) { + try { + return mIPreviewExtender.isExtensionAvailable(cameraId); + } catch (RemoteException e) { + Log.e(TAG, "isExtensionAvailable failed", e); + throw new IllegalStateException("isExtensionAvailable failed", e); + } + } + + @Override + public void init(String cameraId, CameraCharacteristics cameraCharacteristics) { + try { + mIPreviewExtender.init(cameraId); + } catch (RemoteException e) { + Log.e(TAG, "init failed", e); + throw new IllegalStateException("init failed", e); + } + } + + @Override + public CaptureStageImpl getCaptureStage() { + try { + return convertToCaptureStageImpl(mIPreviewExtender.getCaptureStage()); + } catch (RemoteException e) { + Log.e(TAG, "getCaptureStage failed", e); + throw new IllegalStateException("getCaptureStage failed", e); + } + } + + @Override + public ProcessorType getProcessorType() { + try { + switch (mIPreviewExtender.getProcessorType()) { + case IPreviewExtenderImpl.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY: + return ProcessorType.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY; + case IPreviewExtenderImpl.PROCESSOR_TYPE_IMAGE_PROCESSOR: + return ProcessorType.PROCESSOR_TYPE_IMAGE_PROCESSOR; + case IPreviewExtenderImpl.PROCESSOR_TYPE_NONE: + default: + return ProcessorType.PROCESSOR_TYPE_NONE; + } + } catch (RemoteException e) { + Log.e(TAG, "getProcessorType failed", e); + throw new IllegalStateException("getProcessorType failed", e); + } + } + + @Override + public ProcessorImpl getProcessor() { + try { + switch (getProcessorType()) { + case PROCESSOR_TYPE_REQUEST_UPDATE_ONLY: + return new RequestUpdateProcessorAdapter( + mIPreviewExtender.getRequestUpdateProcessor()); + case PROCESSOR_TYPE_IMAGE_PROCESSOR: + return new PreviewImageProcessorAdapter( + mIPreviewExtender.getPreviewImageProcessor()); + case PROCESSOR_TYPE_NONE: + default: + return null; + } + } catch (RemoteException e) { + Log.e(TAG, "getProcessorType failed", e); + throw new IllegalStateException("getProcessorType failed", e); + } + } + + @Nullable + @Override + public List<Pair<Integer, Size[]>> getSupportedResolutions() { + return null; + } + + private static class PreviewImageProcessorAdapter implements PreviewImageProcessorImpl { + + private final IPreviewImageProcessorImpl mIPreviewImageProcessor; + + private PreviewImageProcessorAdapter(IPreviewImageProcessorImpl iPreviewImageProcessor) { + mIPreviewImageProcessor = iPreviewImageProcessor; + } + + @Override + public void process(Image image, TotalCaptureResult result) { + try { + mIPreviewImageProcessor.process( + new ImageWrapper(image), new TotalCaptureResultWrapper(result), null); + } catch (RemoteException e) { + + } + } + + @Override + public void process(Image image, TotalCaptureResult result, + ProcessResultImpl resultCallback, @Nullable Executor executor) { + try { + + IProcessResultImpl.Stub iProcessResultImpl = null; + if (resultCallback != null) { + iProcessResultImpl = new IProcessResultImpl.Stub() { + @Override + public void onCaptureCompleted(long shutterTimestamp, + CameraMetadataWrapper result) { + List<Pair<CaptureResult.Key, Object>> resultList = new ArrayList<>(); + TotalCaptureResult captureResult = result.toTotalCaptureResult(); + for (CaptureResult.Key<?> key : captureResult.getKeys()) { + resultList.add(new Pair(key, captureResult.get(key))); + } + if (executor == null) { + resultCallback.onCaptureCompleted(shutterTimestamp, + resultList); + } else { + executor.execute(() -> { + resultCallback.onCaptureCompleted(shutterTimestamp, + resultList); + }); + } + } + }; + } + mIPreviewImageProcessor.process( + new ImageWrapper(image), new TotalCaptureResultWrapper(result), + iProcessResultImpl); + image.close(); + } catch (RemoteException e) { + + } + } + + @Override + public void onOutputSurface(Surface surface, int imageFormat) { + try { + mIPreviewImageProcessor.onOutputSurface(surface, imageFormat); + } catch (RemoteException e) { + Log.e(TAG, "PreviewImageProcessorAdapter onOutputSurface failed", e); + throw new IllegalStateException( + "PreviewImageProcessorAdapter onOutputSurface failed", e); + } + } + + @Override + public void onResolutionUpdate(Size size) { + try { + androidx.camera.extensions.impl.service.Size serviceSize = + new androidx.camera.extensions.impl.service.Size(); + serviceSize.width = size.getWidth(); + serviceSize.height = size.getHeight(); + mIPreviewImageProcessor.onResolutionUpdate(serviceSize); + } catch (RemoteException e) { + Log.e(TAG, "PreviewImageProcessorAdapter onResolutionUpdate", e); + throw new IllegalStateException( + "PreviewImageProcessorAdapter onResolutionUpdate failed", e); + } + } + + @Override + public void onImageFormatUpdate(int imageFormat) { + try { + mIPreviewImageProcessor.onImageFormatUpdate(imageFormat); + } catch (RemoteException e) { + Log.e(TAG, "PreviewImageProcessorAdapter onImageFormatUpdate failed", e); + throw new IllegalStateException( + "PreviewImageProcessorAdapter onImageFormatUpdate failed", e); + } + } + } + + private static class RequestUpdateProcessorAdapter + implements RequestUpdateProcessorImpl { + private IRequestUpdateProcessorImpl mIRequestUpdateProcessor; + + private RequestUpdateProcessorAdapter(IRequestUpdateProcessorImpl iRequestUpdateProcessor) { + mIRequestUpdateProcessor = iRequestUpdateProcessor; + } + + @Override + public void onOutputSurface(Surface surface, int imageFormat) { + } + + @Override + public void onResolutionUpdate(Size size) { + } + + @Override + public void onImageFormatUpdate(int imageFormat) { + } + + @Nullable + @Override + public CaptureStageImpl process(TotalCaptureResult result) { + try { + return convertToCaptureStageImpl( + mIRequestUpdateProcessor.process(new TotalCaptureResultWrapper(result))); + } catch (RemoteException e) { + Log.e(TAG, "RequestUpdateProcessorAdapter process failed", e); + throw new IllegalStateException("RequestUpdateProcessorAdapter process failed", e); + } + } + } +} diff --git a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ServiceManager.java b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ServiceManager.java index 7e27a7b6..b6e08b01 100644 --- a/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ServiceManager.java +++ b/camera2/extensions/service_based_sample/oem_library/src/java/androidx/camera/extensions/impl/serviceforward/ServiceManager.java @@ -29,6 +29,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.camera.extensions.impl.InitializerImpl; import androidx.camera.extensions.impl.service.IAdvancedExtenderImpl; +import androidx.camera.extensions.impl.service.IImageCaptureExtenderImpl; +import androidx.camera.extensions.impl.service.IPreviewExtenderImpl; import androidx.camera.extensions.impl.service.IExtensionsService; import androidx.camera.extensions.impl.service.IOnExtensionsDeinitializedCallback; import androidx.camera.extensions.impl.service.IOnExtensionsInitializedCallback; @@ -168,4 +170,34 @@ public class ServiceManager { throw new IllegalStateException("initializeAdvancedExtension failed", e); } } + + @NonNull + public IImageCaptureExtenderImpl createImageCaptureExtenderImpl(int extensionType) { + try { + synchronized (mLock) { + if (mExtensionService == null) { + bindServiceSync(mContext); + } + } + return mExtensionService.initializeImageCaptureExtension(extensionType); + } catch (RemoteException e) { + Log.e(TAG, "initializeImageCaptureExtender failed", e); + throw new IllegalStateException("initializeImageCaptureExtender failed", e); + } + } + + @NonNull + public IPreviewExtenderImpl createPreviewExtenderImpl(int extensionType) { + try { + synchronized (mLock) { + if (mExtensionService == null) { + bindServiceSync(mContext); + } + } + return mExtensionService.initializePreviewExtension(extensionType); + } catch (RemoteException e) { + Log.e(TAG, "initializePreviewExtension failed", e); + throw new IllegalStateException("initializePreviewExtension failed", e); + } + } } |