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

Commit 02489189 authored by Ravneet Dhanjal's avatar Ravneet Dhanjal Committed by Android (Google) Code Review
Browse files

Merge "Camera: Enable Postview feature"

parents c2fb1a80 a4a82cb7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -17966,8 +17966,10 @@ package android.hardware.camera2 {
    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);
    method @NonNull public java.util.List<android.util.Size> getPostviewSupportedSizes(int, @NonNull android.util.Size, int);
    method @NonNull public java.util.List<java.lang.Integer> getSupportedExtensions();
    method public boolean isCaptureProcessProgressAvailable(int);
    method public boolean isPostviewAvailable(int);
    field public static final int EXTENSION_AUTOMATIC = 0; // 0x0
    field @Deprecated public static final int EXTENSION_BEAUTY = 1; // 0x1
    field public static final int EXTENSION_BOKEH = 2; // 0x2
@@ -18639,7 +18641,9 @@ package android.hardware.camera2.params {
    method @NonNull public java.util.concurrent.Executor getExecutor();
    method public int getExtension();
    method @NonNull public java.util.List<android.hardware.camera2.params.OutputConfiguration> getOutputConfigurations();
    method @Nullable public android.hardware.camera2.params.OutputConfiguration getPostviewOutputConfiguration();
    method @NonNull public android.hardware.camera2.CameraExtensionSession.StateCallback getStateCallback();
    method public void setPostviewOutputConfiguration(@Nullable android.hardware.camera2.params.OutputConfiguration);
  }
  public final class Face {
+141 −0
Original line number Diff line number Diff line
@@ -573,6 +573,147 @@ public final class CameraExtensionCharacteristics {
        return Collections.unmodifiableList(ret);
    }

    /**
     * Checks for postview support of still capture.
     *
     * <p>A postview is a preview version of the still capture that is available before the final
     * image. For example, it can be used as a temporary placeholder for the requested capture
     * while the final image is being processed. The supported sizes for a still capture's postview
     * can be retrieved using
     * {@link CameraExtensionCharacteristics#getPostviewSupportedSizes(int, Size, int)}.
     * The formats of the still capture and postview should be equivalent upon capture request.</p>
     *
     * @param extension the extension type
     * @return {@code true} in case postview is supported, {@code false} otherwise
     *
     * @throws IllegalArgumentException in case the extension type is not a
     * supported device-specific extension
     */
    public boolean isPostviewAvailable(@Extension int extension) {
        long clientId = registerClient(mContext);
        if (clientId < 0) {
            throw new IllegalArgumentException("Unsupported extensions");
        }

        try {
            if (!isExtensionSupported(mCameraId, extension, mChars)) {
                throw new IllegalArgumentException("Unsupported extension");
            }

            if (areAdvancedExtensionsSupported()) {
                IAdvancedExtenderImpl extender = initializeAdvancedExtension(extension);
                extender.init(mCameraId);
                return extender.isPostviewAvailable();
            } else {
                Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
                        initializeExtension(extension);
                extenders.second.init(mCameraId, mChars.getNativeMetadata());
                return extenders.second.isPostviewAvailable();
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to query the extension for postview availability! Extension "
                    + "service does not respond!");
        } finally {
            unregisterClient(clientId);
        }

        return false;
    }

    /**
     * Get a list of the postview sizes supported for a still capture, using its
     * capture size {@code captureSize}, to use as an output for the postview request.
     *
     * <p>Available postview sizes will always be either equal to or less than the still
     * capture size. When choosing the most applicable postview size for a usecase, it should
     * be noted that lower resolution postviews will generally be available more quickly
     * than larger resolution postviews. For example, when choosing a size for an optimized
     * postview that will be displayed as a placeholder while the final image is processed,
     * the resolution closest to the preview size may be most suitable.</p>
     *
     * <p>Note that device-specific extensions are allowed to support only a subset
     * of the camera resolutions advertised by
     * {@link StreamConfigurationMap#getOutputSizes}.</p>
     *
     * @param extension the extension type
     * @param captureSize size of the still capture for which the postview is requested
     * @param format device-specific extension output format of the still capture and
     * postview
     * @return non-modifiable list of available sizes or an empty list if the format and
     * size is not supported.
     * @throws IllegalArgumentException in case of unsupported extension or if postview
     * feature is not supported by extension.
     */
    @NonNull
    public List<Size> getPostviewSupportedSizes(@Extension int extension,
            @NonNull Size captureSize, int format) {

        long clientId = registerClient(mContext);
        if (clientId < 0) {
            throw new IllegalArgumentException("Unsupported extensions");
        }

        try {
            if (!isExtensionSupported(mCameraId, extension, mChars)) {
                throw new IllegalArgumentException("Unsupported extension");
            }

            android.hardware.camera2.extension.Size sz =
                    new android.hardware.camera2.extension.Size();
            sz.width = captureSize.getWidth();
            sz.height = captureSize.getHeight();

            StreamConfigurationMap streamMap = mChars.get(
                    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.getSupportedPostviewResolutions(
                    sz), format, streamMap);
            } else {
                Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
                        initializeExtension(extension);
                extenders.second.init(mCameraId, mChars.getNativeMetadata());
                if ((extenders.second.getCaptureProcessor() == null) ||
                        !isPostviewAvailable(extension)) {
                    // Extensions that don't implement any capture processor
                    // and have processing occur in the HAL don't currently support the
                    // postview feature
                    throw new IllegalArgumentException("Extension does not support "
                            + "postview feature");
                }

                if (format == ImageFormat.YUV_420_888) {
                    return generateSupportedSizes(
                            extenders.second.getSupportedPostviewResolutions(sz),
                            format, streamMap);
                } else if (format == ImageFormat.JPEG) {
                    // The framework will perform the additional encoding pass on the
                    // processed YUV_420 buffers.
                    return generateJpegSupportedSizes(
                            extenders.second.getSupportedPostviewResolutions(sz),
                                    streamMap);
                } else {
                    throw new IllegalArgumentException("Unsupported format: " + format);
                }
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to query the extension postview supported sizes! Extension "
                    + "service does not respond!");
            return Collections.emptyList();
        } finally {
            unregisterClient(clientId);
        }
    }

    /**
     * Get a list of sizes compatible with {@code klass} to use as an output for the
     * repeating request
+8 −3
Original line number Diff line number Diff line
@@ -311,10 +311,15 @@ public abstract class CameraExtensionSession implements AutoCloseable {
     * The rest of the settings included in the request will be entirely overridden by
     * the device-specific extension. </p>
     *
     * <p>The {@link CaptureRequest.Builder#addTarget} supports only one
     * <p> If {@link CameraExtensionCharacteristics#isPostviewAvailable} returns
     * false, the {@link CaptureRequest.Builder#addTarget} will support only one
     * ImageFormat.YUV_420_888 or ImageFormat.JPEG target surface. {@link CaptureRequest}
     * arguments that include further targets will cause
     * IllegalArgumentException to be thrown. </p>
     * arguments that include further targets will cause IllegalArgumentException to be thrown.
     * If postview is available, {@link CaptureRequest.Builder#addTarget} will support up to two
     * ImageFormat.YUV_420_888 or ImageFormat.JPEG target surfaces for the still capture and
     * postview. IllegalArgumentException will be thrown if a postview target is added without
     * a still capture target, if more than two target surfaces are added, or if the surface
     * formats for postview and capture are not equivalent.
     *
     * <p>Starting with Android {@link android.os.Build.VERSION_CODES#TIRAMISU} single capture
     * requests will also support the preview {@link android.graphics.ImageFormat#PRIVATE} target
+2 −0
Original line number Diff line number Diff line
@@ -30,8 +30,10 @@ interface IAdvancedExtenderImpl
            int format);
    @nullable List<SizeList> getSupportedPreviewOutputResolutions(in String cameraId);
    @nullable List<SizeList> getSupportedCaptureOutputResolutions(in String cameraId);
    @nullable List<SizeList> getSupportedPostviewResolutions(in Size captureSize);
    ISessionProcessorImpl getSessionProcessor();
    CameraMetadataNative getAvailableCaptureRequestKeys(in String cameraId);
    CameraMetadataNative getAvailableCaptureResultKeys(in String cameraId);
    boolean isCaptureProcessProgressAvailable();
    boolean isPostviewAvailable();
}
+4 −2
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@ import android.hardware.camera2.extension.Size;
interface ICaptureProcessorImpl
{
    void onOutputSurface(in Surface surface, int imageFormat);
    void onResolutionUpdate(in Size size);
    void onPostviewOutputSurface(in Surface surface);
    void onResolutionUpdate(in Size size, in Size postviewSize);
    void onImageFormatUpdate(int imageFormat);
    void process(in List<CaptureBundle> capturelist, in IProcessResultImpl resultCallback);
    void process(in List<CaptureBundle> capturelist,
            in IProcessResultImpl resultCallback, boolean isPostviewRequested);
}
Loading