Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd3707ad authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Camera: Support advanced extensions" into sc-dev

parents e13111ba 21b1302c
Loading
Loading
Loading
Loading
+136 −35
Original line number Original line Diff line number Diff line
@@ -21,9 +21,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.ServiceConnection;
import android.graphics.ImageFormat;
import android.graphics.ImageFormat;
import android.hardware.camera2.extension.IAdvancedExtenderImpl;
import android.hardware.camera2.extension.ICameraExtensionsProxyService;
import android.hardware.camera2.extension.ICameraExtensionsProxyService;
import android.hardware.camera2.extension.IImageCaptureExtenderImpl;
import android.hardware.camera2.extension.IImageCaptureExtenderImpl;
import android.hardware.camera2.extension.IPreviewExtenderImpl;
import android.hardware.camera2.extension.IPreviewExtenderImpl;
import android.hardware.camera2.extension.LatencyRange;
import android.hardware.camera2.extension.SizeList;
import android.hardware.camera2.extension.SizeList;
import android.hardware.camera2.params.ExtensionSessionConfiguration;
import android.hardware.camera2.params.ExtensionSessionConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.hardware.camera2.params.StreamConfigurationMap;
@@ -220,6 +222,7 @@ public final class CameraExtensionCharacteristics {
        private InitializerFuture mInitFuture = null;
        private InitializerFuture mInitFuture = null;
        private ServiceConnection mConnection = null;
        private ServiceConnection mConnection = null;
        private ICameraExtensionsProxyService mProxy = null;
        private ICameraExtensionsProxyService mProxy = null;
        private boolean mSupportsAdvancedExtensions = false;


        // Singleton, don't allow construction
        // Singleton, don't allow construction
        private CameraExtensionManagerGlobal() {}
        private CameraExtensionManagerGlobal() {}
@@ -245,6 +248,11 @@ public final class CameraExtensionCharacteristics {
                    public void onServiceConnected(ComponentName component, IBinder binder) {
                    public void onServiceConnected(ComponentName component, IBinder binder) {
                        mProxy = ICameraExtensionsProxyService.Stub.asInterface(binder);
                        mProxy = ICameraExtensionsProxyService.Stub.asInterface(binder);
                        mInitFuture.setStatus(true);
                        mInitFuture.setStatus(true);
                        try {
                            mSupportsAdvancedExtensions = mProxy.advancedExtensionsSupported();
                        } catch (RemoteException e) {
                            Log.e(TAG, "Remote IPC failed!");
                        }
                    }
                    }
                };
                };
                ctx.bindService(intent, mConnection, Context.BIND_AUTO_CREATE |
                ctx.bindService(intent, mConnection, Context.BIND_AUTO_CREATE |
@@ -334,6 +342,10 @@ public final class CameraExtensionCharacteristics {
            }
            }
        }
        }


        public boolean areAdvancedExtensionsSupported() {
            return mSupportsAdvancedExtensions;
        }

        public IPreviewExtenderImpl initializePreviewExtension(int extensionType)
        public IPreviewExtenderImpl initializePreviewExtension(int extensionType)
                throws RemoteException {
                throws RemoteException {
            synchronized (mLock) {
            synchronized (mLock) {
@@ -355,6 +367,17 @@ public final class CameraExtensionCharacteristics {
                }
                }
            }
            }
        }
        }

        public IAdvancedExtenderImpl initializeAdvancedExtension(int extensionType)
                throws RemoteException {
            synchronized (mLock) {
                if (mProxy != null) {
                    return mProxy.initializeAdvancedExtension(extensionType);
                } else {
                    return null;
                }
            }
        }
    }
    }


    /**
    /**
@@ -371,11 +394,28 @@ public final class CameraExtensionCharacteristics {
        CameraExtensionManagerGlobal.get().unregisterClient(clientId);
        CameraExtensionManagerGlobal.get().unregisterClient(clientId);
    }
    }


    /**
     * @hide
     */
    public static boolean areAdvancedExtensionsSupported() {
        return CameraExtensionManagerGlobal.get().areAdvancedExtensionsSupported();
    }

    /**
    /**
     * @hide
     * @hide
     */
     */
    public static boolean isExtensionSupported(String cameraId, int extensionType,
    public static boolean isExtensionSupported(String cameraId, int extensionType,
            CameraCharacteristics chars) {
            CameraCharacteristics chars) {
        if (areAdvancedExtensionsSupported()) {
            try {
                IAdvancedExtenderImpl extender = initializeAdvancedExtension(extensionType);
                return extender.isExtensionAvailable(cameraId);
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to query extension availability! Extension service does not"
                        + " respond!");
                return false;
            }
        } else {
            Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders;
            Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders;
            try {
            try {
                extenders = initializeExtension(extensionType);
                extenders = initializeExtension(extensionType);
@@ -392,6 +432,26 @@ public final class CameraExtensionCharacteristics {
                return false;
                return false;
            }
            }
        }
        }
    }

    /**
     * @hide
     */
    public static IAdvancedExtenderImpl initializeAdvancedExtension(@Extension int extensionType) {
        IAdvancedExtenderImpl extender;
        try {
            extender = CameraExtensionManagerGlobal.get().initializeAdvancedExtension(
                    extensionType);
        } catch (RemoteException e) {
            throw new IllegalStateException("Failed to initialize extension: " + extensionType);
        }

        if (extender == null) {
            throw new IllegalArgumentException("Unknown extension: " + extensionType);
        }

        return extender;
    }


    /**
    /**
     * @hide
     * @hide
@@ -487,13 +547,21 @@ public final class CameraExtensionCharacteristics {
                throw new IllegalArgumentException("Unsupported extension");
                throw new IllegalArgumentException("Unsupported extension");
            }
            }


            Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
                    initializeExtension(extension);
            StreamConfigurationMap streamMap = mChars.get(
            StreamConfigurationMap streamMap = mChars.get(
                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            if (areAdvancedExtensionsSupported()) {
                IAdvancedExtenderImpl extender = initializeAdvancedExtension(extension);
                extender.init(mCameraId);
                return generateSupportedSizes(
                        extender.getSupportedPreviewOutputResolutions(mCameraId),
                        ImageFormat.PRIVATE, streamMap);
            } else {
                Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
                        initializeExtension(extension);
                extenders.first.init(mCameraId, mChars.getNativeMetadata());
                extenders.first.init(mCameraId, mChars.getNativeMetadata());
                return generateSupportedSizes(extenders.first.getSupportedResolutions(),
                return generateSupportedSizes(extenders.first.getSupportedResolutions(),
                        ImageFormat.PRIVATE, streamMap);
                        ImageFormat.PRIVATE, streamMap);
            }
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to query the extension supported sizes! Extension service does"
            Log.e(TAG, "Failed to query the extension supported sizes! Extension service does"
                    + " not respond!");
                    + " not respond!");
@@ -536,11 +604,24 @@ public final class CameraExtensionCharacteristics {
                    throw new IllegalArgumentException("Unsupported extension");
                    throw new IllegalArgumentException("Unsupported extension");
                }
                }


                Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
                        initializeExtension(extension);
                StreamConfigurationMap streamMap = mChars.get(
                StreamConfigurationMap streamMap = mChars.get(
                        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                if (areAdvancedExtensionsSupported()) {
                    switch(format) {
                        case ImageFormat.YUV_420_888:
                        case ImageFormat.JPEG:
                            break;
                        default:
                            throw new IllegalArgumentException("Unsupported format: " + format);
                    }
                    IAdvancedExtenderImpl extender = initializeAdvancedExtension(extension);
                    extender.init(mCameraId);
                    return generateSupportedSizes(extender.getSupportedCaptureOutputResolutions(
                            mCameraId), format, streamMap);
                } else {
                    if (format == ImageFormat.YUV_420_888) {
                    if (format == ImageFormat.YUV_420_888) {
                        Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
                                initializeExtension(extension);
                        extenders.second.init(mCameraId, mChars.getNativeMetadata());
                        extenders.second.init(mCameraId, mChars.getNativeMetadata());
                        if (extenders.second.getCaptureProcessor() == null) {
                        if (extenders.second.getCaptureProcessor() == null) {
                            // Extensions that don't implement any capture processor are limited to
                            // Extensions that don't implement any capture processor are limited to
@@ -550,6 +631,8 @@ public final class CameraExtensionCharacteristics {
                        return generateSupportedSizes(extenders.second.getSupportedResolutions(),
                        return generateSupportedSizes(extenders.second.getSupportedResolutions(),
                                format, streamMap);
                                format, streamMap);
                    } else if (format == ImageFormat.JPEG) {
                    } else if (format == ImageFormat.JPEG) {
                        Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
                                initializeExtension(extension);
                        extenders.second.init(mCameraId, mChars.getNativeMetadata());
                        extenders.second.init(mCameraId, mChars.getNativeMetadata());
                        if (extenders.second.getCaptureProcessor() != null) {
                        if (extenders.second.getCaptureProcessor() != null) {
                            // The framework will perform the additional encoding pass on the
                            // The framework will perform the additional encoding pass on the
@@ -562,6 +645,7 @@ public final class CameraExtensionCharacteristics {
                    } else {
                    } else {
                        throw new IllegalArgumentException("Unsupported format: " + format);
                        throw new IllegalArgumentException("Unsupported format: " + format);
                    }
                    }
                }
            } finally {
            } finally {
                unregisterClient(clientId);
                unregisterClient(clientId);
            }
            }
@@ -608,6 +692,23 @@ public final class CameraExtensionCharacteristics {
            if (!isExtensionSupported(mCameraId, extension, mChars)) {
            if (!isExtensionSupported(mCameraId, extension, mChars)) {
                throw new IllegalArgumentException("Unsupported extension");
                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();
                LatencyRange latencyRange = extender.getEstimatedCaptureLatencyRange(mCameraId,
                        sz, format);
                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"
                    + " not respond!");
        } finally {
        } finally {
            unregisterClient(clientId);
            unregisterClient(clientId);
        }
        }
+27 −0
Original line number Original line Diff line number Diff line
@@ -229,6 +229,33 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
        mFrameNumber = extras.getFrameNumber();
        mFrameNumber = extras.getFrameNumber();
    }
    }


    /**
     * Takes ownership of the passed-in properties object
     *
     * <p>For internal use only</p>
     * @hide
     */
    public CaptureResult(String cameraId, CameraMetadataNative results, CaptureRequest parent,
            int requestId, long frameNumber) {
        if (results == null) {
            throw new IllegalArgumentException("results was null");
        }

        if (parent == null) {
            throw new IllegalArgumentException("parent was null");
        }

        mResults = CameraMetadataNative.move(results);
        if (mResults.isEmpty()) {
            throw new AssertionError("Results must not be empty");
        }
        setNativeInstance(mResults);
        mCameraId = cameraId;
        mRequest = parent;
        mSequenceId = requestId;
        mFrameNumber = frameNumber;
    }

    /**
    /**
     * Returns a copy of the underlying {@link CameraMetadataNative}.
     * Returns a copy of the underlying {@link CameraMetadataNative}.
     * @hide
     * @hide
+30 −0
Original line number Original line Diff line number Diff line
@@ -93,6 +93,36 @@ public final class TotalCaptureResult extends CaptureResult {
        }
        }
    }
    }


    /**
     * Takes ownership of the passed-in camera metadata and the partial results
     *
     * @param partials a list of partial results; {@code null} will be substituted for an empty list
     * @hide
     */
    public TotalCaptureResult(String logicalCameraId, CameraMetadataNative results,
            CaptureRequest parent, int requestId, long frameNumber, List<CaptureResult> partials,
            int sessionId, PhysicalCaptureResultInfo[] physicalResults) {
        super(logicalCameraId, results, parent, requestId, frameNumber);

        if (partials == null) {
            mPartialResults = new ArrayList<>();
        } else {
            mPartialResults = partials;
        }

        mSessionId = sessionId;

        mPhysicalCaptureResults = new HashMap<String, TotalCaptureResult>();
        for (PhysicalCaptureResultInfo onePhysicalResult : physicalResults) {
            TotalCaptureResult physicalResult = new TotalCaptureResult(
                    onePhysicalResult.getCameraId(), onePhysicalResult.getCameraMetadata(),
                    parent, requestId, frameNumber, /*partials*/null, sessionId,
                    new PhysicalCaptureResultInfo[0]);
            mPhysicalCaptureResults.put(onePhysicalResult.getCameraId(),
                    physicalResult);
        }
    }

    /**
    /**
     * Creates a request-less result.
     * Creates a request-less result.
     *
     *
+39 −0
Original line number Original line Diff line number Diff line
/**
 * Copyright (c) 2021, 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.extension.Size;
import android.hardware.camera2.extension.OutputConfigId;
import android.view.Surface;

/** @hide */
parcelable CameraOutputConfig
{
    Size size;
    Surface surface;
    int imageFormat;
    int capacity;

    const int TYPE_SURFACE = 0;
    const int TYPE_IMAGEREADER = 1;
    const int TYPE_MULTIRES_IMAGEREADER = 2;
    int type;

    OutputConfigId outputId;
    int surfaceGroupId;
    String physicalCameraId;
    List<OutputConfigId> surfaceSharingOutputConfigs;
}
+27 −0
Original line number Original line Diff line number Diff line
/**
 * Copyright (c) 2021, 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.extension.CameraOutputConfig;
import android.hardware.camera2.impl.CameraMetadataNative;

/** @hide */
parcelable CameraSessionConfig
{
    List<CameraOutputConfig> outputConfigs;
    CameraMetadataNative sessionParameter;
    int sessionTemplateId;
}
Loading