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/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;