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
This commit is contained in:
Emilian Peev
2022-05-05 15:28:08 -07:00
parent 46e3f92171
commit c7f3fa1920
3 changed files with 83 additions and 81 deletions

View File

@@ -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;
}

View File

@@ -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<>();
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!");
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);
}
ArrayList<OutputConfiguration> outputList = new ArrayList<>();
for (CameraOutputConfig output : outputConfigs) {
if (!cameraOutputs.containsKey(output.outputId.id)) {
// Shared surface already removed by a previous iteration
Surface outputSurface = initializeSurfrace(output);
if (outputSurface == 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);
OutputConfiguration cameraOutput = new OutputConfiguration(output.surfaceGroupId,
outputSurface);
if ((output.sharedSurfaceConfigs != null) && !output.sharedSurfaceConfigs.isEmpty()) {
cameraOutput.enableSurfaceSharing();
for (CameraOutputConfig sharedOutputConfig : output.sharedSurfaceConfigs) {
Surface sharedSurface = initializeSurfrace(sharedOutputConfig);
if (sharedSurface == null) {
continue;
}
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);
}
}
}

View File

@@ -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;
}
}