blob: c9add1c724421ada5a703bfe9b2c5ab7461a5fd2 [file] [log] [blame]
/*
* 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;
}
}