Merge "Camera: Add support for client requests&results when using extension sessions"
This commit is contained in:
committed by
Android (Google) Code Review
commit
86c843e8cd
@@ -17443,6 +17443,8 @@ package android.hardware.camera2 {
|
||||
}
|
||||
|
||||
public final class CameraExtensionCharacteristics {
|
||||
method @NonNull public java.util.Set<android.hardware.camera2.CaptureRequest.Key> getAvailableCaptureRequestKeys(int);
|
||||
method @NonNull public java.util.Set<android.hardware.camera2.CaptureResult.Key> getAvailableCaptureResultKeys(int);
|
||||
method @Nullable public android.util.Range<java.lang.Long> getEstimatedCaptureLatencyRangeMillis(int, @NonNull android.util.Size, int);
|
||||
method @NonNull public <T> java.util.List<android.util.Size> getExtensionSupportedSizes(int, @NonNull Class<T>);
|
||||
method @NonNull public java.util.List<android.util.Size> getExtensionSupportedSizes(int, int);
|
||||
@@ -17467,6 +17469,7 @@ package android.hardware.camera2 {
|
||||
ctor public CameraExtensionSession.ExtensionCaptureCallback();
|
||||
method public void onCaptureFailed(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest);
|
||||
method public void onCaptureProcessStarted(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest);
|
||||
method public void onCaptureResultAvailable(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest, @NonNull android.hardware.camera2.TotalCaptureResult);
|
||||
method public void onCaptureSequenceAborted(@NonNull android.hardware.camera2.CameraExtensionSession, int);
|
||||
method public void onCaptureSequenceCompleted(@NonNull android.hardware.camera2.CameraExtensionSession, int);
|
||||
method public void onCaptureStarted(@NonNull android.hardware.camera2.CameraExtensionSession, @NonNull android.hardware.camera2.CaptureRequest, long);
|
||||
|
||||
@@ -657,7 +657,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
|
||||
*
|
||||
* @throws IllegalArgumentException if metadataClass is not a subclass of CameraMetadata
|
||||
*/
|
||||
private <TKey> List<TKey>
|
||||
<TKey> List<TKey>
|
||||
getAvailableKeyList(Class<?> metadataClass, Class<TKey> keyClass, int[] filterTags,
|
||||
boolean includeSynthetic) {
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.hardware.camera2.extension.IInitializeSessionCallback;
|
||||
import android.hardware.camera2.extension.IPreviewExtenderImpl;
|
||||
import android.hardware.camera2.extension.LatencyRange;
|
||||
import android.hardware.camera2.extension.SizeList;
|
||||
import android.hardware.camera2.impl.CameraMetadataNative;
|
||||
import android.hardware.camera2.params.ExtensionSessionConfiguration;
|
||||
import android.hardware.camera2.params.StreamConfigurationMap;
|
||||
import android.os.ConditionVariable;
|
||||
@@ -49,6 +50,7 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@@ -785,8 +787,8 @@ public final class CameraExtensionCharacteristics {
|
||||
if (latencyRange != null) {
|
||||
return new Range(latencyRange.min, latencyRange.max);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to query the extension capture latency! Extension service does"
|
||||
+ " not respond!");
|
||||
} finally {
|
||||
@@ -795,4 +797,142 @@ public final class CameraExtensionCharacteristics {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of keys supported by a {@link CaptureRequest} submitted in a
|
||||
* {@link CameraExtensionSession} with a given extension type.
|
||||
*
|
||||
* <p>The set returned is not modifiable, so any attempts to modify it will throw
|
||||
* a {@code UnsupportedOperationException}.</p>
|
||||
*
|
||||
* @param extension the extension type
|
||||
*
|
||||
* @return non-modifiable set of capture keys supported by camera extension session initialized
|
||||
* with the given extension type.
|
||||
* @throws IllegalArgumentException in case of unsupported extension.
|
||||
*/
|
||||
@NonNull
|
||||
public Set<CaptureRequest.Key> getAvailableCaptureRequestKeys(@Extension int extension) {
|
||||
long clientId = registerClient(mContext);
|
||||
if (clientId < 0) {
|
||||
throw new IllegalArgumentException("Unsupported extensions");
|
||||
}
|
||||
|
||||
HashSet<CaptureRequest.Key> ret = new HashSet<>();
|
||||
|
||||
try {
|
||||
if (!isExtensionSupported(mCameraId, extension, mChars)) {
|
||||
throw new IllegalArgumentException("Unsupported extension");
|
||||
}
|
||||
Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
|
||||
initializeExtension(extension);
|
||||
extenders.second.onInit(mCameraId, mChars.getNativeMetadata());
|
||||
extenders.second.init(mCameraId, mChars.getNativeMetadata());
|
||||
CameraMetadataNative captureRequestMeta =
|
||||
extenders.second.getAvailableCaptureRequestKeys();
|
||||
|
||||
if (captureRequestMeta != null) {
|
||||
int[] requestKeys = captureRequestMeta.get(
|
||||
CameraCharacteristics.REQUEST_AVAILABLE_REQUEST_KEYS);
|
||||
if (requestKeys == null) {
|
||||
throw new AssertionError("android.request.availableRequestKeys must be non-null"
|
||||
+ " in the characteristics");
|
||||
}
|
||||
CameraCharacteristics requestChars = new CameraCharacteristics(captureRequestMeta);
|
||||
|
||||
Object crKey = CaptureRequest.Key.class;
|
||||
Class<CaptureRequest.Key<?>> crKeyTyped = (Class<CaptureRequest.Key<?>>)crKey;
|
||||
|
||||
ret.addAll(requestChars.getAvailableKeyList(CaptureRequest.class, crKeyTyped,
|
||||
requestKeys, /*includeSynthetic*/ false));
|
||||
}
|
||||
|
||||
// Jpeg quality and orientation must always be supported
|
||||
if (!ret.contains(CaptureRequest.JPEG_QUALITY)) {
|
||||
ret.add(CaptureRequest.JPEG_QUALITY);
|
||||
}
|
||||
if (!ret.contains(CaptureRequest.JPEG_ORIENTATION)) {
|
||||
ret.add(CaptureRequest.JPEG_ORIENTATION);
|
||||
}
|
||||
extenders.second.onDeInit();
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException("Failed to query the available capture request keys!");
|
||||
} finally {
|
||||
unregisterClient(clientId);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableSet(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of keys supported by a {@link CaptureResult} passed as an argument to
|
||||
* {@link CameraExtensionSession.ExtensionCaptureCallback#onCaptureResultAvailable}.
|
||||
*
|
||||
* <p>The set returned is not modifiable, so any attempts to modify it will throw
|
||||
* a {@code UnsupportedOperationException}.</p>
|
||||
*
|
||||
* <p>In case the set is empty, then the extension is not able to support any capture results
|
||||
* and the {@link CameraExtensionSession.ExtensionCaptureCallback#onCaptureResultAvailable}
|
||||
* callback will not be fired.</p>
|
||||
*
|
||||
* @param extension the extension type
|
||||
*
|
||||
* @return non-modifiable set of capture result keys supported by camera extension session
|
||||
* initialized with the given extension type.
|
||||
* @throws IllegalArgumentException in case of unsupported extension.
|
||||
*/
|
||||
@NonNull
|
||||
public Set<CaptureResult.Key> getAvailableCaptureResultKeys(@Extension int extension) {
|
||||
long clientId = registerClient(mContext);
|
||||
if (clientId < 0) {
|
||||
throw new IllegalArgumentException("Unsupported extensions");
|
||||
}
|
||||
|
||||
HashSet<CaptureResult.Key> ret = new HashSet<>();
|
||||
try {
|
||||
if (!isExtensionSupported(mCameraId, extension, mChars)) {
|
||||
throw new IllegalArgumentException("Unsupported extension");
|
||||
}
|
||||
|
||||
Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
|
||||
initializeExtension(extension);
|
||||
extenders.second.onInit(mCameraId, mChars.getNativeMetadata());
|
||||
extenders.second.init(mCameraId, mChars.getNativeMetadata());
|
||||
CameraMetadataNative captureResultMeta =
|
||||
extenders.second.getAvailableCaptureResultKeys();
|
||||
|
||||
if (captureResultMeta != null) {
|
||||
int[] resultKeys = captureResultMeta.get(
|
||||
CameraCharacteristics.REQUEST_AVAILABLE_RESULT_KEYS);
|
||||
if (resultKeys == null) {
|
||||
throw new AssertionError("android.request.availableResultKeys must be non-null "
|
||||
+ "in the characteristics");
|
||||
}
|
||||
CameraCharacteristics resultChars = new CameraCharacteristics(captureResultMeta);
|
||||
Object crKey = CaptureResult.Key.class;
|
||||
Class<CaptureResult.Key<?>> crKeyTyped = (Class<CaptureResult.Key<?>>)crKey;
|
||||
|
||||
ret.addAll(resultChars.getAvailableKeyList(CaptureResult.class, crKeyTyped,
|
||||
resultKeys, /*includeSynthetic*/ false));
|
||||
|
||||
// Jpeg quality, orientation and sensor timestamp must always be supported
|
||||
if (!ret.contains(CaptureResult.JPEG_QUALITY)) {
|
||||
ret.add(CaptureResult.JPEG_QUALITY);
|
||||
}
|
||||
if (!ret.contains(CaptureResult.JPEG_ORIENTATION)) {
|
||||
ret.add(CaptureResult.JPEG_ORIENTATION);
|
||||
}
|
||||
if (!ret.contains(CaptureResult.SENSOR_TIMESTAMP)) {
|
||||
ret.add(CaptureResult.SENSOR_TIMESTAMP);
|
||||
}
|
||||
}
|
||||
extenders.second.onDeInit();
|
||||
} catch (RemoteException e) {
|
||||
throw new IllegalStateException("Failed to query the available capture result keys!");
|
||||
} finally {
|
||||
unregisterClient(clientId);
|
||||
}
|
||||
|
||||
return Collections.unmodifiableSet(ret);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +172,32 @@ public abstract class CameraExtensionSession implements AutoCloseable {
|
||||
int sequenceId) {
|
||||
// default empty implementation
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when an image capture has fully completed and all the
|
||||
* result metadata is available.
|
||||
*
|
||||
* <p>This callback will only be called in case
|
||||
* {@link CameraExtensionCharacteristics#getAvailableCaptureResultKeys} returns a valid
|
||||
* non-empty list.</p>
|
||||
*
|
||||
* <p>The default implementation of this method does nothing.</p>
|
||||
*
|
||||
* @param session The session received during
|
||||
* {@link StateCallback#onConfigured(CameraExtensionSession)}
|
||||
* @param request The request that was given to the CameraDevice
|
||||
* @param result The total output metadata from the capture, which only includes the
|
||||
* capture result keys advertised as supported in
|
||||
* {@link CameraExtensionCharacteristics#getAvailableCaptureResultKeys}.
|
||||
*
|
||||
* @see #capture
|
||||
* @see #setRepeatingRequest
|
||||
* @see CameraExtensionCharacteristics#getAvailableCaptureResultKeys
|
||||
*/
|
||||
public void onCaptureResultAvailable(@NonNull CameraExtensionSession session,
|
||||
@NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
|
||||
// default empty implementation
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ package android.hardware.camera2.extension;
|
||||
|
||||
import android.view.Surface;
|
||||
import android.hardware.camera2.extension.CaptureBundle;
|
||||
import android.hardware.camera2.extension.IProcessResultImpl;
|
||||
import android.hardware.camera2.extension.Size;
|
||||
|
||||
/** @hide */
|
||||
@@ -25,5 +26,5 @@ interface ICaptureProcessorImpl
|
||||
void onOutputSurface(in Surface surface, int imageFormat);
|
||||
void onResolutionUpdate(in Size size);
|
||||
void onImageFormatUpdate(int imageFormat);
|
||||
void process(in List<CaptureBundle> capturelist);
|
||||
void process(in List<CaptureBundle> capturelist, in IProcessResultImpl resultCallback);
|
||||
}
|
||||
|
||||
@@ -39,4 +39,6 @@ interface IImageCaptureExtenderImpl
|
||||
int getMaxCaptureStage();
|
||||
@nullable List<SizeList> getSupportedResolutions();
|
||||
LatencyRange getEstimatedCaptureLatencyRange(in Size outputSize);
|
||||
CameraMetadataNative getAvailableCaptureRequestKeys();
|
||||
CameraMetadataNative getAvailableCaptureResultKeys();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package android.hardware.camera2.extension;
|
||||
|
||||
import android.hardware.camera2.impl.CameraMetadataNative;
|
||||
import android.view.Surface;
|
||||
import android.hardware.camera2.extension.IProcessResultImpl;
|
||||
import android.hardware.camera2.extension.ParcelImage;
|
||||
import android.hardware.camera2.extension.Size;
|
||||
|
||||
@@ -26,5 +27,6 @@ interface IPreviewImageProcessorImpl
|
||||
void onOutputSurface(in Surface surface, int imageFormat);
|
||||
void onResolutionUpdate(in Size size);
|
||||
void onImageFormatUpdate(int imageFormat);
|
||||
void process(in ParcelImage image, in CameraMetadataNative result, int sequenceId);
|
||||
void process(in ParcelImage image, in CameraMetadataNative result, int sequenceId,
|
||||
in IProcessResultImpl resultCallback);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2022, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.hardware.camera2.extension;
|
||||
|
||||
import android.hardware.camera2.impl.CameraMetadataNative;
|
||||
|
||||
/** @hide */
|
||||
interface IProcessResultImpl
|
||||
{
|
||||
void onCaptureCompleted(long shutterTimestamp, in CameraMetadataNative results);
|
||||
}
|
||||
@@ -105,7 +105,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
|
||||
@RequiresPermission(android.Manifest.permission.CAMERA)
|
||||
public static CameraAdvancedExtensionSessionImpl createCameraAdvancedExtensionSession(
|
||||
@NonNull CameraDevice cameraDevice, @NonNull Context ctx,
|
||||
@NonNull ExtensionSessionConfiguration config)
|
||||
@NonNull ExtensionSessionConfiguration config, int sessionId)
|
||||
throws CameraAccessException, RemoteException {
|
||||
long clientId = CameraExtensionCharacteristics.registerClient(ctx);
|
||||
if (clientId < 0) {
|
||||
|
||||
@@ -2495,10 +2495,10 @@ public class CameraDeviceImpl extends CameraDevice
|
||||
if (CameraExtensionCharacteristics.areAdvancedExtensionsSupported()) {
|
||||
mCurrentAdvancedExtensionSession =
|
||||
CameraAdvancedExtensionSessionImpl.createCameraAdvancedExtensionSession(
|
||||
this, mContext, extensionConfiguration);
|
||||
this, mContext, extensionConfiguration, mNextSessionId++);
|
||||
} else {
|
||||
mCurrentExtensionSession = CameraExtensionSessionImpl.createCameraExtensionSession(
|
||||
this, mContext, extensionConfiguration);
|
||||
this, mContext, extensionConfiguration, mNextSessionId++);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new CameraAccessException(CameraAccessException.CAMERA_ERROR);
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.hardware.camera2.impl;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.hardware.camera2.CameraExtensionCharacteristics;
|
||||
import android.hardware.camera2.extension.IPreviewImageProcessorImpl;
|
||||
import android.hardware.camera2.extension.IProcessResultImpl;
|
||||
import android.hardware.camera2.extension.ParcelImage;
|
||||
import android.hardware.camera2.TotalCaptureResult;
|
||||
import android.media.Image;
|
||||
@@ -114,12 +115,12 @@ public class CameraExtensionForwardProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
public void process(ParcelImage image, TotalCaptureResult totalCaptureResult)
|
||||
throws RemoteException {
|
||||
public void process(ParcelImage image, TotalCaptureResult totalCaptureResult,
|
||||
IProcessResultImpl resultCallback) throws RemoteException {
|
||||
if ((mIntermediateSurface != null) && (mIntermediateSurface.isValid()) &&
|
||||
!mOutputAbandoned) {
|
||||
mProcessor.process(image, totalCaptureResult.getNativeMetadata(),
|
||||
totalCaptureResult.getSequenceId());
|
||||
totalCaptureResult.getSequenceId(), resultCallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.graphics.ImageFormat;
|
||||
import android.hardware.camera2.CaptureResult;
|
||||
import android.hardware.camera2.extension.CaptureBundle;
|
||||
import android.hardware.camera2.extension.ICaptureProcessorImpl;
|
||||
import android.hardware.camera2.extension.IProcessResultImpl;
|
||||
import android.media.Image;
|
||||
import android.media.Image.Plane;
|
||||
import android.media.ImageReader;
|
||||
@@ -183,11 +184,13 @@ public class CameraExtensionJpegProcessor implements ICaptureProcessorImpl {
|
||||
int cropLeft, int cropTop, int cropRight, int cropBottom,
|
||||
int rot90);
|
||||
|
||||
public void process(List<CaptureBundle> captureBundle) throws RemoteException {
|
||||
@Override
|
||||
public void process(List<CaptureBundle> captureBundle, IProcessResultImpl captureCallback)
|
||||
throws RemoteException {
|
||||
JpegParameters jpegParams = getJpegParameters(captureBundle);
|
||||
try {
|
||||
mJpegParameters.add(jpegParams);
|
||||
mProcessor.process(captureBundle);
|
||||
mProcessor.process(captureBundle, captureCallback);
|
||||
} catch (Exception e) {
|
||||
mJpegParameters.remove(jpegParams);
|
||||
throw e;
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.hardware.camera2.extension.ICaptureProcessorImpl;
|
||||
import android.hardware.camera2.extension.IImageCaptureExtenderImpl;
|
||||
import android.hardware.camera2.extension.IInitializeSessionCallback;
|
||||
import android.hardware.camera2.extension.IPreviewExtenderImpl;
|
||||
import android.hardware.camera2.extension.IProcessResultImpl;
|
||||
import android.hardware.camera2.extension.IRequestUpdateProcessorImpl;
|
||||
import android.hardware.camera2.extension.ParcelImage;
|
||||
import android.hardware.camera2.TotalCaptureResult;
|
||||
@@ -67,6 +68,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
@@ -83,6 +85,10 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
private final StateCallback mCallbacks;
|
||||
private final List<Size> mSupportedPreviewSizes;
|
||||
private final InitializeSessionHandler mInitializeHandler;
|
||||
private final int mSessionId;
|
||||
private final Set<CaptureRequest.Key> mSupportedRequestKeys;
|
||||
private final Set<CaptureResult.Key> mSupportedResultKeys;
|
||||
private boolean mCaptureResultsSupported;
|
||||
|
||||
private CameraCaptureSession mCaptureSession = null;
|
||||
private Surface mCameraRepeatingSurface, mClientRepeatingRequestSurface;
|
||||
@@ -121,7 +127,8 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
public static CameraExtensionSessionImpl createCameraExtensionSession(
|
||||
@NonNull CameraDevice cameraDevice,
|
||||
@NonNull Context ctx,
|
||||
@NonNull ExtensionSessionConfiguration config)
|
||||
@NonNull ExtensionSessionConfiguration config,
|
||||
int sessionId)
|
||||
throws CameraAccessException, RemoteException {
|
||||
long clientId = CameraExtensionCharacteristics.registerClient(ctx);
|
||||
if (clientId < 0) {
|
||||
@@ -202,7 +209,10 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
repeatingRequestSurface,
|
||||
burstCaptureSurface,
|
||||
config.getStateCallback(),
|
||||
config.getExecutor());
|
||||
config.getExecutor(),
|
||||
sessionId,
|
||||
extensionChars.getAvailableCaptureRequestKeys(config.getExtension()),
|
||||
extensionChars.getAvailableCaptureResultKeys(config.getExtension()));
|
||||
|
||||
session.initialize();
|
||||
|
||||
@@ -217,7 +227,10 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
@Nullable Surface repeatingRequestSurface,
|
||||
@Nullable Surface burstCaptureSurface,
|
||||
@NonNull StateCallback callback,
|
||||
@NonNull Executor executor) {
|
||||
@NonNull Executor executor,
|
||||
int sessionId,
|
||||
@NonNull Set<CaptureRequest.Key> requestKeys,
|
||||
@Nullable Set<CaptureResult.Key> resultKeys) {
|
||||
mExtensionClientId = extensionClientId;
|
||||
mImageExtender = imageExtender;
|
||||
mPreviewExtender = previewExtender;
|
||||
@@ -232,6 +245,10 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
mHandler = new Handler(mHandlerThread.getLooper());
|
||||
mInitialized = false;
|
||||
mInitializeHandler = new InitializeSessionHandler();
|
||||
mSessionId = sessionId;
|
||||
mSupportedRequestKeys = requestKeys;
|
||||
mSupportedResultKeys = resultKeys;
|
||||
mCaptureResultsSupported = !resultKeys.isEmpty();
|
||||
}
|
||||
|
||||
private void initializeRepeatingRequestPipeline() throws RemoteException {
|
||||
@@ -488,7 +505,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
return captureStageList;
|
||||
}
|
||||
|
||||
private static List<CaptureRequest> createBurstRequest(CameraDevice cameraDevice,
|
||||
private List<CaptureRequest> createBurstRequest(CameraDevice cameraDevice,
|
||||
List<CaptureStageImpl> captureStageList, CaptureRequest clientRequest,
|
||||
Surface target, int captureTemplate, Map<CaptureRequest, Integer> captureMap) {
|
||||
CaptureRequest.Builder requestBuilder;
|
||||
@@ -500,16 +517,13 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
return null;
|
||||
}
|
||||
|
||||
// This will override the extension capture stage jpeg parameters with the user set
|
||||
// jpeg quality and rotation. This will guarantee that client configured jpeg
|
||||
// parameters always have highest priority.
|
||||
Integer jpegRotation = clientRequest.get(CaptureRequest.JPEG_ORIENTATION);
|
||||
if (jpegRotation != null) {
|
||||
captureStage.parameters.set(CaptureRequest.JPEG_ORIENTATION, jpegRotation);
|
||||
}
|
||||
Byte jpegQuality = clientRequest.get(CaptureRequest.JPEG_QUALITY);
|
||||
if (jpegQuality != null) {
|
||||
captureStage.parameters.set(CaptureRequest.JPEG_QUALITY, jpegQuality);
|
||||
// This will guarantee that client configured
|
||||
// parameters always have the highest priority.
|
||||
for (CaptureRequest.Key requestKey : mSupportedRequestKeys){
|
||||
Object value = clientRequest.get(requestKey);
|
||||
if (value != null) {
|
||||
captureStage.parameters.set(requestKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
requestBuilder.addTarget(target);
|
||||
@@ -522,10 +536,9 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static CaptureRequest createRequest(CameraDevice cameraDevice,
|
||||
List<CaptureStageImpl> captureStageList,
|
||||
Surface target,
|
||||
int captureTemplate) throws CameraAccessException {
|
||||
private CaptureRequest createRequest(CameraDevice cameraDevice,
|
||||
List<CaptureStageImpl> captureStageList, Surface target, int captureTemplate,
|
||||
CaptureRequest clientRequest) throws CameraAccessException {
|
||||
CaptureRequest.Builder requestBuilder;
|
||||
requestBuilder = cameraDevice.createCaptureRequest(captureTemplate);
|
||||
if (target != null) {
|
||||
@@ -533,14 +546,35 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
}
|
||||
|
||||
CaptureRequest ret = requestBuilder.build();
|
||||
CameraMetadataNative nativeMeta = ret.getNativeMetadata();
|
||||
for (CaptureStageImpl captureStage : captureStageList) {
|
||||
if (captureStage != null) {
|
||||
CameraMetadataNative.update(ret.getNativeMetadata(), captureStage.parameters);
|
||||
CameraMetadataNative.update(nativeMeta, captureStage.parameters);
|
||||
}
|
||||
}
|
||||
|
||||
if (clientRequest != null) {
|
||||
// This will guarantee that client configured
|
||||
// parameters always have the highest priority.
|
||||
for (CaptureRequest.Key requestKey : mSupportedRequestKeys) {
|
||||
Object value = clientRequest.get(requestKey);
|
||||
if (value != null) {
|
||||
nativeMeta.set(requestKey, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private CaptureRequest createRequest(CameraDevice cameraDevice,
|
||||
List<CaptureStageImpl> captureStageList,
|
||||
Surface target,
|
||||
int captureTemplate) throws CameraAccessException {
|
||||
return createRequest(cameraDevice, captureStageList, target, captureTemplate,
|
||||
/*clientRequest*/ null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int capture(@NonNull CaptureRequest request,
|
||||
@NonNull Executor executor,
|
||||
@@ -634,12 +668,17 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
}
|
||||
|
||||
private int setRepeatingRequest(CaptureStageImpl captureStage,
|
||||
CameraCaptureSession.CaptureCallback requestHandler)
|
||||
CameraCaptureSession.CaptureCallback requestHandler) throws CameraAccessException {
|
||||
return setRepeatingRequest(captureStage, requestHandler, /*clientRequest*/ null);
|
||||
}
|
||||
|
||||
private int setRepeatingRequest(CaptureStageImpl captureStage,
|
||||
CameraCaptureSession.CaptureCallback requestHandler, CaptureRequest clientRequest)
|
||||
throws CameraAccessException {
|
||||
ArrayList<CaptureStageImpl> captureStageList = new ArrayList<>();
|
||||
captureStageList.add(captureStage);
|
||||
CaptureRequest repeatingRequest = createRequest(mCameraDevice,
|
||||
captureStageList, mCameraRepeatingSurface, CameraDevice.TEMPLATE_PREVIEW);
|
||||
CaptureRequest repeatingRequest = createRequest(mCameraDevice, captureStageList,
|
||||
mCameraRepeatingSurface, CameraDevice.TEMPLATE_PREVIEW, clientRequest);
|
||||
return mCaptureSession.setSingleRepeatingRequest(repeatingRequest,
|
||||
new CameraExtensionUtils.HandlerExecutor(mHandler), requestHandler);
|
||||
}
|
||||
@@ -848,6 +887,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
|
||||
private ImageCallback mImageCallback = null;
|
||||
private boolean mCaptureFailed = false;
|
||||
private CaptureResultHandler mCaptureResultHandler = null;
|
||||
|
||||
public BurstRequestHandler(@NonNull CaptureRequest request, @NonNull Executor executor,
|
||||
@NonNull ExtensionCaptureCallback callbacks,
|
||||
@@ -968,20 +1008,18 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
|
||||
Long timestamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
|
||||
if (timestamp != null) {
|
||||
if (mCaptureResultsSupported && (mCaptureResultHandler == null)) {
|
||||
mCaptureResultHandler = new CaptureResultHandler(mClientRequest, mExecutor,
|
||||
mCallbacks, result.getSessionId());
|
||||
}
|
||||
if (mImageProcessor != null) {
|
||||
if (mCapturePendingMap.indexOfKey(timestamp) >= 0) {
|
||||
Image img = mCapturePendingMap.get(timestamp).first;
|
||||
mCaptureStageMap.put(stageId,
|
||||
new Pair<>(img,
|
||||
result));
|
||||
mCaptureStageMap.put(stageId, new Pair<>(img, result));
|
||||
checkAndFireBurstProcessing();
|
||||
} else {
|
||||
mCapturePendingMap.put(timestamp,
|
||||
new Pair<>(null,
|
||||
stageId));
|
||||
mCaptureStageMap.put(stageId,
|
||||
new Pair<>(null,
|
||||
result));
|
||||
mCapturePendingMap.put(timestamp, new Pair<>(null, stageId));
|
||||
mCaptureStageMap.put(stageId, new Pair<>(null, result));
|
||||
}
|
||||
} else {
|
||||
mCaptureRequestMap.clear();
|
||||
@@ -991,6 +1029,18 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
() -> mCallbacks
|
||||
.onCaptureProcessStarted(CameraExtensionSessionImpl.this,
|
||||
mClientRequest));
|
||||
|
||||
if (mCaptureResultHandler != null) {
|
||||
CameraMetadataNative captureResults = new CameraMetadataNative();
|
||||
for (CaptureResult.Key key : mSupportedResultKeys) {
|
||||
Object value = result.get(key);
|
||||
if (value != null) {
|
||||
captureResults.set(key, value);
|
||||
}
|
||||
}
|
||||
mCaptureResultHandler.onCaptureCompleted(timestamp,
|
||||
captureResults);
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
@@ -1018,7 +1068,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
List<CaptureBundle> captureList = initializeParcelable(mCaptureStageMap,
|
||||
jpegOrientation, jpegQuality);
|
||||
try {
|
||||
mImageProcessor.process(captureList);
|
||||
mImageProcessor.process(captureList, mCaptureResultHandler);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to process multi-frame request! Extension service "
|
||||
+ "does not respond!");
|
||||
@@ -1233,6 +1283,43 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
}
|
||||
}
|
||||
|
||||
private class CaptureResultHandler extends IProcessResultImpl.Stub {
|
||||
private final Executor mExecutor;
|
||||
private final ExtensionCaptureCallback mCallbacks;
|
||||
private final CaptureRequest mClientRequest;
|
||||
private final int mRequestId;
|
||||
|
||||
public CaptureResultHandler(@NonNull CaptureRequest clientRequest,
|
||||
@NonNull Executor executor, @NonNull ExtensionCaptureCallback listener,
|
||||
int requestId) {
|
||||
mClientRequest = clientRequest;
|
||||
mExecutor = executor;
|
||||
mCallbacks = listener;
|
||||
mRequestId = requestId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCaptureCompleted(long shutterTimestamp, CameraMetadataNative result) {
|
||||
if (result == null) {
|
||||
Log.e(TAG,"Invalid capture result!");
|
||||
return;
|
||||
}
|
||||
|
||||
result.set(CaptureResult.SENSOR_TIMESTAMP, shutterTimestamp);
|
||||
TotalCaptureResult totalResult = new TotalCaptureResult(mCameraDevice.getId(), result,
|
||||
mClientRequest, mRequestId, shutterTimestamp, new ArrayList<CaptureResult>(),
|
||||
mSessionId, new PhysicalCaptureResultInfo[0]);
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mExecutor.execute(
|
||||
() -> mCallbacks.onCaptureResultAvailable(CameraExtensionSessionImpl.this,
|
||||
mClientRequest, totalResult));
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This handler can operate in two modes:
|
||||
// 1) Using valid client callbacks, which means camera buffers will be propagated the
|
||||
// registered output surfaces and clients will be notified accordingly.
|
||||
@@ -1247,6 +1334,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
private OnImageAvailableListener mImageCallback = null;
|
||||
private LongSparseArray<Pair<Image, TotalCaptureResult>> mPendingResultMap =
|
||||
new LongSparseArray<>();
|
||||
private CaptureResultHandler mCaptureResultHandler = null;
|
||||
|
||||
private boolean mRequestUpdatedNeeded = false;
|
||||
|
||||
@@ -1380,6 +1468,11 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
synchronized (mInterfaceLock) {
|
||||
final Long timestamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
|
||||
if (timestamp != null) {
|
||||
if (mCaptureResultsSupported && mClientNotificationsEnabled &&
|
||||
(mCaptureResultHandler == null)) {
|
||||
mCaptureResultHandler = new CaptureResultHandler(mClientRequest, mExecutor,
|
||||
mCallbacks, result.getSessionId());
|
||||
}
|
||||
if (mPreviewProcessorType ==
|
||||
IPreviewExtenderImpl.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY) {
|
||||
CaptureStageImpl captureStage = null;
|
||||
@@ -1392,7 +1485,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
}
|
||||
if (captureStage != null) {
|
||||
try {
|
||||
setRepeatingRequest(captureStage, this);
|
||||
setRepeatingRequest(captureStage, this, request);
|
||||
mRequestUpdatedNeeded = true;
|
||||
} catch (IllegalStateException e) {
|
||||
// This is possible in case the camera device closes and the
|
||||
@@ -1411,7 +1504,8 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
ParcelImage parcelImage = initializeParcelImage(
|
||||
mPendingResultMap.get(timestamp).first);
|
||||
try {
|
||||
mPreviewImageProcessor.process(parcelImage, result);
|
||||
mPreviewImageProcessor.process(parcelImage, result,
|
||||
mCaptureResultHandler);
|
||||
} catch (RemoteException e) {
|
||||
processStatus = false;
|
||||
Log.e(TAG, "Extension service does not respond during " +
|
||||
@@ -1449,6 +1543,19 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
.onCaptureProcessStarted(
|
||||
CameraExtensionSessionImpl.this,
|
||||
mClientRequest));
|
||||
if ((mCaptureResultHandler != null) && (mPreviewProcessorType !=
|
||||
IPreviewExtenderImpl.PROCESSOR_TYPE_IMAGE_PROCESSOR)) {
|
||||
CameraMetadataNative captureResults =
|
||||
new CameraMetadataNative();
|
||||
for (CaptureResult.Key key : mSupportedResultKeys) {
|
||||
Object value = result.get(key);
|
||||
if (value != null) {
|
||||
captureResults.set(key, value);
|
||||
}
|
||||
}
|
||||
mCaptureResultHandler.onCaptureCompleted(timestamp,
|
||||
captureResults);
|
||||
}
|
||||
} else {
|
||||
mExecutor.execute(
|
||||
() -> mCallbacks
|
||||
@@ -1592,7 +1699,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
|
||||
ParcelImage parcelImage = initializeParcelImage(img);
|
||||
try {
|
||||
mPreviewImageProcessor.process(parcelImage,
|
||||
mPendingResultMap.get(timestamp).second);
|
||||
mPendingResultMap.get(timestamp).second, mCaptureResultHandler);
|
||||
} catch (RemoteException e) {
|
||||
processStatus = false;
|
||||
Log.e(TAG, "Extension service does not respond during " +
|
||||
|
||||
@@ -43,6 +43,7 @@ import android.hardware.camera2.extension.IImageProcessorImpl;
|
||||
import android.hardware.camera2.extension.IInitializeSessionCallback;
|
||||
import android.hardware.camera2.extension.IPreviewExtenderImpl;
|
||||
import android.hardware.camera2.extension.IPreviewImageProcessorImpl;
|
||||
import android.hardware.camera2.extension.IProcessResultImpl;
|
||||
import android.hardware.camera2.extension.IRequestCallback;
|
||||
import android.hardware.camera2.extension.IRequestProcessorImpl;
|
||||
import android.hardware.camera2.extension.IRequestUpdateProcessorImpl;
|
||||
@@ -90,6 +91,7 @@ import androidx.camera.extensions.impl.NightPreviewExtenderImpl;
|
||||
import androidx.camera.extensions.impl.PreviewExtenderImpl;
|
||||
import androidx.camera.extensions.impl.PreviewExtenderImpl.ProcessorType;
|
||||
import androidx.camera.extensions.impl.PreviewImageProcessorImpl;
|
||||
import androidx.camera.extensions.impl.ProcessResultImpl;
|
||||
import androidx.camera.extensions.impl.RequestUpdateProcessorImpl;
|
||||
import androidx.camera.extensions.impl.advanced.AdvancedExtenderImpl;
|
||||
import androidx.camera.extensions.impl.advanced.AutoAdvancedExtenderImpl;
|
||||
@@ -124,14 +126,17 @@ public class CameraExtensionsProxyService extends Service {
|
||||
private static final String LATEST_VERSION = "1.2.0";
|
||||
private static final String NON_INIT_VERSION_PREFIX = "1.0";
|
||||
private static final String ADVANCED_VERSION_PREFIX = "1.2";
|
||||
private static final String[] SUPPORTED_VERSION_PREFIXES = {ADVANCED_VERSION_PREFIX,
|
||||
"1.1", NON_INIT_VERSION_PREFIX};
|
||||
private static final String RESULTS_VERSION_PREFIX = "1.3";
|
||||
private static final String[] SUPPORTED_VERSION_PREFIXES = {RESULTS_VERSION_PREFIX,
|
||||
ADVANCED_VERSION_PREFIX, "1.1", NON_INIT_VERSION_PREFIX};
|
||||
private static final boolean EXTENSIONS_PRESENT = checkForExtensions();
|
||||
private static final String EXTENSIONS_VERSION = EXTENSIONS_PRESENT ?
|
||||
(new ExtensionVersionImpl()).checkApiVersion(LATEST_VERSION) : null;
|
||||
private static final boolean ADVANCED_API_SUPPORTED = checkForAdvancedAPI();
|
||||
private static final boolean INIT_API_SUPPORTED = EXTENSIONS_PRESENT &&
|
||||
(!EXTENSIONS_VERSION.startsWith(NON_INIT_VERSION_PREFIX));
|
||||
private static final boolean RESULT_API_SUPPORTED = EXTENSIONS_PRESENT &&
|
||||
(EXTENSIONS_VERSION.startsWith(RESULTS_VERSION_PREFIX));
|
||||
|
||||
private HashMap<String, CameraCharacteristics> mCharacteristicsHashMap = new HashMap<>();
|
||||
private HashMap<String, Long> mMetadataVendorIdMap = new HashMap<>();
|
||||
@@ -1242,7 +1247,7 @@ public class CameraExtensionsProxyService extends Service {
|
||||
}
|
||||
|
||||
if (processor != null) {
|
||||
return new PreviewImageProcessorImplStub(processor);
|
||||
return new PreviewImageProcessorImplStub(processor, mCameraId);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -1332,7 +1337,7 @@ public class CameraExtensionsProxyService extends Service {
|
||||
public ICaptureProcessorImpl getCaptureProcessor() {
|
||||
CaptureProcessorImpl captureProcessor = mImageExtender.getCaptureProcessor();
|
||||
if (captureProcessor != null) {
|
||||
return new CaptureProcessorImplStub(captureProcessor);
|
||||
return new CaptureProcessorImplStub(captureProcessor, mCameraId);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -1390,13 +1395,97 @@ public class CameraExtensionsProxyService extends Service {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CameraMetadataNative getAvailableCaptureRequestKeys() {
|
||||
if (RESULT_API_SUPPORTED) {
|
||||
List<CaptureRequest.Key> supportedCaptureKeys =
|
||||
mImageExtender.getAvailableCaptureRequestKeys();
|
||||
|
||||
if ((supportedCaptureKeys != null) && !supportedCaptureKeys.isEmpty()) {
|
||||
CameraMetadataNative ret = new CameraMetadataNative();
|
||||
long vendorId = mMetadataVendorIdMap.containsKey(mCameraId) ?
|
||||
mMetadataVendorIdMap.get(mCameraId) : Long.MAX_VALUE;
|
||||
ret.setVendorId(vendorId);
|
||||
int requestKeyTags [] = new int[supportedCaptureKeys.size()];
|
||||
int i = 0;
|
||||
for (CaptureRequest.Key key : supportedCaptureKeys) {
|
||||
requestKeyTags[i++] = CameraMetadataNative.getTag(key.getName(), vendorId);
|
||||
}
|
||||
ret.set(CameraCharacteristics.REQUEST_AVAILABLE_REQUEST_KEYS, requestKeyTags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CameraMetadataNative getAvailableCaptureResultKeys() {
|
||||
if (RESULT_API_SUPPORTED) {
|
||||
List<CaptureResult.Key> supportedResultKeys =
|
||||
mImageExtender.getAvailableCaptureResultKeys();
|
||||
|
||||
if ((supportedResultKeys != null) && !supportedResultKeys.isEmpty()) {
|
||||
CameraMetadataNative ret = new CameraMetadataNative();
|
||||
long vendorId = mMetadataVendorIdMap.containsKey(mCameraId) ?
|
||||
mMetadataVendorIdMap.get(mCameraId) : Long.MAX_VALUE;
|
||||
ret.setVendorId(vendorId);
|
||||
int resultKeyTags [] = new int[supportedResultKeys.size()];
|
||||
int i = 0;
|
||||
for (CaptureResult.Key key : supportedResultKeys) {
|
||||
resultKeyTags[i++] = CameraMetadataNative.getTag(key.getName(), vendorId);
|
||||
}
|
||||
ret.set(CameraCharacteristics.REQUEST_AVAILABLE_RESULT_KEYS, resultKeyTags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class ProcessResultCallback implements ProcessResultImpl {
|
||||
private final IProcessResultImpl mProcessResult;
|
||||
private final String mCameraId;
|
||||
|
||||
private ProcessResultCallback(IProcessResultImpl processResult, String cameraId) {
|
||||
mProcessResult = processResult;
|
||||
mCameraId = cameraId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCaptureCompleted(long shutterTimestamp,
|
||||
List<Pair<CaptureResult.Key, Object>> result) {
|
||||
if (result == null) {
|
||||
Log.e(TAG, "Invalid capture result received!");
|
||||
}
|
||||
|
||||
CameraMetadataNative captureResults = new CameraMetadataNative();
|
||||
if (mMetadataVendorIdMap.containsKey(mCameraId)) {
|
||||
captureResults.setVendorId(mMetadataVendorIdMap.get(mCameraId));
|
||||
}
|
||||
for (Pair<CaptureResult.Key, Object> pair : result) {
|
||||
captureResults.set(pair.first, pair.second);
|
||||
}
|
||||
|
||||
try {
|
||||
mProcessResult.onCaptureCompleted(shutterTimestamp, captureResults);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Remote client doesn't respond to capture results!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CaptureProcessorImplStub extends ICaptureProcessorImpl.Stub {
|
||||
private final CaptureProcessorImpl mCaptureProcessor;
|
||||
private final String mCameraId;
|
||||
|
||||
public CaptureProcessorImplStub(CaptureProcessorImpl captureProcessor) {
|
||||
public CaptureProcessorImplStub(CaptureProcessorImpl captureProcessor, String cameraId) {
|
||||
mCaptureProcessor = captureProcessor;
|
||||
mCameraId = cameraId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1415,7 +1504,7 @@ public class CameraExtensionsProxyService extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(List<CaptureBundle> captureList) {
|
||||
public void process(List<CaptureBundle> captureList, IProcessResultImpl resultCallback) {
|
||||
HashMap<Integer, Pair<Image, TotalCaptureResult>> captureMap = new HashMap<>();
|
||||
for (CaptureBundle captureBundle : captureList) {
|
||||
captureMap.put(captureBundle.stage, new Pair<> (
|
||||
@@ -1424,7 +1513,14 @@ public class CameraExtensionsProxyService extends Service {
|
||||
captureBundle.sequenceId)));
|
||||
}
|
||||
if (!captureMap.isEmpty()) {
|
||||
mCaptureProcessor.process(captureMap);
|
||||
if ((resultCallback != null) && (RESULT_API_SUPPORTED)) {
|
||||
mCaptureProcessor.process(captureMap, new ProcessResultCallback(resultCallback,
|
||||
mCameraId), null /*executor*/);
|
||||
} else if (resultCallback == null) {
|
||||
mCaptureProcessor.process(captureMap);
|
||||
} else {
|
||||
Log.e(TAG, "Process requests with capture results are not supported!");
|
||||
}
|
||||
} else {
|
||||
Log.e(TAG, "Process request with absent capture stages!");
|
||||
}
|
||||
@@ -1433,9 +1529,11 @@ public class CameraExtensionsProxyService extends Service {
|
||||
|
||||
private class PreviewImageProcessorImplStub extends IPreviewImageProcessorImpl.Stub {
|
||||
private final PreviewImageProcessorImpl mProcessor;
|
||||
private final String mCameraId;
|
||||
|
||||
public PreviewImageProcessorImplStub(PreviewImageProcessorImpl processor) {
|
||||
public PreviewImageProcessorImplStub(PreviewImageProcessorImpl processor, String cameraId) {
|
||||
mProcessor = processor;
|
||||
mCameraId = cameraId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1455,9 +1553,17 @@ public class CameraExtensionsProxyService extends Service {
|
||||
|
||||
@Override
|
||||
public void process(android.hardware.camera2.extension.ParcelImage image,
|
||||
CameraMetadataNative result, int sequenceId) {
|
||||
mProcessor.process(new ExtensionImage(image),
|
||||
new TotalCaptureResult(result, sequenceId));
|
||||
CameraMetadataNative result, int sequenceId, IProcessResultImpl resultCallback) {
|
||||
if ((resultCallback != null) && RESULT_API_SUPPORTED) {
|
||||
mProcessor.process(new ExtensionImage(image),
|
||||
new TotalCaptureResult(result, sequenceId),
|
||||
new ProcessResultCallback(resultCallback, mCameraId), null /*executor*/);
|
||||
} else if (resultCallback == null) {
|
||||
mProcessor.process(new ExtensionImage(image),
|
||||
new TotalCaptureResult(result, sequenceId));
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user