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

Commit c7f3fa19 authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Pass shared outputs during advanced extension configuration

Shared outputs are not expected to be part of the main output
configuration list. Expect to receive the shared surfaces only
as part of the corresponding shared list.

Bug: 231636379
Test: Camera CTS
Change-Id: I67547a38ed97d55c8270196403d4af5d62795351
parent 46e3f921
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@
 */
package android.hardware.camera2.extension;

import android.hardware.camera2.extension.Size;
import android.hardware.camera2.extension.OutputConfigId;
import android.hardware.camera2.extension.Size;
import android.view.Surface;

/** @hide */
@@ -35,5 +35,5 @@ parcelable CameraOutputConfig
    OutputConfigId outputId;
    int surfaceGroupId;
    String physicalCameraId;
    List<OutputConfigId> surfaceSharingOutputConfigs;
    List<CameraOutputConfig> sharedSurfaceConfigs;
}
+46 −48
Original line number Diff line number Diff line
@@ -217,60 +217,30 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
        CameraSessionConfig sessionConfig = mSessionProcessor.initSession(mCameraDevice.getId(),
                previewSurface, captureSurface);
        List<CameraOutputConfig> outputConfigs = sessionConfig.outputConfigs;
        // map camera output ids to output configurations
        HashMap<Integer, OutputConfiguration> cameraOutputs = new HashMap<>();
        ArrayList<OutputConfiguration> outputList = new ArrayList<>();
        for (CameraOutputConfig output : outputConfigs) {
            OutputConfiguration cameraOutput = null;
            switch(output.type) {
                case CameraOutputConfig.TYPE_SURFACE:
                    if (output.surface == null) {
                        Log.w(TAG, "Unsupported client output id: " + output.outputId.id +
                                ", skipping!");
                        continue;
                    }
                    cameraOutput = new OutputConfiguration(output.surfaceGroupId,
                            output.surface);
                    break;
                case CameraOutputConfig.TYPE_IMAGEREADER:
                    if ((output.imageFormat == ImageFormat.UNKNOWN) || (output.size.width <= 0) ||
                            (output.size.height <= 0)) {
                        Log.w(TAG, "Unsupported client output id: " + output.outputId.id +
                                ", skipping!");
            Surface outputSurface = initializeSurfrace(output);
            if (outputSurface == null) {
                continue;
            }
                    ImageReader reader = ImageReader.newInstance(output.size.width,
                            output.size.height, output.imageFormat, output.capacity);
                    mReaderMap.put(output.outputId.id, reader);
                    cameraOutput = new OutputConfiguration(output.surfaceGroupId,
                            reader.getSurface());
                    break;
                case CameraOutputConfig.TYPE_MULTIRES_IMAGEREADER:
                    // Support for multi-resolution outputs to be added in future releases
                default:
                    throw new IllegalArgumentException("Unsupported output config type: " +
                            output.type);
            }
            cameraOutput.setPhysicalCameraId(output.physicalCameraId);
            cameraOutputs.put(output.outputId.id, cameraOutput);
        }
            OutputConfiguration cameraOutput = new OutputConfiguration(output.surfaceGroupId,
                    outputSurface);

        ArrayList<OutputConfiguration> outputList = new ArrayList<>();
        for (CameraOutputConfig output : outputConfigs) {
            if (!cameraOutputs.containsKey(output.outputId.id)) {
                // Shared surface already removed by a previous iteration
            if ((output.sharedSurfaceConfigs != null) && !output.sharedSurfaceConfigs.isEmpty()) {
                cameraOutput.enableSurfaceSharing();
                for (CameraOutputConfig sharedOutputConfig : output.sharedSurfaceConfigs) {
                    Surface sharedSurface = initializeSurfrace(sharedOutputConfig);
                    if (sharedSurface == null) {
                        continue;
                    }
            OutputConfiguration outConfig = cameraOutputs.get(output.outputId.id);
            if ((output.surfaceSharingOutputConfigs != null) &&
                    !output.surfaceSharingOutputConfigs.isEmpty()) {
                outConfig.enableSurfaceSharing();
                for (OutputConfigId outputId : output.surfaceSharingOutputConfigs) {
                    outConfig.addSurface(cameraOutputs.get(outputId.id).getSurface());
                    cameraOutputs.remove(outputId.id);
                    cameraOutput.addSurface(sharedSurface);
                    mCameraConfigMap.put(sharedSurface, sharedOutputConfig);
                }
            }
            outputList.add(outConfig);
            mCameraConfigMap.put(outConfig.getSurface(), output);

            cameraOutput.setPhysicalCameraId(output.physicalCameraId);
            outputList.add(cameraOutput);
            mCameraConfigMap.put(cameraOutput.getSurface(), output);
        }

        SessionConfiguration sessionConfiguration = new SessionConfiguration(
@@ -995,4 +965,32 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes
        CameraMetadataNative.update(ret.getNativeMetadata(), request.parameters);
        return ret;
    }

    private Surface initializeSurfrace(CameraOutputConfig output) {
        switch(output.type) {
            case CameraOutputConfig.TYPE_SURFACE:
                if (output.surface == null) {
                    Log.w(TAG, "Unsupported client output id: " + output.outputId.id +
                            ", skipping!");
                    return null;
                }
                return output.surface;
            case CameraOutputConfig.TYPE_IMAGEREADER:
                if ((output.imageFormat == ImageFormat.UNKNOWN) || (output.size.width <= 0) ||
                        (output.size.height <= 0)) {
                    Log.w(TAG, "Unsupported client output id: " + output.outputId.id +
                            ", skipping!");
                    return null;
                }
                ImageReader reader = ImageReader.newInstance(output.size.width,
                        output.size.height, output.imageFormat, output.capacity);
                mReaderMap.put(output.outputId.id, reader);
                return reader.getSurface();
            case CameraOutputConfig.TYPE_MULTIRES_IMAGEREADER:
                // Support for multi-resolution outputs to be added in future releases
            default:
                throw new IllegalArgumentException("Unsupported output config type: " +
                        output.type);
        }
    }
}
+35 −31
Original line number Diff line number Diff line
@@ -1135,41 +1135,13 @@ public class CameraExtensionsProxyService extends Service {
            CameraSessionConfig ret = new CameraSessionConfig();
            ret.outputConfigs = new ArrayList<>();
            for (Camera2OutputConfigImpl output : outputConfigs) {
                CameraOutputConfig entry = new CameraOutputConfig();
                entry.outputId = new OutputConfigId();
                entry.outputId.id = output.getId();
                entry.physicalCameraId = output.getPhysicalCameraId();
                entry.surfaceGroupId = output.getSurfaceGroupId();
                if (output instanceof SurfaceOutputConfigImpl) {
                    SurfaceOutputConfigImpl surfaceConfig = (SurfaceOutputConfigImpl) output;
                    entry.type = CameraOutputConfig.TYPE_SURFACE;
                    entry.surface = surfaceConfig.getSurface();
                } else if (output instanceof ImageReaderOutputConfigImpl) {
                    ImageReaderOutputConfigImpl imageReaderOutputConfig =
                            (ImageReaderOutputConfigImpl) output;
                    entry.type = CameraOutputConfig.TYPE_IMAGEREADER;
                    entry.size = new android.hardware.camera2.extension.Size();
                    entry.size.width = imageReaderOutputConfig.getSize().getWidth();
                    entry.size.height = imageReaderOutputConfig.getSize().getHeight();
                    entry.imageFormat = imageReaderOutputConfig.getImageFormat();
                    entry.capacity = imageReaderOutputConfig.getMaxImages();
                } else if (output instanceof MultiResolutionImageReaderOutputConfigImpl) {
                    MultiResolutionImageReaderOutputConfigImpl multiResReaderConfig =
                            (MultiResolutionImageReaderOutputConfigImpl) output;
                    entry.type = CameraOutputConfig.TYPE_MULTIRES_IMAGEREADER;
                    entry.imageFormat = multiResReaderConfig.getImageFormat();
                    entry.capacity = multiResReaderConfig.getMaxImages();
                } else {
                    throw new IllegalStateException("Unknown output config type!");
                }
                CameraOutputConfig entry = getCameraOutputConfig(output);
                List<Camera2OutputConfigImpl> sharedOutputs =
                        output.getSurfaceSharingOutputConfigs();
                if ((sharedOutputs != null) && (!sharedOutputs.isEmpty())) {
                    entry.surfaceSharingOutputConfigs = new ArrayList<>();
                    entry.sharedSurfaceConfigs = new ArrayList<>();
                    for (Camera2OutputConfigImpl sharedOutput : sharedOutputs) {
                        OutputConfigId outputId = new OutputConfigId();
                        outputId.id = sharedOutput.getId();
                        entry.surfaceSharingOutputConfigs.add(outputId);
                        entry.sharedSurfaceConfigs.add(getCameraOutputConfig(sharedOutput));
                    }
                }
                ret.outputConfigs.add(entry);
@@ -1854,4 +1826,36 @@ public class CameraExtensionsProxyService extends Service {
            }
        }
    }

    private static CameraOutputConfig getCameraOutputConfig(Camera2OutputConfigImpl output) {
        CameraOutputConfig ret = new CameraOutputConfig();
        ret.outputId = new OutputConfigId();
        ret.outputId.id = output.getId();
        ret.physicalCameraId = output.getPhysicalCameraId();
        ret.surfaceGroupId = output.getSurfaceGroupId();
        if (output instanceof SurfaceOutputConfigImpl) {
            SurfaceOutputConfigImpl surfaceConfig = (SurfaceOutputConfigImpl) output;
            ret.type = CameraOutputConfig.TYPE_SURFACE;
            ret.surface = surfaceConfig.getSurface();
        } else if (output instanceof ImageReaderOutputConfigImpl) {
            ImageReaderOutputConfigImpl imageReaderOutputConfig =
                    (ImageReaderOutputConfigImpl) output;
            ret.type = CameraOutputConfig.TYPE_IMAGEREADER;
            ret.size = new android.hardware.camera2.extension.Size();
            ret.size.width = imageReaderOutputConfig.getSize().getWidth();
            ret.size.height = imageReaderOutputConfig.getSize().getHeight();
            ret.imageFormat = imageReaderOutputConfig.getImageFormat();
            ret.capacity = imageReaderOutputConfig.getMaxImages();
        } else if (output instanceof MultiResolutionImageReaderOutputConfigImpl) {
            MultiResolutionImageReaderOutputConfigImpl multiResReaderConfig =
                    (MultiResolutionImageReaderOutputConfigImpl) output;
            ret.type = CameraOutputConfig.TYPE_MULTIRES_IMAGEREADER;
            ret.imageFormat = multiResReaderConfig.getImageFormat();
            ret.capacity = multiResReaderConfig.getMaxImages();
        } else {
            throw new IllegalStateException("Unknown output config type!");
        }

        return ret;
    }
}