Camera: Add per-surface mirroring mode
Add the support to do per output surface mirror mode. Previously
mirroring mode is set per OutputConfiguration, which could contain
multiple shared surfaces.
Flag: com.android.internal.camera.flags.mirror_mode_shared_surfaces
Test: atest MultiViewTest
Bug: 298899993
Change-Id: I3654cb585d243365b62a10131c21a869af754e73
diff --git a/camera/camera2/OutputConfiguration.cpp b/camera/camera2/OutputConfiguration.cpp
index 2d1af32..48a7338 100644
--- a/camera/camera2/OutputConfiguration.cpp
+++ b/camera/camera2/OutputConfiguration.cpp
@@ -22,12 +22,14 @@
#include <camera/camera2/OutputConfiguration.h>
#include <camera/StringUtils.h>
+#include <com_android_internal_camera_flags.h>
#include <binder/Parcel.h>
#include <gui/view/Surface.h>
#include <system/camera_metadata.h>
#include <system/graphics.h>
#include <utils/String8.h>
+namespace flags = com::android::internal::camera::flags;
namespace android {
@@ -95,7 +97,21 @@
return mTimestampBase;
}
-int OutputConfiguration::getMirrorMode() const {
+int OutputConfiguration::getMirrorMode(sp<IGraphicBufferProducer> surface) const {
+ if (!flags::mirror_mode_shared_surfaces()) {
+ return mMirrorMode;
+ }
+
+ // Use per-producer mirror mode if available.
+ for (size_t i = 0; i < mGbps.size(); i++) {
+ if (mGbps[i] == surface) {
+ return mMirrorModeForProducers[i];
+ }
+ }
+
+ // For surface that doesn't belong to this output configuration, use
+ // mMirrorMode as default.
+ ALOGW("%s: Surface doesn't belong to this OutputConfiguration!", __FUNCTION__);
return mMirrorMode;
}
@@ -251,6 +267,12 @@
return err;
}
+ std::vector<int> mirrorModeForProducers;
+ if ((err = parcel->readInt32Vector(&mirrorModeForProducers)) != OK) {
+ ALOGE("%s: Failed to read mirroring mode for surfaces from parcel", __FUNCTION__);
+ return err;
+ }
+
int useReadoutTimestamp = 0;
if ((err = parcel->readInt32(&useReadoutTimestamp)) != OK) {
ALOGE("%s: Failed to read useReadoutTimestamp flag from parcel", __FUNCTION__);
@@ -286,6 +308,7 @@
mStreamUseCase = streamUseCase;
mTimestampBase = timestampBase;
mMirrorMode = mirrorMode;
+ mMirrorModeForProducers = std::move(mirrorModeForProducers);
mUseReadoutTimestamp = useReadoutTimestamp != 0;
for (auto& surface : surfaceShims) {
ALOGV("%s: OutputConfiguration: %p, name %s", __FUNCTION__,
@@ -409,6 +432,9 @@
err = parcel->writeInt32(mMirrorMode);
if (err != OK) return err;
+ err = parcel->writeInt32Vector(mMirrorModeForProducers);
+ if (err != OK) return err;
+
err = parcel->writeInt32(mUseReadoutTimestamp ? 1 : 0);
if (err != OK) return err;
@@ -438,6 +464,20 @@
return true;
}
+template <typename T>
+static bool simpleVectorsLessThan(T first, T second) {
+ if (first.size() != second.size()) {
+ return first.size() < second.size();
+ }
+
+ for (size_t i = 0; i < first.size(); i++) {
+ if (first[i] != second[i]) {
+ return first[i] < second[i];
+ }
+ }
+ return false;
+}
+
bool OutputConfiguration::gbpsEqual(const OutputConfiguration& other) const {
const std::vector<sp<IGraphicBufferProducer> >& otherGbps =
other.getGraphicBufferProducers();
@@ -449,20 +489,20 @@
return simpleVectorsEqual(othersensorPixelModesUsed, mSensorPixelModesUsed);
}
+bool OutputConfiguration::mirrorModesEqual(const OutputConfiguration& other) const {
+ const std::vector<int>& otherMirrorModes = other.getMirrorModes();
+ return simpleVectorsEqual(otherMirrorModes, mMirrorModeForProducers);
+
+}
+
bool OutputConfiguration::sensorPixelModesUsedLessThan(const OutputConfiguration& other) const {
const std::vector<int32_t>& spms = other.getSensorPixelModesUsed();
+ return simpleVectorsLessThan(mSensorPixelModesUsed, spms);
+}
- if (mSensorPixelModesUsed.size() != spms.size()) {
- return mSensorPixelModesUsed.size() < spms.size();
- }
-
- for (size_t i = 0; i < spms.size(); i++) {
- if (mSensorPixelModesUsed[i] != spms[i]) {
- return mSensorPixelModesUsed[i] < spms[i];
- }
- }
-
- return false;
+bool OutputConfiguration::mirrorModesLessThan(const OutputConfiguration& other) const {
+ const std::vector<int>& otherMirrorModes = other.getMirrorModes();
+ return simpleVectorsLessThan(mMirrorModeForProducers, otherMirrorModes);
}
bool OutputConfiguration::gbpsLessThan(const OutputConfiguration& other) const {
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index 8e53ca0..cabfbc4 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -178,3 +178,11 @@
description: "Pass the full AttributionSource chain to PermissionChecker"
bug: "190657833"
}
+
+flag {
+ namespace: "camera_platform"
+ name: "mirror_mode_shared_surfaces"
+ is_exported: true
+ description: "Support setting and getting mirror mode for shared surfaces"
+ bug: "298899993"
+}
diff --git a/camera/include/camera/camera2/OutputConfiguration.h b/camera/include/camera/camera2/OutputConfiguration.h
index 83ce39d..2049a31 100644
--- a/camera/include/camera/camera2/OutputConfiguration.h
+++ b/camera/include/camera/camera2/OutputConfiguration.h
@@ -72,7 +72,7 @@
bool isMultiResolution() const;
int64_t getStreamUseCase() const;
int getTimestampBase() const;
- int getMirrorMode() const;
+ int getMirrorMode(sp<IGraphicBufferProducer> surface) const;
bool useReadoutTimestamp() const;
int getFormat() const;
int getDataspace() const;
@@ -125,6 +125,7 @@
mStreamUseCase == other.mStreamUseCase &&
mTimestampBase == other.mTimestampBase &&
mMirrorMode == other.mMirrorMode &&
+ mirrorModesEqual(other) &&
mUseReadoutTimestamp == other.mUseReadoutTimestamp &&
mFormat == other.mFormat &&
mDataspace == other.mDataspace &&
@@ -180,6 +181,9 @@
if (mMirrorMode != other.mMirrorMode) {
return mMirrorMode < other.mMirrorMode;
}
+ if (!mirrorModesEqual(other)) {
+ return mirrorModesLessThan(other);
+ }
if (mUseReadoutTimestamp != other.mUseReadoutTimestamp) {
return mUseReadoutTimestamp < other.mUseReadoutTimestamp;
}
@@ -204,6 +208,9 @@
bool sensorPixelModesUsedLessThan(const OutputConfiguration& other) const;
bool gbpsLessThan(const OutputConfiguration& other) const;
void addGraphicProducer(sp<IGraphicBufferProducer> gbp) {mGbps.push_back(gbp);}
+ bool mirrorModesEqual(const OutputConfiguration& other) const;
+ bool mirrorModesLessThan(const OutputConfiguration& other) const;
+ const std::vector<int32_t>& getMirrorModes() const {return mMirrorModeForProducers;}
private:
std::vector<sp<IGraphicBufferProducer>> mGbps;
int mRotation;
@@ -221,6 +228,7 @@
int64_t mStreamUseCase;
int mTimestampBase;
int mMirrorMode;
+ std::vector<int> mMirrorModeForProducers; // 1:1 mapped with mGbps
bool mUseReadoutTimestamp;
int mFormat;
int mDataspace;
diff --git a/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp b/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp
index 7046075..b6fa817 100644
--- a/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp
+++ b/camera/tests/fuzzer/camera_c2OutputConfiguration_fuzzer.cpp
@@ -120,7 +120,10 @@
[&]() { outputConfiguration->getColorSpace(); },
[&]() { outputConfiguration->getStreamUseCase(); },
[&]() { outputConfiguration->getTimestampBase(); },
- [&]() { outputConfiguration->getMirrorMode(); },
+ [&]() {
+ sp<IGraphicBufferProducer> gbp = createIGraphicBufferProducer();
+ outputConfiguration->getMirrorMode(gbp);
+ },
[&]() { outputConfiguration->useReadoutTimestamp(); },
});
callC2OutputConfAPIs();
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index f469aad..bacbfaf 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -908,7 +908,6 @@
int64_t dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
int64_t streamUseCase = outputConfiguration.getStreamUseCase();
int timestampBase = outputConfiguration.getTimestampBase();
- int mirrorMode = outputConfiguration.getMirrorMode();
int32_t colorSpace = outputConfiguration.getColorSpace();
bool useReadoutTimestamp = outputConfiguration.useReadoutTimestamp();
@@ -927,7 +926,7 @@
return res;
}
- std::vector<sp<Surface>> surfaces;
+ std::vector<SurfaceHolder> surfaces;
std::vector<sp<IBinder>> binders;
status_t err;
@@ -952,6 +951,7 @@
return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.c_str());
}
+ int mirrorMode = outputConfiguration.getMirrorMode(bufferProducer);
sp<Surface> surface;
res = SessionConfigurationUtils::createSurfaceFromGbp(streamInfo,
isStreamInfoValid, surface, bufferProducer, mCameraIdStr,
@@ -966,7 +966,7 @@
}
binders.push_back(IInterface::asBinder(bufferProducer));
- surfaces.push_back(surface);
+ surfaces.push_back({surface, mirrorMode});
}
// If mOverrideForPerfClass is true, do not fail createStream() for small
@@ -976,10 +976,11 @@
int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
std::vector<int> surfaceIds;
bool isDepthCompositeStream =
- camera3::DepthCompositeStream::isDepthCompositeStream(surfaces[0]);
- bool isHeicCompositeStream = camera3::HeicCompositeStream::isHeicCompositeStream(surfaces[0]);
+ camera3::DepthCompositeStream::isDepthCompositeStream(surfaces[0].mSurface);
+ bool isHeicCompositeStream = camera3::HeicCompositeStream::isHeicCompositeStream(
+ surfaces[0].mSurface);
bool isJpegRCompositeStream =
- camera3::JpegRCompositeStream::isJpegRCompositeStream(surfaces[0]) &&
+ camera3::JpegRCompositeStream::isJpegRCompositeStream(surfaces[0].mSurface) &&
!mDevice->isCompositeJpegRDisabled();
if (isDepthCompositeStream || isHeicCompositeStream || isJpegRCompositeStream) {
sp<CompositeStream> compositeStream;
@@ -1000,7 +1001,8 @@
useReadoutTimestamp);
if (err == OK) {
Mutex::Autolock l(mCompositeLock);
- mCompositeStreamMap.add(IInterface::asBinder(surfaces[0]->getIGraphicBufferProducer()),
+ mCompositeStreamMap.add(
+ IInterface::asBinder(surfaces[0].mSurface->getIGraphicBufferProducer()),
compositeStream);
}
} else {
@@ -1010,8 +1012,7 @@
&streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution,
/*consumerUsage*/0, streamInfo.dynamicRangeProfile, streamInfo.streamUseCase,
- streamInfo.timestampBase, streamInfo.mirrorMode, streamInfo.colorSpace,
- useReadoutTimestamp);
+ streamInfo.timestampBase, streamInfo.colorSpace, useReadoutTimestamp);
}
if (err != OK) {
@@ -1036,9 +1037,6 @@
__FUNCTION__, mCameraIdStr.c_str(), streamId, streamInfo.width,
streamInfo.height, streamInfo.format);
- // Set transform flags to ensure preview to be rotated correctly.
- res = setStreamTransformLocked(streamId, streamInfo.mirrorMode);
-
// Fill in mHighResolutionCameraIdToStreamIdSet map
const std::string &cameraIdUsed =
physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
@@ -1087,7 +1085,7 @@
consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
}
int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
- std::vector<sp<Surface>> noSurface;
+ std::vector<SurfaceHolder> noSurface;
std::vector<int> surfaceIds;
const std::string &physicalCameraId = outputConfiguration.getPhysicalCameraId();
const std::string &cameraIdUsed =
@@ -1113,7 +1111,6 @@
outputConfiguration.isMultiResolution(), consumerUsage,
outputConfiguration.getDynamicRangeProfile(),
outputConfiguration.getStreamUseCase(),
- outputConfiguration.getMirrorMode(),
outputConfiguration.useReadoutTimestamp());
if (err != OK) {
@@ -1132,16 +1129,12 @@
outputConfiguration.getDynamicRangeProfile(),
outputConfiguration.getStreamUseCase(),
outputConfiguration.getTimestampBase(),
- outputConfiguration.getMirrorMode(),
colorSpace));
ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
" (%d x %d) stream with format 0x%x.",
__FUNCTION__, mCameraIdStr.c_str(), streamId, width, height, format);
- // Set transform flags to ensure preview to be rotated correctly.
- res = setStreamTransformLocked(streamId, outputConfiguration.getMirrorMode());
-
*newStreamId = streamId;
// Fill in mHighResolutionCameraIdToStreamIdSet
// Only needed for high resolution sensors
@@ -1153,33 +1146,6 @@
return res;
}
-binder::Status CameraDeviceClient::setStreamTransformLocked(int streamId, int mirrorMode) {
- int32_t transform = 0;
- status_t err;
- binder::Status res;
-
- if (!mDevice.get()) {
- return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
- }
-
- err = getRotationTransformLocked(mirrorMode, &transform);
- if (err != OK) {
- // Error logged by getRotationTransformLocked.
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
- "Unable to calculate rotation transform for new stream");
- }
-
- err = mDevice->setStreamTransform(streamId, transform);
- if (err != OK) {
- std::string msg = fmt::sprintf("Failed to set stream transform (stream id %d)",
- streamId);
- ALOGE("%s: %s", __FUNCTION__, msg.c_str());
- return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.c_str());
- }
-
- return res;
-}
-
binder::Status CameraDeviceClient::createInputStream(
int width, int height, int format, bool isMultiResolution,
/*out*/
@@ -1312,7 +1278,7 @@
std::vector<size_t> removedSurfaceIds;
std::vector<sp<IBinder>> removedOutputs;
- std::vector<sp<Surface>> newOutputs;
+ std::vector<SurfaceHolder> newOutputs;
std::vector<OutputStreamInfo> streamInfos;
KeyedVector<sp<IBinder>, sp<IGraphicBufferProducer>> newOutputsMap;
for (auto &it : bufferProducers) {
@@ -1341,11 +1307,11 @@
int timestampBase = outputConfiguration.getTimestampBase();
int64_t dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
int32_t colorSpace = outputConfiguration.getColorSpace();
- int mirrorMode = outputConfiguration.getMirrorMode();
for (size_t i = 0; i < newOutputsMap.size(); i++) {
OutputStreamInfo outInfo;
sp<Surface> surface;
+ int mirrorMode = outputConfiguration.getMirrorMode(newOutputsMap.valueAt(i));
res = SessionConfigurationUtils::createSurfaceFromGbp(outInfo,
/*isStreamInfoValid*/ false, surface, newOutputsMap.valueAt(i), mCameraIdStr,
mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
@@ -1354,7 +1320,7 @@
return res;
streamInfos.push_back(outInfo);
- newOutputs.push_back(surface);
+ newOutputs.push_back({surface, mirrorMode});
}
//Trivial case no changes required
@@ -1711,14 +1677,13 @@
return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
}
- std::vector<sp<Surface>> consumerSurfaces;
+ std::vector<SurfaceHolder> consumerSurfaceHolders;
const std::vector<int32_t> &sensorPixelModesUsed =
outputConfiguration.getSensorPixelModesUsed();
int64_t dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
int32_t colorSpace = outputConfiguration.getColorSpace();
int64_t streamUseCase = outputConfiguration.getStreamUseCase();
int timestampBase = outputConfiguration.getTimestampBase();
- int mirrorMode = outputConfiguration.getMirrorMode();
for (auto& bufferProducer : bufferProducers) {
// Don't create multiple streams for the same target surface
ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
@@ -1729,6 +1694,7 @@
}
sp<Surface> surface;
+ int mirrorMode = outputConfiguration.getMirrorMode(bufferProducer);
res = SessionConfigurationUtils::createSurfaceFromGbp(mStreamInfoMap[streamId],
true /*isStreamInfoValid*/, surface, bufferProducer, mCameraIdStr,
mDevice->infoPhysical(physicalId), sensorPixelModesUsed, dynamicRangeProfile,
@@ -1737,12 +1703,12 @@
if (!res.isOk())
return res;
- consumerSurfaces.push_back(surface);
+ consumerSurfaceHolders.push_back({surface, mirrorMode});
}
// Gracefully handle case where finalizeOutputConfigurations is called
// without any new surface.
- if (consumerSurfaces.size() == 0) {
+ if (consumerSurfaceHolders.size() == 0) {
mStreamInfoMap[streamId].finalized = true;
return res;
}
@@ -1750,11 +1716,11 @@
// Finish the deferred stream configuration with the surface.
status_t err;
std::vector<int> consumerSurfaceIds;
- err = mDevice->setConsumerSurfaces(streamId, consumerSurfaces, &consumerSurfaceIds);
+ err = mDevice->setConsumerSurfaces(streamId, consumerSurfaceHolders, &consumerSurfaceIds);
if (err == OK) {
- for (size_t i = 0; i < consumerSurfaces.size(); i++) {
+ for (size_t i = 0; i < consumerSurfaceHolders.size(); i++) {
sp<IBinder> binder = IInterface::asBinder(
- consumerSurfaces[i]->getIGraphicBufferProducer());
+ consumerSurfaceHolders[i].mSurface->getIGraphicBufferProducer());
ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %d", __FUNCTION__,
binder.get(), streamId, consumerSurfaceIds[i]);
mStreamMap.add(binder, StreamSurfaceId(streamId, consumerSurfaceIds[i]));
@@ -2271,14 +2237,6 @@
return true;
}
-status_t CameraDeviceClient::getRotationTransformLocked(int mirrorMode,
- int32_t* transform) {
- ALOGV("%s: begin", __FUNCTION__);
-
- const CameraMetadata& staticInfo = mDevice->info();
- return CameraUtils::getRotationTransform(staticInfo, mirrorMode, transform);
-}
-
const CameraMetadata &CameraDeviceClient::getStaticInfo(const std::string &cameraId) {
if (mDevice->getId() == cameraId) {
return mDevice->info();
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 42f2752..912577d 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -247,9 +247,6 @@
virtual void onResultAvailable(const CaptureResult& result);
virtual void detachDevice();
- // Calculate the ANativeWindow transform from android.sensor.orientation
- status_t getRotationTransformLocked(int mirrorMode, /*out*/int32_t* transform);
-
bool supportsUltraHighResolutionCapture(const std::string &cameraId);
bool isSensorPixelModeConsistent(const std::list<int> &streamIdList,
@@ -306,10 +303,6 @@
bool isShared,
int* newStreamId = NULL);
- // Set the stream transform flags to automatically rotate the camera stream for preview use
- // cases.
- binder::Status setStreamTransformLocked(int streamId, int mirrorMode);
-
// Utility method to insert the surface into SurfaceMap
binder::Status insertGbpLocked(const sp<IGraphicBufferProducer>& gbp,
/*out*/SurfaceMap* surfaceMap, /*out*/Vector<int32_t>* streamIds,
diff --git a/services/camera/libcameraservice/api2/CompositeStream.cpp b/services/camera/libcameraservice/api2/CompositeStream.cpp
index 8f53458..6d7fabd 100644
--- a/services/camera/libcameraservice/api2/CompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/CompositeStream.cpp
@@ -44,7 +44,7 @@
}
}
-status_t CompositeStream::createStream(const std::vector<sp<Surface>>& consumers,
+status_t CompositeStream::createStream(const std::vector<SurfaceHolder>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
camera_stream_rotation_t rotation, int * id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
diff --git a/services/camera/libcameraservice/api2/CompositeStream.h b/services/camera/libcameraservice/api2/CompositeStream.h
index fa569ce..2b158c9 100644
--- a/services/camera/libcameraservice/api2/CompositeStream.h
+++ b/services/camera/libcameraservice/api2/CompositeStream.h
@@ -41,7 +41,7 @@
CompositeStream(sp<CameraDeviceBase> device, wp<hardware::camera2::ICameraDeviceCallbacks> cb);
virtual ~CompositeStream() {}
- status_t createStream(const std::vector<sp<Surface>>& consumers,
+ status_t createStream(const std::vector<SurfaceHolder>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
@@ -55,7 +55,7 @@
void switchToOffline();
// Create and register all internal camera streams.
- virtual status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
+ virtual status_t createInternalStreams(const std::vector<SurfaceHolder>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
index 244a1e5..14618c4 100644
--- a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp
@@ -588,7 +588,7 @@
}
-status_t DepthCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
+status_t DepthCompositeStream::createInternalStreams(const std::vector<SurfaceHolder>& consumers,
bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
@@ -643,7 +643,7 @@
if (ret == OK) {
mBlobStreamId = *id;
mBlobSurfaceId = (*surfaceIds)[0];
- mOutputSurface = consumers[0];
+ mOutputSurface = consumers[0].mSurface;
} else {
return ret;
}
diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.h b/services/camera/libcameraservice/api2/DepthCompositeStream.h
index 75deef7..9c0311e 100644
--- a/services/camera/libcameraservice/api2/DepthCompositeStream.h
+++ b/services/camera/libcameraservice/api2/DepthCompositeStream.h
@@ -49,7 +49,7 @@
static bool isDepthCompositeStreamInfo(const OutputStreamInfo& streamInfo);
// CompositeStream overrides
- status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
+ status_t createInternalStreams(const std::vector<SurfaceHolder>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 3af673b..0f4ba65 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -123,7 +123,7 @@
return ((format == HAL_PIXEL_FORMAT_BLOB) && (dataspace == HAL_DATASPACE_HEIF));
}
-status_t HeicCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
+status_t HeicCompositeStream::createInternalStreams(const std::vector<SurfaceHolder>& consumers,
bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
@@ -228,7 +228,7 @@
return res;
}
- mOutputSurface = consumers[0];
+ mOutputSurface = consumers[0].mSurface;
res = registerCompositeStreamListener(mMainImageStreamId);
if (res != OK) {
ALOGE("%s: Failed to register HAL main image stream: %s (%d)", __FUNCTION__,
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.h b/services/camera/libcameraservice/api2/HeicCompositeStream.h
index ba10e05..fad968a 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.h
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.h
@@ -43,7 +43,7 @@
static bool isHeicCompositeStream(const sp<Surface> &surface);
static bool isHeicCompositeStreamInfo(const OutputStreamInfo& streamInfo);
- status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
+ status_t createInternalStreams(const std::vector<SurfaceHolder>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
diff --git a/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp b/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
index c5bd7a9..e0d7604 100644
--- a/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/JpegRCompositeStream.cpp
@@ -557,7 +557,7 @@
}
-status_t JpegRCompositeStream::createInternalStreams(const std::vector<sp<Surface>>& consumers,
+status_t JpegRCompositeStream::createInternalStreams(const std::vector<SurfaceHolder>& consumers,
bool /*hasDeferredConsumer*/, uint32_t width, uint32_t height, int format,
camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
@@ -600,7 +600,7 @@
if (ret == OK) {
mP010StreamId = *id;
mP010SurfaceId = (*surfaceIds)[0];
- mOutputSurface = consumers[0];
+ mOutputSurface = consumers[0].mSurface;
} else {
return ret;
}
diff --git a/services/camera/libcameraservice/api2/JpegRCompositeStream.h b/services/camera/libcameraservice/api2/JpegRCompositeStream.h
index d3ab19c..efd31da 100644
--- a/services/camera/libcameraservice/api2/JpegRCompositeStream.h
+++ b/services/camera/libcameraservice/api2/JpegRCompositeStream.h
@@ -46,7 +46,7 @@
static bool isJpegRCompositeStreamInfo(const OutputStreamInfo& streamInfo);
// CompositeStream overrides
- status_t createInternalStreams(const std::vector<sp<Surface>>& consumers,
+ status_t createInternalStreams(const std::vector<SurfaceHolder>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
camera_stream_rotation_t rotation, int *id, const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 9c8f5ad..f5e960b 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -68,6 +68,7 @@
using camera3::camera_request_template_t;;
using camera3::camera_stream_configuration_mode_t;
using camera3::camera_stream_rotation_t;
+using camera3::SurfaceHolder;
class CameraProviderManager;
@@ -200,7 +201,7 @@
* For HAL_PIXEL_FORMAT_BLOB formats, the width and height should be the
* logical dimensions of the buffer, not the number of bytes.
*/
- virtual status_t createStream(const std::vector<sp<Surface>>& consumers,
+ virtual status_t createStream(const std::vector<SurfaceHolder>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
const std::string& physicalCameraId,
@@ -212,7 +213,6 @@
int64_t dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
int64_t streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT,
- int mirrorMode = OutputConfiguration::MIRROR_MODE_AUTO,
int32_t colorSpace = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED,
bool useReadoutTimestamp = false)
= 0;
@@ -404,12 +404,12 @@
* Set the deferred consumer surface and finish the rest of the stream configuration.
*/
virtual status_t setConsumerSurfaces(int streamId,
- const std::vector<sp<Surface>>& consumers, std::vector<int> *surfaceIds /*out*/) = 0;
+ const std::vector<SurfaceHolder>& consumers, std::vector<int> *surfaceIds /*out*/) = 0;
/**
* Update a given stream.
*/
- virtual status_t updateStream(int streamId, const std::vector<sp<Surface>> &newSurfaces,
+ virtual status_t updateStream(int streamId, const std::vector<SurfaceHolder> &newSurfaces,
const std::vector<android::camera3::OutputStreamInfo> &outputInfo,
const std::vector<size_t> &removedSurfaceIds,
KeyedVector<sp<Surface>, size_t> *outputMap/*out*/) = 0;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 5721745..eb8cb9d 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -50,6 +50,7 @@
#include <utils/Trace.h>
#include <utils/Timers.h>
#include <cutils/properties.h>
+#include <camera/CameraUtils.h>
#include <camera/StringUtils.h>
#include <android-base/properties.h>
@@ -1046,13 +1047,13 @@
return BAD_VALUE;
}
- std::vector<sp<Surface>> consumers;
- consumers.push_back(consumer);
+ std::vector<SurfaceHolder> consumers;
+ consumers.push_back(SurfaceHolder{consumer, mirrorMode});
return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
format, dataSpace, rotation, id, physicalCameraId, sensorPixelModesUsed, surfaceIds,
streamSetId, isShared, isMultiResolution, consumerUsage, dynamicRangeProfile,
- streamUseCase, timestampBase, mirrorMode, colorSpace, useReadoutTimestamp);
+ streamUseCase, timestampBase, colorSpace, useReadoutTimestamp);
}
static bool isRawFormat(int format) {
@@ -1067,14 +1068,14 @@
}
}
-status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
+status_t Camera3Device::createStream(const std::vector<SurfaceHolder>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed,
std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
uint64_t consumerUsage, int64_t dynamicRangeProfile, int64_t streamUseCase,
- int timestampBase, int mirrorMode, int32_t colorSpace, bool useReadoutTimestamp) {
+ int timestampBase, int32_t colorSpace, bool useReadoutTimestamp) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
@@ -1083,10 +1084,10 @@
ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
" consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d"
" dynamicRangeProfile 0x%" PRIx64 ", streamUseCase %" PRId64 ", timestampBase %d,"
- " mirrorMode %d, colorSpace %d, useReadoutTimestamp %d",
+ " colorSpace %d, useReadoutTimestamp %d",
mId.c_str(), mNextStreamId, width, height, format, dataSpace, rotation,
consumerUsage, isShared, physicalCameraId.c_str(), isMultiResolution,
- dynamicRangeProfile, streamUseCase, timestampBase, mirrorMode, colorSpace,
+ dynamicRangeProfile, streamUseCase, timestampBase, colorSpace,
useReadoutTimestamp);
status_t res;
@@ -1155,11 +1156,11 @@
return BAD_VALUE;
}
}
- newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
+ newStream = new Camera3OutputStream(mNextStreamId, consumers[0].mSurface,
width, height, blobBufferSize, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, transport, streamSetId,
isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
- timestampBase, mirrorMode, colorSpace, useReadoutTimestamp);
+ timestampBase, consumers[0].mMirrorMode, colorSpace, useReadoutTimestamp);
} else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
bool maxResolution =
sensorPixelModesUsed.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
@@ -1170,34 +1171,34 @@
SET_ERR_L("Invalid RAW opaque buffer size %zd", rawOpaqueBufferSize);
return BAD_VALUE;
}
- newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
+ newStream = new Camera3OutputStream(mNextStreamId, consumers[0].mSurface,
width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, transport, streamSetId,
isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
- timestampBase, mirrorMode, colorSpace, useReadoutTimestamp);
+ timestampBase, consumers[0].mMirrorMode, colorSpace, useReadoutTimestamp);
} else if (isShared) {
newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, transport, streamSetId,
mUseHalBufManager, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
- timestampBase, mirrorMode, colorSpace, useReadoutTimestamp);
+ timestampBase, colorSpace, useReadoutTimestamp);
} else if (consumers.size() == 0 && hasDeferredConsumer) {
newStream = new Camera3OutputStream(mNextStreamId,
width, height, format, consumerUsage, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, transport, streamSetId,
isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
- timestampBase, mirrorMode, colorSpace, useReadoutTimestamp);
+ timestampBase, colorSpace, useReadoutTimestamp);
} else {
- newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
+ newStream = new Camera3OutputStream(mNextStreamId, consumers[0].mSurface,
width, height, format, dataSpace, rotation,
mTimestampOffset, physicalCameraId, sensorPixelModesUsed, transport, streamSetId,
isMultiResolution, dynamicRangeProfile, streamUseCase, mDeviceTimeBaseIsRealtime,
- timestampBase, mirrorMode, colorSpace, useReadoutTimestamp);
+ timestampBase, consumers[0].mMirrorMode, colorSpace, useReadoutTimestamp);
}
size_t consumerCount = consumers.size();
for (size_t i = 0; i < consumerCount; i++) {
- int id = newStream->getSurfaceId(consumers[i]);
+ int id = newStream->getSurfaceId(consumers[i].mSurface);
if (id < 0) {
SET_ERR_L("Invalid surface id");
return BAD_VALUE;
@@ -1205,6 +1206,11 @@
if (surfaceIds != nullptr) {
surfaceIds->push_back(id);
}
+
+ res = deriveAndSetTransformLocked(*newStream, consumers[i].mMirrorMode, id);
+ if (res < 0) {
+ return res;
+ }
}
newStream->setStatusTracker(mStatusTracker);
@@ -2038,7 +2044,7 @@
}
status_t Camera3Device::setConsumerSurfaces(int streamId,
- const std::vector<sp<Surface>>& consumers, std::vector<int> *surfaceIds) {
+ const std::vector<SurfaceHolder>& consumers, std::vector<int> *surfaceIds) {
ATRACE_CALL();
ALOGV("%s: Camera %s: set consumer surface for stream %d",
__FUNCTION__, mId.c_str(), streamId);
@@ -2070,12 +2076,17 @@
}
for (auto &consumer : consumers) {
- int id = stream->getSurfaceId(consumer);
+ int id = stream->getSurfaceId(consumer.mSurface);
if (id < 0) {
CLOGE("Invalid surface id!");
return BAD_VALUE;
}
surfaceIds->push_back(id);
+
+ res = deriveAndSetTransformLocked(*stream, consumer.mMirrorMode, id);
+ if (res != OK) {
+ return res;
+ }
}
if (isDeferred) {
@@ -2101,7 +2112,7 @@
return OK;
}
-status_t Camera3Device::updateStream(int streamId, const std::vector<sp<Surface>> &newSurfaces,
+status_t Camera3Device::updateStream(int streamId, const std::vector<SurfaceHolder> &newSurfaces,
const std::vector<OutputStreamInfo> &outputInfo,
const std::vector<size_t> &removedSurfaceIds, KeyedVector<sp<Surface>, size_t> *outputMap) {
Mutex::Autolock il(mInterfaceLock);
@@ -2131,6 +2142,14 @@
return res;
}
+ for (size_t i = 0; i < outputMap->size(); i++) {
+ res = deriveAndSetTransformLocked(
+ *stream, newSurfaces[i].mMirrorMode, outputMap->valueAt(i));
+ if (res != OK) {
+ return res;
+ }
+ }
+
return res;
}
@@ -5786,4 +5805,15 @@
}
}
+status_t Camera3Device::deriveAndSetTransformLocked(
+ Camera3OutputStreamInterface& stream, int mirrorMode, int surfaceId) {
+ int transform = -1;
+ int res = CameraUtils::getRotationTransform(mDeviceInfo, mirrorMode, &transform);
+ if (res != OK) {
+ return res;
+ }
+ stream.setTransform(transform, false /*mayChangeMirror*/, surfaceId);
+ return OK;
+}
+
}; // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 3c45c1a..397ec5c 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -63,6 +63,7 @@
using android::camera3::camera_stream_configuration_mode_t;
using android::camera3::CAMERA_TEMPLATE_COUNT;
using android::camera3::OutputStreamInfo;
+using android::camera3::SurfaceHolder;
namespace android {
@@ -168,7 +169,7 @@
bool useReadoutTimestamp = false)
override;
- status_t createStream(const std::vector<sp<Surface>>& consumers,
+ status_t createStream(const std::vector<SurfaceHolder>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
const std::string& physicalCameraId,
@@ -181,7 +182,6 @@
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
int64_t streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT,
- int mirrorMode = OutputConfiguration::MIRROR_MODE_AUTO,
int32_t colorSpace = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED,
bool useReadoutTimestamp = false)
override;
@@ -247,13 +247,13 @@
* consumer configuration.
*/
status_t setConsumerSurfaces(
- int streamId, const std::vector<sp<Surface>>& consumers,
+ int streamId, const std::vector<SurfaceHolder>& consumers,
std::vector<int> *surfaceIds /*out*/) override;
/**
* Update a given stream.
*/
- status_t updateStream(int streamId, const std::vector<sp<Surface>> &newSurfaces,
+ status_t updateStream(int streamId, const std::vector<SurfaceHolder> &newSurfaces,
const std::vector<OutputStreamInfo> &outputInfo,
const std::vector<size_t> &removedSurfaceIds,
KeyedVector<sp<Surface>, size_t> *outputMap/*out*/);
@@ -1644,6 +1644,8 @@
sp<Camera3DeviceInjectionMethods> mInjectionMethods;
void overrideStreamUseCaseLocked();
+ status_t deriveAndSetTransformLocked(camera3::Camera3OutputStreamInterface& stream,
+ int mirrorMode, int surfaceId);
}; // class Camera3Device
diff --git a/services/camera/libcameraservice/device3/Camera3FakeStream.cpp b/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
index 55467c3..79b88f8 100644
--- a/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3FakeStream.cpp
@@ -76,7 +76,7 @@
Camera3IOStreamBase::dump(fd, args);
}
-status_t Camera3FakeStream::setTransform(int, bool) {
+status_t Camera3FakeStream::setTransform(int, bool, int) {
ATRACE_CALL();
// Do nothing
return OK;
@@ -120,13 +120,13 @@
return FAKE_ID;
}
-status_t Camera3FakeStream::setConsumers(const std::vector<sp<Surface>>& /*consumers*/) {
+status_t Camera3FakeStream::setConsumers(const std::vector<SurfaceHolder>& /*consumers*/) {
ALOGE("%s: Stream %d: Fake stream doesn't support set consumer surface!",
__FUNCTION__, mId);
return INVALID_OPERATION;
}
-status_t Camera3FakeStream::updateStream(const std::vector<sp<Surface>> &/*outputSurfaces*/,
+status_t Camera3FakeStream::updateStream(const std::vector<SurfaceHolder> &/*outputSurfaces*/,
const std::vector<OutputStreamInfo> &/*outputInfo*/,
const std::vector<size_t> &/*removedSurfaceIds*/,
KeyedVector<sp<Surface>, size_t> * /*outputMap*/) {
diff --git a/services/camera/libcameraservice/device3/Camera3FakeStream.h b/services/camera/libcameraservice/device3/Camera3FakeStream.h
index 7addb90..9291bd0 100644
--- a/services/camera/libcameraservice/device3/Camera3FakeStream.h
+++ b/services/camera/libcameraservice/device3/Camera3FakeStream.h
@@ -52,7 +52,7 @@
virtual void dump(int fd, const Vector<String16> &args);
- status_t setTransform(int transform, bool mayChangeMirror);
+ status_t setTransform(int transform, bool mayChangeMirror, int surfaceId);
virtual status_t detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd);
@@ -80,7 +80,7 @@
/**
* Set the consumer surfaces to the output stream.
*/
- virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers);
+ virtual status_t setConsumers(const std::vector<SurfaceHolder>& consumers);
/**
* Query the output surface id.
@@ -93,7 +93,7 @@
/**
* Update the stream output surfaces.
*/
- virtual status_t updateStream(const std::vector<sp<Surface>> &outputSurfaces,
+ virtual status_t updateStream(const std::vector<SurfaceHolder> &outputSurfaces,
const std::vector<OutputStreamInfo> &outputInfo,
const std::vector<size_t> &removedSurfaceIds,
KeyedVector<sp<Surface>, size_t> *outputMap/*out*/);
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 83c8a38..dc663f3 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -136,7 +136,7 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
- int mirrorMode, int32_t colorSpace, bool useReadoutTimestamp) :
+ int32_t colorSpace, bool useReadoutTimestamp) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
@@ -150,7 +150,7 @@
mUseReadoutTime(useReadoutTimestamp),
mConsumerUsage(consumerUsage),
mDropBuffers(false),
- mMirrorMode(mirrorMode),
+ mMirrorMode(OutputConfiguration::MIRROR_MODE_AUTO),
mDequeueBufferLatency(kDequeueLatencyBinSize),
mIPCTransport(transport) {
// Deferred consumer only support preview surface format now.
@@ -184,8 +184,7 @@
int setId, bool isMultiResolution,
int64_t dynamicRangeProfile, int64_t streamUseCase,
bool deviceTimeBaseIsRealtime, int timestampBase,
- int mirrorMode, int32_t colorSpace,
- bool useReadoutTimestamp) :
+ int32_t colorSpace, bool useReadoutTimestamp) :
Camera3IOStreamBase(id, type, width, height,
/*maxSize*/0,
format, dataSpace, rotation,
@@ -199,7 +198,7 @@
mUseReadoutTime(useReadoutTimestamp),
mConsumerUsage(consumerUsage),
mDropBuffers(false),
- mMirrorMode(mirrorMode),
+ mMirrorMode(OutputConfiguration::MIRROR_MODE_AUTO),
mDequeueBufferLatency(kDequeueLatencyBinSize),
mIPCTransport(transport) {
@@ -479,21 +478,23 @@
" DequeueBuffer latency histogram:");
}
-status_t Camera3OutputStream::setTransform(int transform, bool mayChangeMirror) {
+status_t Camera3OutputStream::setTransform(int transform, bool mayChangeMirror, int surfaceId) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
+
if (mMirrorMode != OutputConfiguration::MIRROR_MODE_AUTO && mayChangeMirror) {
// If the mirroring mode is not AUTO, do not allow transform update
// which may change mirror.
return OK;
}
- return setTransformLocked(transform);
-}
-
-status_t Camera3OutputStream::setTransformLocked(int transform) {
status_t res = OK;
+ if (surfaceId != 0) {
+ ALOGE("%s: Invalid surfaceId %d", __FUNCTION__, surfaceId);
+ return BAD_VALUE;
+ }
+
if (transform == -1) return res;
if (mState == STATE_ERROR) {
@@ -525,6 +526,12 @@
return res;
}
+ if ((res = native_window_set_buffers_transform(mConsumer.get(), mTransform)) != OK) {
+ ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
+ __FUNCTION__, mTransform, strerror(-res), res);
+ return res;
+ }
+
// Set dequeueBuffer/attachBuffer timeout if the consumer is not hw composer or hw texture.
// We need skip these cases as timeout will disable the non-blocking (async) mode.
if (!(isConsumedByHWComposer() || isConsumedByHWTexture())) {
@@ -694,14 +701,6 @@
return res;
}
- res = native_window_set_buffers_transform(mConsumer.get(),
- mTransform);
- if (res != OK) {
- ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
- __FUNCTION__, mTransform, strerror(-res), res);
- return res;
- }
-
/**
* Camera3 Buffer manager is only supported by HAL3.3 onwards, as the older HALs requires
* buffers to be statically allocated for internal static buffer registration, while the
@@ -1069,7 +1068,7 @@
return OK;
}
-status_t Camera3OutputStream::updateStream(const std::vector<sp<Surface>> &/*outputSurfaces*/,
+status_t Camera3OutputStream::updateStream(const std::vector<SurfaceHolder> &/*outputSurfaces*/,
const std::vector<OutputStreamInfo> &/*outputInfo*/,
const std::vector<size_t> &/*removedSurfaceIds*/,
KeyedVector<sp<Surface>, size_t> * /*outputMapo*/) {
@@ -1206,14 +1205,14 @@
return mConsumer == nullptr;
}
-status_t Camera3OutputStream::setConsumers(const std::vector<sp<Surface>>& consumers) {
+status_t Camera3OutputStream::setConsumers(const std::vector<SurfaceHolder>& consumers) {
Mutex::Autolock l(mLock);
if (consumers.size() != 1) {
ALOGE("%s: it's illegal to set %zu consumer surfaces!",
__FUNCTION__, consumers.size());
return INVALID_OPERATION;
}
- if (consumers[0] == nullptr) {
+ if (consumers[0].mSurface == nullptr) {
ALOGE("%s: it's illegal to set null consumer surface!", __FUNCTION__);
return INVALID_OPERATION;
}
@@ -1223,7 +1222,8 @@
return INVALID_OPERATION;
}
- mConsumer = consumers[0];
+ mConsumer = consumers[0].mSurface;
+ mMirrorMode = consumers[0].mMirrorMode;
return OK;
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index f8b78c1..a547f82 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -134,7 +134,6 @@
int64_t streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
bool deviceTimeBaseIsRealtime = false,
int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT,
- int mirrorMode = OutputConfiguration::MIRROR_MODE_AUTO,
int32_t colorSpace = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED,
bool useReadoutTimestamp = false);
@@ -150,7 +149,7 @@
* Set the transform on the output stream; one of the
* HAL_TRANSFORM_* / NATIVE_WINDOW_TRANSFORM_* constants.
*/
- status_t setTransform(int transform, bool mayChangeMirror);
+ virtual status_t setTransform(int transform, bool mayChangeMirror, int surfaceId = 0);
/**
* Return if this output stream is for video encoding.
@@ -179,7 +178,7 @@
/**
* Set the consumer surfaces to the output stream.
*/
- virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers);
+ virtual status_t setConsumers(const std::vector<SurfaceHolder>& consumers);
class BufferProducerListener : public SurfaceListener {
public:
@@ -236,7 +235,7 @@
/**
* Update the stream output surfaces.
*/
- virtual status_t updateStream(const std::vector<sp<Surface>> &outputSurfaces,
+ virtual status_t updateStream(const std::vector<SurfaceHolder> &outputSurfaces,
const std::vector<OutputStreamInfo> &outputInfo,
const std::vector<size_t> &removedSurfaceIds,
KeyedVector<sp<Surface>, size_t> *outputMap/*out*/);
@@ -286,7 +285,6 @@
int64_t streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
bool deviceTimeBaseIsRealtime = false,
int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT,
- int mirrorMode = OutputConfiguration::MIRROR_MODE_AUTO,
int32_t colorSpace = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED,
bool useReadoutTimestamp = false);
@@ -323,8 +321,6 @@
int mTransform;
- virtual status_t setTransformLocked(int transform);
-
bool mTraceFirstBuffer;
/**
@@ -383,7 +379,7 @@
std::vector<Surface::BatchBuffer> mBatchedBuffers;
// ---- End of mBatchLock protected scope ----
- const int mMirrorMode;
+ int mMirrorMode;
/**
* Internal Camera3Stream interface
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index 77edfbe..ff7ad56 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -34,7 +34,7 @@
* Set the transform on the output stream; one of the
* HAL_TRANSFORM_* / NATIVE_WINDOW_TRANSFORM_* constants.
*/
- virtual status_t setTransform(int transform, bool mayChangeMirror) = 0;
+ virtual status_t setTransform(int transform, bool mayChangeMirror, int surfaceId = 0) = 0;
/**
* Return if this output stream is for video encoding.
@@ -49,7 +49,7 @@
/**
* Set the consumer surfaces to the output stream.
*/
- virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers) = 0;
+ virtual status_t setConsumers(const std::vector<SurfaceHolder>& consumers) = 0;
/**
* Detach an unused buffer from the stream.
@@ -81,7 +81,7 @@
/**
* Update the stream output surfaces.
*/
- virtual status_t updateStream(const std::vector<sp<Surface>> &outputSurfaces,
+ virtual status_t updateStream(const std::vector<SurfaceHolder> &outputSurfaces,
const std::vector<OutputStreamInfo> &outputInfo,
const std::vector<size_t> &removedSurfaceIds,
KeyedVector<sp<Surface>, size_t> *outputMap/*out*/) = 0;
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index 187bd93..b436d2e 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -18,6 +18,8 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
+#include <utils/Trace.h>
+
#include "Flags.h"
#include "Camera3SharedOutputStream.h"
@@ -29,7 +31,7 @@
const size_t Camera3SharedOutputStream::kMaxOutputs;
Camera3SharedOutputStream::Camera3SharedOutputStream(int id,
- const std::vector<sp<Surface>>& surfaces,
+ const std::vector<SurfaceHolder>& surfaces,
uint32_t width, uint32_t height, int format,
uint64_t consumerUsage, android_dataspace dataSpace,
camera_stream_rotation_t rotation,
@@ -37,12 +39,12 @@
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
int setId, bool useHalBufManager, int64_t dynamicProfile,
int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
- int mirrorMode, int32_t colorSpace, bool useReadoutTimestamp) :
+ int32_t colorSpace, bool useReadoutTimestamp) :
Camera3OutputStream(id, CAMERA_STREAM_OUTPUT, width, height,
format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
transport, consumerUsage, timestampOffset, setId,
/*isMultiResolution*/false, dynamicProfile, streamUseCase,
- deviceTimeBaseIsRealtime, timestampBase, mirrorMode, colorSpace,
+ deviceTimeBaseIsRealtime, timestampBase, colorSpace,
useReadoutTimestamp),
mUseHalBufManager(useHalBufManager) {
size_t consumerCount = std::min(surfaces.size(), kMaxOutputs);
@@ -50,7 +52,7 @@
ALOGE("%s: Trying to add more consumers than the maximum ", __func__);
}
for (size_t i = 0; i < consumerCount; i++) {
- mSurfaceUniqueIds[i] = std::make_pair(surfaces[i], mNextUniqueSurfaceId++);
+ mSurfaceUniqueIds[i] = SurfaceHolderUniqueId{surfaces[i], mNextUniqueSurfaceId++};
}
}
@@ -72,8 +74,8 @@
std::unordered_map<size_t, sp<Surface>> initialSurfaces;
for (size_t i = 0; i < kMaxOutputs; i++) {
- if (mSurfaceUniqueIds[i].first != nullptr) {
- initialSurfaces.emplace(i, mSurfaceUniqueIds[i].first);
+ if (mSurfaceUniqueIds[i].mSurfaceHolder.mSurface != nullptr) {
+ initialSurfaces.emplace(i, mSurfaceUniqueIds[i].mSurfaceHolder.mSurface);
}
}
@@ -142,19 +144,19 @@
return true;
}
- return (mSurfaceUniqueIds[surface_id].first == nullptr);
+ return (mSurfaceUniqueIds[surface_id].mSurfaceHolder.mSurface == nullptr);
}
-status_t Camera3SharedOutputStream::setConsumers(const std::vector<sp<Surface>>& surfaces) {
+status_t Camera3SharedOutputStream::setConsumers(const std::vector<SurfaceHolder>& surfaceHolders) {
Mutex::Autolock l(mLock);
- if (surfaces.size() == 0) {
+ if (surfaceHolders.size() == 0) {
ALOGE("%s: it's illegal to set zero consumer surfaces!", __FUNCTION__);
return INVALID_OPERATION;
}
status_t ret = OK;
- for (auto& surface : surfaces) {
- if (surface == nullptr) {
+ for (auto& surfaceHolder : surfaceHolders) {
+ if (surfaceHolder.mSurface == nullptr) {
ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
return INVALID_OPERATION;
}
@@ -165,11 +167,11 @@
return NO_MEMORY;
}
- mSurfaceUniqueIds[id] = std::make_pair(surface, mNextUniqueSurfaceId++);
+ mSurfaceUniqueIds[id] = SurfaceHolderUniqueId{surfaceHolder, mNextUniqueSurfaceId++};
// Only call addOutput if the splitter has been connected.
if (mStreamSplitter != nullptr) {
- ret = mStreamSplitter->addOutput(id, surface);
+ ret = mStreamSplitter->addOutput(id, surfaceHolder.mSurface);
if (ret != OK) {
ALOGE("%s: addOutput failed with error code %d", __FUNCTION__, ret);
return ret;
@@ -222,7 +224,7 @@
for (const auto& uniqueId : uniqueSurfaceIds) {
bool uniqueIdFound = false;
for (size_t i = 0; i < kMaxOutputs; i++) {
- if (mSurfaceUniqueIds[i].second == uniqueId) {
+ if (mSurfaceUniqueIds[i].mId == uniqueId) {
surfaceIds.push_back(i);
uniqueIdFound = true;
break;
@@ -275,6 +277,23 @@
return res;
}
+ // Set buffer transform for all configured surfaces
+ for (const auto& surfaceUniqueId : mSurfaceUniqueIds) {
+ const sp<Surface>& surface = surfaceUniqueId.mSurfaceHolder.mSurface;
+ int surfaceId = surfaceUniqueId.mId;
+ int32_t transform = surfaceUniqueId.mTransform;
+ if (transform == -1 || surface == nullptr) {
+ continue;
+ }
+
+ res = mStreamSplitter->setTransform(surfaceId, transform);
+ if (res != OK) {
+ ALOGE("%s: StreamSplitter failed to setTransform: %s(%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+ }
+
return OK;
}
@@ -299,8 +318,9 @@
*usage = getPresetConsumerUsage();
for (size_t id = 0; id < kMaxOutputs; id++) {
- if (mSurfaceUniqueIds[id].first != nullptr) {
- res = getEndpointUsageForSurface(&u, mSurfaceUniqueIds[id].first);
+ const auto& surface = mSurfaceUniqueIds[id].mSurfaceHolder.mSurface;
+ if (surface != nullptr) {
+ res = getEndpointUsageForSurface(&u, surface);
*usage |= u;
}
}
@@ -316,7 +336,7 @@
ssize_t Camera3SharedOutputStream::getNextSurfaceIdLocked() {
ssize_t id = -1;
for (size_t i = 0; i < kMaxOutputs; i++) {
- if (mSurfaceUniqueIds[i].first == nullptr) {
+ if (mSurfaceUniqueIds[i].mSurfaceHolder.mSurface == nullptr) {
id = i;
break;
}
@@ -329,7 +349,7 @@
Mutex::Autolock l(mLock);
ssize_t id = -1;
for (size_t i = 0; i < kMaxOutputs; i++) {
- if (mSurfaceUniqueIds[i].first == surface) {
+ if (mSurfaceUniqueIds[i].mSurfaceHolder.mSurface == surface) {
id = i;
break;
}
@@ -353,13 +373,13 @@
if (surfaceId >= kMaxOutputs) {
return BAD_VALUE;
}
- outUniqueIds->push_back(mSurfaceUniqueIds[surfaceId].second);
+ outUniqueIds->push_back(mSurfaceUniqueIds[surfaceId].mId);
}
return OK;
}
status_t Camera3SharedOutputStream::revertPartialUpdateLocked(
- const KeyedVector<sp<Surface>, size_t> &removedSurfaces,
+ const KeyedVector<size_t, SurfaceHolder> &removedSurfaces,
const KeyedVector<sp<Surface>, size_t> &attachedSurfaces) {
status_t ret = OK;
@@ -371,25 +391,25 @@
return UNKNOWN_ERROR;
}
}
- mSurfaceUniqueIds[index] = std::make_pair(nullptr, mNextUniqueSurfaceId++);
+ mSurfaceUniqueIds[index] = SurfaceHolderUniqueId{mNextUniqueSurfaceId++};
}
for (size_t i = 0; i < removedSurfaces.size(); i++) {
- size_t index = removedSurfaces.valueAt(i);
+ size_t index = removedSurfaces.keyAt(i);
if (mStreamSplitter != nullptr) {
- ret = mStreamSplitter->addOutput(index, removedSurfaces.keyAt(i));
+ ret = mStreamSplitter->addOutput(index, removedSurfaces.valueAt(i).mSurface);
if (ret != OK) {
return UNKNOWN_ERROR;
}
}
- mSurfaceUniqueIds[index] = std::make_pair(
- removedSurfaces.keyAt(i), mNextUniqueSurfaceId++);
+ mSurfaceUniqueIds[index] = SurfaceHolderUniqueId{removedSurfaces.valueAt(i),
+ mNextUniqueSurfaceId++};
}
return ret;
}
-status_t Camera3SharedOutputStream::updateStream(const std::vector<sp<Surface>> &outputSurfaces,
+status_t Camera3SharedOutputStream::updateStream(const std::vector<SurfaceHolder> &outputSurfaces,
const std::vector<OutputStreamInfo> &outputInfo,
const std::vector<size_t> &removedSurfaceIds,
KeyedVector<sp<Surface>, size_t> *outputMap) {
@@ -403,7 +423,7 @@
uint64_t usage;
getEndpointUsage(&usage);
- KeyedVector<sp<Surface>, size_t> removedSurfaces;
+ KeyedVector<size_t, SurfaceHolder> removedSurfaces;
//Check whether the new surfaces are compatible.
for (const auto &infoIt : outputInfo) {
bool imgReaderUsage = (infoIt.consumerUsage & GRALLOC_USAGE_SW_READ_OFTEN) ? true : false;
@@ -437,8 +457,8 @@
}
}
- removedSurfaces.add(mSurfaceUniqueIds[it].first, it);
- mSurfaceUniqueIds[it] = std::make_pair(nullptr, mNextUniqueSurfaceId++);
+ removedSurfaces.add(it, mSurfaceUniqueIds[it].mSurfaceHolder);
+ mSurfaceUniqueIds[it] = SurfaceHolderUniqueId{mNextUniqueSurfaceId++};
}
//Next add the new outputs
@@ -453,7 +473,7 @@
return NO_MEMORY;
}
if (mStreamSplitter != nullptr) {
- ret = mStreamSplitter->addOutput(surfaceId, it);
+ ret = mStreamSplitter->addOutput(surfaceId, it.mSurface);
if (ret != OK) {
ALOGE("%s: failed with error code %d", __FUNCTION__, ret);
status_t res = revertPartialUpdateLocked(removedSurfaces, *outputMap);
@@ -463,13 +483,54 @@
return ret;
}
}
- mSurfaceUniqueIds[surfaceId] = std::make_pair(it, mNextUniqueSurfaceId++);
- outputMap->add(it, surfaceId);
+ mSurfaceUniqueIds[surfaceId] = SurfaceHolderUniqueId{it, mNextUniqueSurfaceId++};
+ outputMap->add(it.mSurface, surfaceId);
}
return ret;
}
+status_t Camera3SharedOutputStream::setTransform(
+ int transform, bool mayChangeMirror, int surfaceId) {
+ ATRACE_CALL();
+ Mutex::Autolock l(mLock);
+
+ status_t res = OK;
+
+ if (surfaceId < 0 || (size_t)surfaceId >= mSurfaceUniqueIds.size()) {
+ ALOGE("%s: Invalid surfaceId %d", __FUNCTION__, surfaceId);
+ return BAD_VALUE;
+ }
+ if (transform == -1) return res;
+
+ if (mState == STATE_ERROR) {
+ ALOGE("%s: Stream in error state", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ auto& surfaceHolderForId = mSurfaceUniqueIds[surfaceId];
+ if (surfaceHolderForId.mSurfaceHolder.mMirrorMode != OutputConfiguration::MIRROR_MODE_AUTO &&
+ mayChangeMirror) {
+ // If the mirroring mode is not AUTO, do not allow transform update
+ // which may change mirror.
+ return OK;
+ }
+
+ surfaceHolderForId.mTransform = transform;
+ if (mState == STATE_CONFIGURED) {
+ sp<Surface> surface = surfaceHolderForId.mSurfaceHolder.mSurface;
+ if (surface != nullptr) {
+ res = mStreamSplitter->setTransform(surfaceId, transform);
+ if (res != OK) {
+ ALOGE("%s: StreamSplitter fails to setTransform: %s(%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
+ }
+ }
+ return res;
+}
+
} // namespace camera3
} // namespace android
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index ae11507..1fd676c 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -41,21 +41,15 @@
* surfaces. A valid stream set id needs to be set to support buffer
* sharing between multiple streams.
*/
- Camera3SharedOutputStream(int id, const std::vector<sp<Surface>>& surfaces,
+ Camera3SharedOutputStream(int id, const std::vector<SurfaceHolder>& surfaces,
uint32_t width, uint32_t height, int format,
uint64_t consumerUsage, android_dataspace dataSpace,
camera_stream_rotation_t rotation, nsecs_t timestampOffset,
const std::string& physicalCameraId,
const std::unordered_set<int32_t> &sensorPixelModesUsed, IPCTransport transport,
- int setId = CAMERA3_STREAM_SET_ID_INVALID,
- bool useHalBufManager = false,
- int64_t dynamicProfile = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
- int64_t streamUseCase = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
- bool deviceTimeBaseIsRealtime = false,
- int timestampBase = OutputConfiguration::TIMESTAMP_BASE_DEFAULT,
- int mirrorMode = OutputConfiguration::MIRROR_MODE_AUTO,
- int32_t colorSpace = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED,
- bool useReadoutTimestamp = false);
+ int setId, bool useHalBufManager, int64_t dynamicProfile, int64_t streamUseCase,
+ bool deviceTimeBaseIsRealtime, int timestampBase,
+ int32_t colorSpace, bool useReadoutTimestamp);
virtual ~Camera3SharedOutputStream();
@@ -65,7 +59,7 @@
virtual bool isConsumerConfigurationDeferred(size_t surface_id) const;
- virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers);
+ virtual status_t setConsumers(const std::vector<SurfaceHolder>& consumers);
virtual ssize_t getSurfaceId(const sp<Surface> &surface);
@@ -78,7 +72,7 @@
virtual status_t getUniqueSurfaceIds(const std::vector<size_t>& surfaceIds,
/*out*/std::vector<size_t>* outUniqueIds) override;
- virtual status_t updateStream(const std::vector<sp<Surface>> &outputSurfaces,
+ virtual status_t updateStream(const std::vector<SurfaceHolder> &outputSurfaces,
const std::vector<OutputStreamInfo> &outputInfo,
const std::vector<size_t> &removedSurfaceIds,
KeyedVector<sp<Surface>, size_t> *outputMap/*out*/);
@@ -89,6 +83,8 @@
return false;
}
+ virtual status_t setTransform(int transform, bool mayChangeMirror, int surfaceId);
+
private:
static const size_t kMaxOutputs = 4;
@@ -97,17 +93,26 @@
// depends on this flag.
bool mUseHalBufManager;
- // Pair of an output Surface and its unique ID
- typedef std::pair<sp<Surface>, size_t> SurfaceUniqueId;
+ // Struct of an output SurfaceHolder, transform, and its unique ID
+ struct SurfaceHolderUniqueId {
+ SurfaceHolder mSurfaceHolder;
+ int mTransform = -1;
+ size_t mId = -1;
- // Map surfaceId -> (output surface, unique surface ID)
- std::array<SurfaceUniqueId, kMaxOutputs> mSurfaceUniqueIds;
+ SurfaceHolderUniqueId() = default;
+ SurfaceHolderUniqueId(size_t id) : mId(id) {}
+ SurfaceHolderUniqueId(const SurfaceHolder& holder, size_t id) :
+ mSurfaceHolder(holder), mId(id) {}
+ };
+
+ // Map surfaceId -> SurfaceHolderUniqueId
+ std::array<SurfaceHolderUniqueId, kMaxOutputs> mSurfaceUniqueIds;
size_t mNextUniqueSurfaceId = 0;
ssize_t getNextSurfaceIdLocked();
- status_t revertPartialUpdateLocked(const KeyedVector<sp<Surface>, size_t> &removedSurfaces,
+ status_t revertPartialUpdateLocked(const KeyedVector<size_t, SurfaceHolder> &removedSurfaces,
const KeyedVector<sp<Surface>, size_t> &attachedSurfaces);
/**
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index 0786622..8f3249d 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -115,7 +115,6 @@
int64_t dynamicRangeProfile;
int64_t streamUseCase;
int timestampBase;
- int mirrorMode;
int32_t colorSpace;
OutputStreamInfo() :
width(-1), height(-1), format(-1), dataSpace(HAL_DATASPACE_UNKNOWN),
@@ -123,17 +122,21 @@
dynamicRangeProfile(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD),
streamUseCase(ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT),
timestampBase(OutputConfiguration::TIMESTAMP_BASE_DEFAULT),
- mirrorMode(OutputConfiguration::MIRROR_MODE_AUTO),
colorSpace(ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED) {}
OutputStreamInfo(int _width, int _height, int _format, android_dataspace _dataSpace,
uint64_t _consumerUsage, const std::unordered_set<int32_t>& _sensorPixelModesUsed,
- int64_t _dynamicRangeProfile, int _streamUseCase, int _timestampBase, int _mirrorMode,
+ int64_t _dynamicRangeProfile, int _streamUseCase, int _timestampBase,
int32_t _colorSpace) :
width(_width), height(_height), format(_format),
dataSpace(_dataSpace), consumerUsage(_consumerUsage),
sensorPixelModesUsed(_sensorPixelModesUsed), dynamicRangeProfile(_dynamicRangeProfile),
- streamUseCase(_streamUseCase), timestampBase(_timestampBase), mirrorMode(_mirrorMode),
- colorSpace(_colorSpace) {}
+ streamUseCase(_streamUseCase), timestampBase(_timestampBase), colorSpace(_colorSpace) {}
+};
+
+// A holder containing a surface and its corresponding mirroring mode
+struct SurfaceHolder {
+ sp<Surface> mSurface;
+ int mMirrorMode = OutputConfiguration::MIRROR_MODE_AUTO;
};
// Utility class to lock and unlock a GraphicBuffer
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index 7090545..a360abf 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -201,6 +201,17 @@
mUseHalBufManager = enabled;
}
+status_t Camera3StreamSplitter::setTransform(size_t surfaceId, int transform) {
+ Mutex::Autolock lock(mMutex);
+ if (!mOutputSurfaces.contains(surfaceId) || mOutputSurfaces[surfaceId] == nullptr) {
+ SP_LOGE("%s: No surface at id %zu", __FUNCTION__, surfaceId);
+ return BAD_VALUE;
+ }
+
+ mOutputTransforms[surfaceId] = transform;
+ return OK;
+}
+
status_t Camera3StreamSplitter::addOutputLocked(size_t surfaceId, const sp<Surface>& outputQueue) {
ATRACE_CALL();
if (outputQueue == nullptr) {
@@ -374,7 +385,12 @@
output->setBuffersDataSpace(static_cast<ui::Dataspace>(bufferItem.mDataSpace));
output->setCrop(&bufferItem.mCrop);
output->setScalingMode(bufferItem.mScalingMode);
- output->setBuffersTransform(bufferItem.mTransform);
+
+ int transform = bufferItem.mTransform;
+ if (mOutputTransforms.contains(surfaceId)) {
+ transform = mOutputTransforms[surfaceId];
+ }
+ output->setBuffersTransform(transform);
// In case the output BufferQueue has its own lock, if we hold splitter lock while calling
// queueBuffer (which will try to acquire the output lock), the output could be holding its
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 0440e08..6e5d8f7 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -96,6 +96,7 @@
void setHalBufferManager(bool enabled);
+ status_t setTransform(size_t surfaceId, int transform);
private:
// From BufferItemConsumer::FrameAvailableListener
//
@@ -237,6 +238,9 @@
//Map surface ids -> gbp outputs
std::unordered_map<int, sp<Surface>> mOutputSurfaces;
+ // Map surface ids -> transform
+ std::unordered_map<int, int> mOutputTransforms;
+
//Map surface ids -> consumer buffer count
std::unordered_map<int, size_t > mConsumerBufferCount;
diff --git a/services/camera/libcameraservice/device3/deprecated/DeprecatedCamera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/deprecated/DeprecatedCamera3StreamSplitter.cpp
index c1113e5..00bbde3 100644
--- a/services/camera/libcameraservice/device3/deprecated/DeprecatedCamera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/deprecated/DeprecatedCamera3StreamSplitter.cpp
@@ -189,6 +189,17 @@
mUseHalBufManager = enabled;
}
+status_t DeprecatedCamera3StreamSplitter::setTransform(size_t surfaceId, int transform) {
+ Mutex::Autolock lock(mMutex);
+ if (!mOutputs.contains(surfaceId) || mOutputs[surfaceId] == nullptr) {
+ SP_LOGE("%s: No surface at id %zu", __FUNCTION__, surfaceId);
+ return BAD_VALUE;
+ }
+
+ mOutputTransforms[surfaceId] = transform;
+ return OK;
+}
+
status_t DeprecatedCamera3StreamSplitter::addOutputLocked(size_t surfaceId,
const sp<Surface>& outputQueue) {
ATRACE_CALL();
@@ -355,9 +366,13 @@
const sp<IGraphicBufferProducer>& output, const BufferItem& bufferItem, size_t surfaceId) {
ATRACE_CALL();
status_t res;
+ int transform = bufferItem.mTransform;
+ if (mOutputTransforms.contains(surfaceId)) {
+ transform = mOutputTransforms[surfaceId];
+ }
IGraphicBufferProducer::QueueBufferInput queueInput(
bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp, bufferItem.mDataSpace,
- bufferItem.mCrop, static_cast<int32_t>(bufferItem.mScalingMode), bufferItem.mTransform,
+ bufferItem.mCrop, static_cast<int32_t>(bufferItem.mScalingMode), transform,
bufferItem.mFence);
IGraphicBufferProducer::QueueBufferOutput queueOutput;
diff --git a/services/camera/libcameraservice/device3/deprecated/DeprecatedCamera3StreamSplitter.h b/services/camera/libcameraservice/device3/deprecated/DeprecatedCamera3StreamSplitter.h
index 4610985..61b43a8 100644
--- a/services/camera/libcameraservice/device3/deprecated/DeprecatedCamera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/deprecated/DeprecatedCamera3StreamSplitter.h
@@ -95,6 +95,7 @@
void setHalBufferManager(bool enabled);
+ status_t setTransform(size_t surfaceId, int transform);
private:
// From IConsumerListener
//
@@ -259,6 +260,9 @@
// Map surface ids -> gbp outputs
std::unordered_map<int, sp<Surface>> mOutputSurfaces;
+ // Map surface ids -> transform
+ std::unordered_map<int, int> mOutputTransforms;
+
// Map surface ids -> consumer buffer count
std::unordered_map<int, size_t> mConsumerBufferCount;
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index 40ca276..d937fe9 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -602,7 +602,6 @@
streamInfo.dynamicRangeProfile = dynamicRangeProfile;
streamInfo.streamUseCase = streamUseCase;
streamInfo.timestampBase = timestampBase;
- streamInfo.mirrorMode = mirrorMode;
streamInfo.colorSpace = colorSpace;
return binder::Status::ok();
}
@@ -848,7 +847,6 @@
int64_t streamUseCase = it.getStreamUseCase();
int timestampBase = it.getTimestampBase();
- int mirrorMode = it.getMirrorMode();
// If the configuration is a deferred consumer, or a not yet completed
// configuration with no buffer producers attached.
if (deferredConsumer || (!isConfigurationComplete && numBufferProducers == 0)) {
@@ -908,6 +906,7 @@
}
for (auto& bufferProducer : bufferProducers) {
+ int mirrorMode = it.getMirrorMode(bufferProducer);
sp<Surface> surface;
res = createSurfaceFromGbp(streamInfo, isStreamInfoValid, surface, bufferProducer,
logicalCameraId, metadataChosen, sensorPixelModesUsed, dynamicRangeProfile,