Loading core/java/android/hardware/camera2/CameraExtensionCharacteristics.java +28 −6 Original line number Diff line number Diff line Loading @@ -693,18 +693,40 @@ public final class CameraExtensionCharacteristics { throw new IllegalArgumentException("Unsupported extension"); } if (areAdvancedExtensionsSupported()) { IAdvancedExtenderImpl extender = initializeAdvancedExtension(extension); extender.init(mCameraId); android.hardware.camera2.extension.Size sz = new android.hardware.camera2.extension.Size(); sz.width = captureOutputSize.getWidth(); sz.height = captureOutputSize.getHeight(); if (areAdvancedExtensionsSupported()) { IAdvancedExtenderImpl extender = initializeAdvancedExtension(extension); extender.init(mCameraId); LatencyRange latencyRange = extender.getEstimatedCaptureLatencyRange(mCameraId, sz, format); if (latencyRange != null) { return new Range(latencyRange.min, latencyRange.max); } } else { Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders = initializeExtension(extension); extenders.second.init(mCameraId, mChars.getNativeMetadata()); if ((format == ImageFormat.YUV_420_888) && (extenders.second.getCaptureProcessor() == null) ){ // Extensions that don't implement any capture processor are limited to // JPEG only! return null; } if ((format == ImageFormat.JPEG) && (extenders.second.getCaptureProcessor() != null)) { // The framework will perform the additional encoding pass on the // processed YUV_420 buffers. Latency in this case is very device // specific and cannot be estimated accurately enough. return null; } LatencyRange latencyRange = extenders.second.getEstimatedCaptureLatencyRange(sz); if (latencyRange != null) { return new Range(latencyRange.min, latencyRange.max); } } } catch (RemoteException e) { Log.e(TAG, "Failed to query the extension capture latency! Extension service does" Loading core/java/android/hardware/camera2/extension/IImageCaptureExtenderImpl.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.extension.CaptureStageImpl; import android.hardware.camera2.extension.ICaptureProcessorImpl; import android.hardware.camera2.extension.LatencyRange; import android.hardware.camera2.extension.Size; import android.hardware.camera2.extension.SizeList; /** @hide */ Loading @@ -36,4 +38,5 @@ interface IImageCaptureExtenderImpl @nullable List<CaptureStageImpl> getCaptureStages(); int getMaxCaptureStage(); @nullable List<SizeList> getSupportedResolutions(); LatencyRange getEstimatedCaptureLatencyRange(in Size outputSize); } core/java/android/hardware/camera2/extension/IImageProcessorImpl.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -21,5 +21,6 @@ import android.hardware.camera2.extension.ParcelImage; /** @hide */ interface IImageProcessorImpl { void onNextImageAvailable(in OutputConfigId outputConfigId, in ParcelImage image); void onNextImageAvailable(in OutputConfigId outputConfigId, in ParcelImage image, in String physicalCameraId); } core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java +27 −14 Original line number Diff line number Diff line Loading @@ -79,8 +79,8 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private final HandlerThread mHandlerThread; private final CameraExtensionSession.StateCallback mCallbacks; private final IAdvancedExtenderImpl mAdvancedExtender; // maps camera outputs to extension output ids private final HashMap<Surface, Integer> mSurfaceIdMap = new HashMap<>(); // maps registered camera surfaces to extension output configs private final HashMap<Surface, CameraOutputConfig> mCameraConfigMap = new HashMap<>(); // maps camera extension output ids to camera registered image readers private final HashMap<Integer, ImageReader> mReaderMap = new HashMap<>(); private final RequestProcessor mRequestProcessor = new RequestProcessor(); Loading Loading @@ -226,7 +226,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes reader.getSurface()); break; case CameraOutputConfig.TYPE_MULTIRES_IMAGEREADER: // TBD // Support for multi-resolution outputs to be added in future releases default: throw new IllegalArgumentException("Unsupported output config type: " + output.type); Loading @@ -251,7 +251,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } } outputList.add(outConfig); mSurfaceIdMap.put(outConfig.getSurface(), output.outputId.id); mCameraConfigMap.put(outConfig.getSurface(), output); } SessionConfiguration sessionConfiguration = new SessionConfiguration( Loading Loading @@ -629,7 +629,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes if (request.getTag() instanceof Integer) { Integer requestId = (Integer) request.getTag(); mCallback.onCaptureBufferLost(requestId, frameNumber, mSurfaceIdMap.get(target)); mCameraConfigMap.get(target).outputId.id); } else { Log.e(TAG, "Invalid capture request tag!"); } Loading Loading @@ -736,12 +736,14 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private static final class ImageReaderHandler implements ImageReader.OnImageAvailableListener { private final OutputConfigId mOutputConfigId; private final IImageProcessorImpl mIImageProcessor; private final String mPhysicalCameraId; private ImageReaderHandler(int outputConfigId, IImageProcessorImpl iImageProcessor) { IImageProcessorImpl iImageProcessor, String physicalCameraId) { mOutputConfigId = new OutputConfigId(); mOutputConfigId.id = outputConfigId; mIImageProcessor = iImageProcessor; mPhysicalCameraId = physicalCameraId; } @Override Loading Loading @@ -787,7 +789,8 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes parcelImage.crop = img.getCropRect(); try { mIImageProcessor.onNextImageAvailable(mOutputConfigId, parcelImage); mIImageProcessor.onNextImageAvailable(mOutputConfigId, parcelImage, mPhysicalCameraId); } catch (RemoteException e) { Log.e(TAG, "Failed to propagate image buffer on output surface id: " + mOutputConfigId + " extension service does not respond!"); Loading @@ -804,8 +807,17 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes IImageProcessorImpl imageProcessor) { synchronized (mInterfaceLock) { if (mReaderMap.containsKey(outputConfigId.id)) { mReaderMap.get(outputConfigId.id).setOnImageAvailableListener( new ImageReaderHandler(outputConfigId.id, imageProcessor), mHandler); ImageReader reader = mReaderMap.get(outputConfigId.id); String physicalCameraId = null; if (mCameraConfigMap.containsKey(reader.getSurface())) { physicalCameraId = mCameraConfigMap.get(reader.getSurface()).physicalCameraId; reader.setOnImageAvailableListener(new ImageReaderHandler(outputConfigId.id, imageProcessor, physicalCameraId), mHandler); } else { Log.e(TAG, "Camera output configuration for ImageReader with " + " config Id " + outputConfigId.id + " not found!"); } } else { Log.e(TAG, "ImageReader with output config id: " + outputConfigId.id + " not found!"); Loading @@ -828,7 +840,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes ArrayList<CaptureRequest> captureRequests = new ArrayList<>(); for (Request request : requests) { captureRequests.add(initializeCaptureRequest(mCameraDevice, request, mSurfaceIdMap)); mCameraConfigMap)); } mCaptureSession.captureBurstRequests(captureRequests, new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback); Loading @@ -848,7 +860,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes synchronized (mInterfaceLock) { try { CaptureRequest repeatingRequest = initializeCaptureRequest(mCameraDevice, request, mSurfaceIdMap); request, mCameraConfigMap); CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback); mCaptureSession.setSingleRepeatingRequest(repeatingRequest, new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback); Loading Loading @@ -891,12 +903,13 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } private static CaptureRequest initializeCaptureRequest(CameraDevice cameraDevice, Request request, HashMap<Surface, Integer> surfaceIdMap) throws CameraAccessException { Request request, HashMap<Surface, CameraOutputConfig> surfaceIdMap) throws CameraAccessException { CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(request.templateId); for (OutputConfigId configId : request.targetOutputConfigIds) { boolean found = false; for (Map.Entry<Surface, Integer> entry : surfaceIdMap.entrySet()) { if (entry.getValue() == configId.id) { for (Map.Entry<Surface, CameraOutputConfig> entry : surfaceIdMap.entrySet()) { if (entry.getValue().outputId.id == configId.id) { builder.addTarget(entry.getKey()); found = true; break; Loading core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java +0 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package android.hardware.camera2.impl; import android.content.Context; import android.graphics.ImageFormat; import android.graphics.PixelFormat; import android.graphics.SurfaceTexture; import android.hardware.HardwareBuffer; import android.hardware.camera2.CameraAccessException; Loading @@ -42,7 +41,6 @@ import android.hardware.camera2.TotalCaptureResult; import android.hardware.camera2.params.ExtensionSessionConfiguration; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.params.SessionConfiguration; import android.hardware.camera2.params.StreamConfigurationMap; import android.hardware.camera2.utils.SurfaceUtils; import android.media.Image; import android.media.ImageReader; Loading @@ -68,7 +66,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; public final class CameraExtensionSessionImpl extends CameraExtensionSession { private static final int PREVIEW_QUEUE_SIZE = 3; Loading Loading
core/java/android/hardware/camera2/CameraExtensionCharacteristics.java +28 −6 Original line number Diff line number Diff line Loading @@ -693,18 +693,40 @@ public final class CameraExtensionCharacteristics { throw new IllegalArgumentException("Unsupported extension"); } if (areAdvancedExtensionsSupported()) { IAdvancedExtenderImpl extender = initializeAdvancedExtension(extension); extender.init(mCameraId); android.hardware.camera2.extension.Size sz = new android.hardware.camera2.extension.Size(); sz.width = captureOutputSize.getWidth(); sz.height = captureOutputSize.getHeight(); if (areAdvancedExtensionsSupported()) { IAdvancedExtenderImpl extender = initializeAdvancedExtension(extension); extender.init(mCameraId); LatencyRange latencyRange = extender.getEstimatedCaptureLatencyRange(mCameraId, sz, format); if (latencyRange != null) { return new Range(latencyRange.min, latencyRange.max); } } else { Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders = initializeExtension(extension); extenders.second.init(mCameraId, mChars.getNativeMetadata()); if ((format == ImageFormat.YUV_420_888) && (extenders.second.getCaptureProcessor() == null) ){ // Extensions that don't implement any capture processor are limited to // JPEG only! return null; } if ((format == ImageFormat.JPEG) && (extenders.second.getCaptureProcessor() != null)) { // The framework will perform the additional encoding pass on the // processed YUV_420 buffers. Latency in this case is very device // specific and cannot be estimated accurately enough. return null; } LatencyRange latencyRange = extenders.second.getEstimatedCaptureLatencyRange(sz); if (latencyRange != null) { return new Range(latencyRange.min, latencyRange.max); } } } catch (RemoteException e) { Log.e(TAG, "Failed to query the extension capture latency! Extension service does" Loading
core/java/android/hardware/camera2/extension/IImageCaptureExtenderImpl.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.extension.CaptureStageImpl; import android.hardware.camera2.extension.ICaptureProcessorImpl; import android.hardware.camera2.extension.LatencyRange; import android.hardware.camera2.extension.Size; import android.hardware.camera2.extension.SizeList; /** @hide */ Loading @@ -36,4 +38,5 @@ interface IImageCaptureExtenderImpl @nullable List<CaptureStageImpl> getCaptureStages(); int getMaxCaptureStage(); @nullable List<SizeList> getSupportedResolutions(); LatencyRange getEstimatedCaptureLatencyRange(in Size outputSize); }
core/java/android/hardware/camera2/extension/IImageProcessorImpl.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -21,5 +21,6 @@ import android.hardware.camera2.extension.ParcelImage; /** @hide */ interface IImageProcessorImpl { void onNextImageAvailable(in OutputConfigId outputConfigId, in ParcelImage image); void onNextImageAvailable(in OutputConfigId outputConfigId, in ParcelImage image, in String physicalCameraId); }
core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java +27 −14 Original line number Diff line number Diff line Loading @@ -79,8 +79,8 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private final HandlerThread mHandlerThread; private final CameraExtensionSession.StateCallback mCallbacks; private final IAdvancedExtenderImpl mAdvancedExtender; // maps camera outputs to extension output ids private final HashMap<Surface, Integer> mSurfaceIdMap = new HashMap<>(); // maps registered camera surfaces to extension output configs private final HashMap<Surface, CameraOutputConfig> mCameraConfigMap = new HashMap<>(); // maps camera extension output ids to camera registered image readers private final HashMap<Integer, ImageReader> mReaderMap = new HashMap<>(); private final RequestProcessor mRequestProcessor = new RequestProcessor(); Loading Loading @@ -226,7 +226,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes reader.getSurface()); break; case CameraOutputConfig.TYPE_MULTIRES_IMAGEREADER: // TBD // Support for multi-resolution outputs to be added in future releases default: throw new IllegalArgumentException("Unsupported output config type: " + output.type); Loading @@ -251,7 +251,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } } outputList.add(outConfig); mSurfaceIdMap.put(outConfig.getSurface(), output.outputId.id); mCameraConfigMap.put(outConfig.getSurface(), output); } SessionConfiguration sessionConfiguration = new SessionConfiguration( Loading Loading @@ -629,7 +629,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes if (request.getTag() instanceof Integer) { Integer requestId = (Integer) request.getTag(); mCallback.onCaptureBufferLost(requestId, frameNumber, mSurfaceIdMap.get(target)); mCameraConfigMap.get(target).outputId.id); } else { Log.e(TAG, "Invalid capture request tag!"); } Loading Loading @@ -736,12 +736,14 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private static final class ImageReaderHandler implements ImageReader.OnImageAvailableListener { private final OutputConfigId mOutputConfigId; private final IImageProcessorImpl mIImageProcessor; private final String mPhysicalCameraId; private ImageReaderHandler(int outputConfigId, IImageProcessorImpl iImageProcessor) { IImageProcessorImpl iImageProcessor, String physicalCameraId) { mOutputConfigId = new OutputConfigId(); mOutputConfigId.id = outputConfigId; mIImageProcessor = iImageProcessor; mPhysicalCameraId = physicalCameraId; } @Override Loading Loading @@ -787,7 +789,8 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes parcelImage.crop = img.getCropRect(); try { mIImageProcessor.onNextImageAvailable(mOutputConfigId, parcelImage); mIImageProcessor.onNextImageAvailable(mOutputConfigId, parcelImage, mPhysicalCameraId); } catch (RemoteException e) { Log.e(TAG, "Failed to propagate image buffer on output surface id: " + mOutputConfigId + " extension service does not respond!"); Loading @@ -804,8 +807,17 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes IImageProcessorImpl imageProcessor) { synchronized (mInterfaceLock) { if (mReaderMap.containsKey(outputConfigId.id)) { mReaderMap.get(outputConfigId.id).setOnImageAvailableListener( new ImageReaderHandler(outputConfigId.id, imageProcessor), mHandler); ImageReader reader = mReaderMap.get(outputConfigId.id); String physicalCameraId = null; if (mCameraConfigMap.containsKey(reader.getSurface())) { physicalCameraId = mCameraConfigMap.get(reader.getSurface()).physicalCameraId; reader.setOnImageAvailableListener(new ImageReaderHandler(outputConfigId.id, imageProcessor, physicalCameraId), mHandler); } else { Log.e(TAG, "Camera output configuration for ImageReader with " + " config Id " + outputConfigId.id + " not found!"); } } else { Log.e(TAG, "ImageReader with output config id: " + outputConfigId.id + " not found!"); Loading @@ -828,7 +840,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes ArrayList<CaptureRequest> captureRequests = new ArrayList<>(); for (Request request : requests) { captureRequests.add(initializeCaptureRequest(mCameraDevice, request, mSurfaceIdMap)); mCameraConfigMap)); } mCaptureSession.captureBurstRequests(captureRequests, new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback); Loading @@ -848,7 +860,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes synchronized (mInterfaceLock) { try { CaptureRequest repeatingRequest = initializeCaptureRequest(mCameraDevice, request, mSurfaceIdMap); request, mCameraConfigMap); CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback); mCaptureSession.setSingleRepeatingRequest(repeatingRequest, new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback); Loading Loading @@ -891,12 +903,13 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } private static CaptureRequest initializeCaptureRequest(CameraDevice cameraDevice, Request request, HashMap<Surface, Integer> surfaceIdMap) throws CameraAccessException { Request request, HashMap<Surface, CameraOutputConfig> surfaceIdMap) throws CameraAccessException { CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(request.templateId); for (OutputConfigId configId : request.targetOutputConfigIds) { boolean found = false; for (Map.Entry<Surface, Integer> entry : surfaceIdMap.entrySet()) { if (entry.getValue() == configId.id) { for (Map.Entry<Surface, CameraOutputConfig> entry : surfaceIdMap.entrySet()) { if (entry.getValue().outputId.id == configId.id) { builder.addTarget(entry.getKey()); found = true; break; Loading
core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java +0 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package android.hardware.camera2.impl; import android.content.Context; import android.graphics.ImageFormat; import android.graphics.PixelFormat; import android.graphics.SurfaceTexture; import android.hardware.HardwareBuffer; import android.hardware.camera2.CameraAccessException; Loading @@ -42,7 +41,6 @@ import android.hardware.camera2.TotalCaptureResult; import android.hardware.camera2.params.ExtensionSessionConfiguration; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.params.SessionConfiguration; import android.hardware.camera2.params.StreamConfigurationMap; import android.hardware.camera2.utils.SurfaceUtils; import android.media.Image; import android.media.ImageReader; Loading @@ -68,7 +66,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; public final class CameraExtensionSessionImpl extends CameraExtensionSession { private static final int PREVIEW_QUEUE_SIZE = 3; Loading