Camera: Add support for multi-resolution input and output streams
1. Add support for multi-resolution image reader
2. Add support for multi-resolution reprocessing
3. Support the up-reved HAL provider and device interfaces
Test: Camera CTS
Bug: 156254356
Change-Id: Ifb9befb6b12d76ec9ecdda4dbbdc853a4cd54a83
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
index d6bf83e..a556200 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
@@ -40,16 +40,17 @@
ATRACE_CALL();
int streamId = streamInfo.streamId;
- int streamSetId = streamInfo.streamSetId;
+ StreamSetKey streamSetKey = {streamInfo.streamSetId, streamInfo.isMultiRes};
- if (streamId == CAMERA3_STREAM_ID_INVALID || streamSetId == CAMERA3_STREAM_SET_ID_INVALID) {
+ if (streamId == CAMERA3_STREAM_ID_INVALID ||
+ streamSetKey.id == CAMERA3_STREAM_SET_ID_INVALID) {
ALOGE("%s: Stream id (%d) or stream set id (%d) is invalid",
- __FUNCTION__, streamId, streamSetId);
+ __FUNCTION__, streamId, streamSetKey.id);
return BAD_VALUE;
}
if (streamInfo.totalBufferCount > kMaxBufferCount || streamInfo.totalBufferCount == 0) {
ALOGE("%s: Stream id (%d) with stream set id (%d) total buffer count %zu is invalid",
- __FUNCTION__, streamId, streamSetId, streamInfo.totalBufferCount);
+ __FUNCTION__, streamId, streamSetKey.id, streamInfo.totalBufferCount);
return BAD_VALUE;
}
if (!streamInfo.isConfigured) {
@@ -75,7 +76,8 @@
for (size_t i = 0; i < mStreamSetMap.size(); i++) {
ssize_t streamIdx = mStreamSetMap[i].streamInfoMap.indexOfKey(streamId);
if (streamIdx != NAME_NOT_FOUND &&
- mStreamSetMap[i].streamInfoMap[streamIdx].streamSetId != streamInfo.streamSetId) {
+ mStreamSetMap[i].streamInfoMap[streamIdx].streamSetId != streamInfo.streamSetId &&
+ mStreamSetMap[i].streamInfoMap[streamIdx].isMultiRes != streamInfo.isMultiRes) {
ALOGE("%s: It is illegal to register the same stream id with different stream set",
__FUNCTION__);
return BAD_VALUE;
@@ -83,20 +85,20 @@
}
// Check if there is an existing stream set registered; if not, create one; otherwise, add this
// stream info to the existing stream set entry.
- ssize_t setIdx = mStreamSetMap.indexOfKey(streamSetId);
+ ssize_t setIdx = mStreamSetMap.indexOfKey(streamSetKey);
if (setIdx == NAME_NOT_FOUND) {
- ALOGV("%s: stream set %d is not registered to stream set map yet, create it.",
- __FUNCTION__, streamSetId);
+ ALOGV("%s: stream set %d(%d) is not registered to stream set map yet, create it.",
+ __FUNCTION__, streamSetKey.id, streamSetKey.isMultiRes);
// Create stream info map, then add to mStreamsetMap.
StreamSet newStreamSet;
- setIdx = mStreamSetMap.add(streamSetId, newStreamSet);
+ setIdx = mStreamSetMap.add(streamSetKey, newStreamSet);
}
// Update stream set map and water mark.
StreamSet& currentStreamSet = mStreamSetMap.editValueAt(setIdx);
ssize_t streamIdx = currentStreamSet.streamInfoMap.indexOfKey(streamId);
if (streamIdx != NAME_NOT_FOUND) {
- ALOGW("%s: stream %d was already registered with stream set %d",
- __FUNCTION__, streamId, streamSetId);
+ ALOGW("%s: stream %d was already registered with stream set %d(%d)",
+ __FUNCTION__, streamId, streamSetKey.id, streamSetKey.isMultiRes);
return OK;
}
currentStreamSet.streamInfoMap.add(streamId, streamInfo);
@@ -113,21 +115,22 @@
return OK;
}
-status_t Camera3BufferManager::unregisterStream(int streamId, int streamSetId) {
+status_t Camera3BufferManager::unregisterStream(int streamId, int streamSetId, bool isMultiRes) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
- ALOGV("%s: unregister stream %d with stream set %d", __FUNCTION__,
- streamId, streamSetId);
+ ALOGV("%s: unregister stream %d with stream set %d(%d)", __FUNCTION__,
+ streamId, streamSetId, isMultiRes);
- if (!checkIfStreamRegisteredLocked(streamId, streamSetId)){
- ALOGE("%s: stream %d with set id %d wasn't properly registered to this buffer manager!",
- __FUNCTION__, streamId, streamSetId);
+ StreamSetKey streamSetKey = {streamSetId, isMultiRes};
+ if (!checkIfStreamRegisteredLocked(streamId, streamSetKey)){
+ ALOGE("%s: stream %d with set %d(%d) wasn't properly registered to this"
+ " buffer manager!", __FUNCTION__, streamId, streamSetId, isMultiRes);
return BAD_VALUE;
}
// De-list all the buffers associated with this stream first.
- StreamSet& currentSet = mStreamSetMap.editValueFor(streamSetId);
+ StreamSet& currentSet = mStreamSetMap.editValueFor(streamSetKey);
BufferCountMap& handOutBufferCounts = currentSet.handoutBufferCountMap;
BufferCountMap& attachedBufferCounts = currentSet.attachedBufferCountMap;
InfoMap& infoMap = currentSet.streamInfoMap;
@@ -150,26 +153,28 @@
// Remove this stream set if all its streams have been removed.
if (handOutBufferCounts.size() == 0 && infoMap.size() == 0) {
- mStreamSetMap.removeItem(streamSetId);
+ mStreamSetMap.removeItem(streamSetKey);
}
return OK;
}
-void Camera3BufferManager::notifyBufferRemoved(int streamId, int streamSetId) {
+void Camera3BufferManager::notifyBufferRemoved(int streamId, int streamSetId, bool isMultiRes) {
Mutex::Autolock l(mLock);
- StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetId);
+ StreamSetKey streamSetKey = {streamSetId, isMultiRes};
+ StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetKey);
size_t& attachedBufferCount =
streamSet.attachedBufferCountMap.editValueFor(streamId);
attachedBufferCount--;
}
status_t Camera3BufferManager::checkAndFreeBufferOnOtherStreamsLocked(
- int streamId, int streamSetId) {
+ int streamId, StreamSetKey streamSetKey) {
StreamId firstOtherStreamId = CAMERA3_STREAM_ID_INVALID;
- StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetId);
+ StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetKey);
if (streamSet.streamInfoMap.size() == 1) {
- ALOGV("StreamSet %d has no other stream available to free", streamSetId);
+ ALOGV("StreamSet %d(%d) has no other stream available to free",
+ streamSetKey.id, streamSetKey.isMultiRes);
return OK;
}
@@ -190,7 +195,8 @@
firstOtherStreamId = CAMERA3_STREAM_ID_INVALID;
}
if (firstOtherStreamId == CAMERA3_STREAM_ID_INVALID || !freeBufferIsAttached) {
- ALOGV("StreamSet %d has no buffer available to free", streamSetId);
+ ALOGV("StreamSet %d(%d) has no buffer available to free",
+ streamSetKey.id, streamSetKey.isMultiRes);
return OK;
}
@@ -237,20 +243,21 @@
}
status_t Camera3BufferManager::getBufferForStream(int streamId, int streamSetId,
- sp<GraphicBuffer>* gb, int* fenceFd, bool noFreeBufferAtConsumer) {
+ bool isMultiRes, sp<GraphicBuffer>* gb, int* fenceFd, bool noFreeBufferAtConsumer) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
- ALOGV("%s: get buffer for stream %d with stream set %d", __FUNCTION__,
- streamId, streamSetId);
+ ALOGV("%s: get buffer for stream %d with stream set %d(%d)", __FUNCTION__,
+ streamId, streamSetId, isMultiRes);
- if (!checkIfStreamRegisteredLocked(streamId, streamSetId)) {
- ALOGE("%s: stream %d is not registered with stream set %d yet!!!",
- __FUNCTION__, streamId, streamSetId);
+ StreamSetKey streamSetKey = {streamSetId, isMultiRes};
+ if (!checkIfStreamRegisteredLocked(streamId, streamSetKey)) {
+ ALOGE("%s: stream %d is not registered with stream set %d(%d) yet!!!",
+ __FUNCTION__, streamId, streamSetId, isMultiRes);
return BAD_VALUE;
}
- StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetId);
+ StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetKey);
BufferCountMap& handOutBufferCounts = streamSet.handoutBufferCountMap;
size_t& bufferCount = handOutBufferCounts.editValueFor(streamId);
BufferCountMap& attachedBufferCounts = streamSet.attachedBufferCountMap;
@@ -272,7 +279,8 @@
bufferCount++;
return ALREADY_EXISTS;
}
- ALOGV("Stream %d set %d: Get buffer for stream: Allocate new", streamId, streamSetId);
+ ALOGV("Stream %d set %d(%d): Get buffer for stream: Allocate new",
+ streamId, streamSetId, isMultiRes);
if (mGrallocVersion < HARDWARE_DEVICE_API_VERSION(1,0)) {
const StreamInfo& info = streamSet.streamInfoMap.valueFor(streamId);
@@ -313,13 +321,13 @@
// in returnBufferForStream() if we want to free buffer more quickly.
// TODO: probably should find out all the inactive stream IDs, and free the firstly found
// buffers for them.
- res = checkAndFreeBufferOnOtherStreamsLocked(streamId, streamSetId);
+ res = checkAndFreeBufferOnOtherStreamsLocked(streamId, streamSetKey);
if (res != OK) {
return res;
}
// Since we just allocated one new buffer above, try free one more buffer from other streams
// to prevent total buffer count from growing
- res = checkAndFreeBufferOnOtherStreamsLocked(streamId, streamSetId);
+ res = checkAndFreeBufferOnOtherStreamsLocked(streamId, streamSetKey);
if (res != OK) {
return res;
}
@@ -332,7 +340,7 @@
}
status_t Camera3BufferManager::onBufferReleased(
- int streamId, int streamSetId, bool* shouldFreeBuffer) {
+ int streamId, int streamSetId, bool isMultiRes, bool* shouldFreeBuffer) {
ATRACE_CALL();
if (shouldFreeBuffer == nullptr) {
@@ -341,22 +349,24 @@
}
Mutex::Autolock l(mLock);
- ALOGV("Stream %d set %d: Buffer released", streamId, streamSetId);
+ ALOGV("Stream %d set %d(%d): Buffer released", streamId, streamSetId, isMultiRes);
*shouldFreeBuffer = false;
- if (!checkIfStreamRegisteredLocked(streamId, streamSetId)){
+ StreamSetKey streamSetKey = {streamSetId, isMultiRes};
+ if (!checkIfStreamRegisteredLocked(streamId, streamSetKey)){
ALOGV("%s: signaling buffer release for an already unregistered stream "
- "(stream %d with set id %d)", __FUNCTION__, streamId, streamSetId);
+ "(stream %d with set id %d(%d))", __FUNCTION__, streamId, streamSetId,
+ isMultiRes);
return OK;
}
if (mGrallocVersion < HARDWARE_DEVICE_API_VERSION(1,0)) {
- StreamSet& streamSet = mStreamSetMap.editValueFor(streamSetId);
+ StreamSet& streamSet = mStreamSetMap.editValueFor(streamSetKey);
BufferCountMap& handOutBufferCounts = streamSet.handoutBufferCountMap;
size_t& bufferCount = handOutBufferCounts.editValueFor(streamId);
bufferCount--;
- ALOGV("%s: Stream %d set %d: Buffer count now %zu", __FUNCTION__, streamId, streamSetId,
- bufferCount);
+ ALOGV("%s: Stream %d set %d(%d): Buffer count now %zu", __FUNCTION__, streamId,
+ streamSetId, isMultiRes, bufferCount);
size_t totalAllocatedBufferCount = 0;
size_t totalHandOutBufferCount = 0;
@@ -371,8 +381,9 @@
// BufferManager got more than enough buffers, so decrease watermark
// to trigger more buffers free operation.
streamSet.allocatedBufferWaterMark = newWaterMark;
- ALOGV("%s: Stream %d set %d: watermark--; now %zu",
- __FUNCTION__, streamId, streamSetId, streamSet.allocatedBufferWaterMark);
+ ALOGV("%s: Stream %d set %d(%d): watermark--; now %zu",
+ __FUNCTION__, streamId, streamSetId, isMultiRes,
+ streamSet.allocatedBufferWaterMark);
}
size_t attachedBufferCount = streamSet.attachedBufferCountMap.valueFor(streamId);
@@ -395,20 +406,22 @@
return OK;
}
-status_t Camera3BufferManager::onBuffersRemoved(int streamId, int streamSetId, size_t count) {
+status_t Camera3BufferManager::onBuffersRemoved(int streamId, int streamSetId,
+ bool isMultiRes, size_t count) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
- ALOGV("Stream %d set %d: Buffer removed", streamId, streamSetId);
+ ALOGV("Stream %d set %d(%d): Buffer removed", streamId, streamSetId, isMultiRes);
- if (!checkIfStreamRegisteredLocked(streamId, streamSetId)){
+ StreamSetKey streamSetKey = {streamSetId, isMultiRes};
+ if (!checkIfStreamRegisteredLocked(streamId, streamSetKey)){
ALOGV("%s: signaling buffer removal for an already unregistered stream "
- "(stream %d with set id %d)", __FUNCTION__, streamId, streamSetId);
+ "(stream %d with set id %d(%d))", __FUNCTION__, streamId, streamSetId, isMultiRes);
return OK;
}
if (mGrallocVersion < HARDWARE_DEVICE_API_VERSION(1,0)) {
- StreamSet& streamSet = mStreamSetMap.editValueFor(streamSetId);
+ StreamSet& streamSet = mStreamSetMap.editValueFor(streamSetKey);
BufferCountMap& handOutBufferCounts = streamSet.handoutBufferCountMap;
size_t& totalHandoutCount = handOutBufferCounts.editValueFor(streamId);
BufferCountMap& attachedBufferCounts = streamSet.attachedBufferCountMap;
@@ -427,8 +440,9 @@
totalHandoutCount -= count;
totalAttachedCount -= count;
- ALOGV("%s: Stream %d set %d: Buffer count now %zu, attached buffer count now %zu",
- __FUNCTION__, streamId, streamSetId, totalHandoutCount, totalAttachedCount);
+ ALOGV("%s: Stream %d set %d(%d): Buffer count now %zu, attached buffer count now %zu",
+ __FUNCTION__, streamId, streamSetId, isMultiRes, totalHandoutCount,
+ totalAttachedCount);
} else {
// TODO: implement gralloc V1 support
return BAD_VALUE;
@@ -444,7 +458,8 @@
String8 lines;
lines.appendFormat(" Total stream sets: %zu\n", mStreamSetMap.size());
for (size_t i = 0; i < mStreamSetMap.size(); i++) {
- lines.appendFormat(" Stream set %d has below streams:\n", mStreamSetMap.keyAt(i));
+ lines.appendFormat(" Stream set %d(%d) has below streams:\n",
+ mStreamSetMap.keyAt(i).id, mStreamSetMap.keyAt(i).isMultiRes);
for (size_t j = 0; j < mStreamSetMap[i].streamInfoMap.size(); j++) {
lines.appendFormat(" Stream %d\n", mStreamSetMap[i].streamInfoMap[j].streamId);
}
@@ -470,11 +485,12 @@
write(fd, lines.string(), lines.size());
}
-bool Camera3BufferManager::checkIfStreamRegisteredLocked(int streamId, int streamSetId) const {
- ssize_t setIdx = mStreamSetMap.indexOfKey(streamSetId);
+bool Camera3BufferManager::checkIfStreamRegisteredLocked(int streamId,
+ StreamSetKey streamSetKey) const {
+ ssize_t setIdx = mStreamSetMap.indexOfKey(streamSetKey);
if (setIdx == NAME_NOT_FOUND) {
- ALOGV("%s: stream set %d is not registered to stream set map yet!",
- __FUNCTION__, streamSetId);
+ ALOGV("%s: stream set %d(%d) is not registered to stream set map yet!",
+ __FUNCTION__, streamSetKey.id, streamSetKey.isMultiRes);
return false;
}
@@ -486,9 +502,10 @@
size_t bufferWaterMark = mStreamSetMap[setIdx].maxAllowedBufferCount;
if (bufferWaterMark == 0 || bufferWaterMark > kMaxBufferCount) {
- ALOGW("%s: stream %d with stream set %d is not registered correctly to stream set map,"
+ ALOGW("%s: stream %d with stream set %d(%d) is not registered correctly to stream set map,"
" as the water mark (%zu) is wrong!",
- __FUNCTION__, streamId, streamSetId, bufferWaterMark);
+ __FUNCTION__, streamId, streamSetKey.id, streamSetKey.isMultiRes,
+ bufferWaterMark);
return false;
}
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.h b/services/camera/libcameraservice/device3/Camera3BufferManager.h
index f0de1c1..64aaa230 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.h
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.h
@@ -99,7 +99,7 @@
* combination doesn't match what was registered, or this stream wasn't registered
* to this buffer manager before.
*/
- status_t unregisterStream(int streamId, int streamSetId);
+ status_t unregisterStream(int streamId, int streamSetId, bool isMultiRes);
/**
* This method obtains a buffer for a stream from this buffer manager.
@@ -127,8 +127,8 @@
* NO_MEMORY: Unable to allocate a buffer for this stream at this time.
*/
status_t getBufferForStream(
- int streamId, int streamSetId, sp<GraphicBuffer>* gb, int* fenceFd,
- bool noFreeBufferAtConsumer = false);
+ int streamId, int streamSetId, bool isMultiRes, sp<GraphicBuffer>* gb,
+ int* fenceFd, bool noFreeBufferAtConsumer = false);
/**
* This method notifies the manager that a buffer has been released by the consumer.
@@ -153,7 +153,8 @@
* combination doesn't match what was registered, or this stream wasn't registered
* to this buffer manager before, or shouldFreeBuffer is null/
*/
- status_t onBufferReleased(int streamId, int streamSetId, /*out*/bool* shouldFreeBuffer);
+ status_t onBufferReleased(int streamId, int streamSetId, bool isMultiRes,
+ /*out*/bool* shouldFreeBuffer);
/**
* This method notifies the manager that certain buffers has been removed from the
@@ -171,13 +172,13 @@
* to this buffer manager before, or the removed buffer count is larger than
* current total handoutCount or attachedCount.
*/
- status_t onBuffersRemoved(int streamId, int streamSetId, size_t count);
+ status_t onBuffersRemoved(int streamId, int streamSetId, bool isMultiRes, size_t count);
/**
* This method notifiers the manager that a buffer is freed from the buffer queue, usually
* because onBufferReleased signals the caller to free a buffer via the shouldFreeBuffer flag.
*/
- void notifyBufferRemoved(int streamId, int streamSetId);
+ void notifyBufferRemoved(int streamId, int streamSetId, bool isMultiRes);
/**
* Dump the buffer manager statistics.
@@ -292,8 +293,20 @@
/**
* Stream set map managed by this buffer manager.
*/
- typedef int StreamSetId;
- KeyedVector<StreamSetId, StreamSet> mStreamSetMap;
+ struct StreamSetKey {
+ // The stream set ID
+ int id;
+ // Whether this stream set is for multi-resolution output streams. It's
+ // valid for 2 stream sets to have the same stream set ID if: one is for
+ // multi-resolution output stream, and the other one is not.
+ bool isMultiRes;
+
+ inline bool operator<(const StreamSetKey& other) const {
+ return (isMultiRes < other.isMultiRes) ||
+ ((isMultiRes == other.isMultiRes) && (id < other.id));
+ }
+ };
+ KeyedVector<StreamSetKey, StreamSet> mStreamSetMap;
KeyedVector<StreamId, wp<Camera3OutputStream>> mStreamMap;
// TODO: There is no easy way to query the Gralloc version in this code yet, we have different
@@ -304,13 +317,13 @@
* Check if this stream was successfully registered already. This method needs to be called with
* mLock held.
*/
- bool checkIfStreamRegisteredLocked(int streamId, int streamSetId) const;
+ bool checkIfStreamRegisteredLocked(int streamId, StreamSetKey streamSetKey) const;
/**
* Check if other streams in the stream set has extra buffer available to be freed, and
* free one if so.
*/
- status_t checkAndFreeBufferOnOtherStreamsLocked(int streamId, int streamSetId);
+ status_t checkAndFreeBufferOnOtherStreamsLocked(int streamId, StreamSetKey streamSetKey);
};
} // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 73a133f..18eb57e 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -313,6 +313,7 @@
mFakeStreamId = NO_STREAM;
mNeedConfig = true;
mPauseStateNotify = false;
+ mIsInputStreamMultiResolution = false;
// Measure the clock domain offset between camera and video/hw_composer
camera_metadata_entry timestampSource =
@@ -481,7 +482,7 @@
return gotLock;
}
-Camera3Device::Size Camera3Device::getMaxJpegResolution() const {
+camera3::Size Camera3Device::getMaxJpegResolution() const {
int32_t maxJpegWidth = 0, maxJpegHeight = 0;
const int STREAM_CONFIGURATION_SIZE = 4;
const int STREAM_FORMAT_OFFSET = 0;
@@ -492,7 +493,7 @@
mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
if (availableStreamConfigs.count == 0 ||
availableStreamConfigs.count % STREAM_CONFIGURATION_SIZE != 0) {
- return Size(0, 0);
+ return camera3::Size(0, 0);
}
// Get max jpeg size (area-wise).
@@ -509,7 +510,7 @@
}
}
- return Size(maxJpegWidth, maxJpegHeight);
+ return camera3::Size(maxJpegWidth, maxJpegHeight);
}
nsecs_t Camera3Device::getMonoToBoottimeOffset() {
@@ -603,7 +604,7 @@
ssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
// Get max jpeg size (area-wise).
- Size maxJpegResolution = getMaxJpegResolution();
+ camera3::Size maxJpegResolution = getMaxJpegResolution();
if (maxJpegResolution.width == 0) {
ALOGE("%s: Camera %s: Can't find valid available jpeg sizes in static metadata!",
__FUNCTION__, mId.string());
@@ -1252,7 +1253,7 @@
}
status_t Camera3Device::createInputStream(
- uint32_t width, uint32_t height, int format, int *id) {
+ uint32_t width, uint32_t height, int format, bool isMultiResolution, int *id) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
@@ -1299,6 +1300,7 @@
newStream->setStatusTracker(mStatusTracker);
mInputStream = newStream;
+ mIsInputStreamMultiResolution = isMultiResolution;
*id = mNextStreamId++;
@@ -1323,7 +1325,8 @@
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
const String8& physicalCameraId,
- std::vector<int> *surfaceIds, int streamSetId, bool isShared, uint64_t consumerUsage) {
+ std::vector<int> *surfaceIds, int streamSetId, bool isShared,
+ bool isMultiResolution, uint64_t consumerUsage) {
ATRACE_CALL();
if (consumer == nullptr) {
@@ -1336,23 +1339,24 @@
return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
format, dataSpace, rotation, id, physicalCameraId, surfaceIds, streamSetId,
- isShared, consumerUsage);
+ isShared, isMultiResolution, consumerUsage);
}
status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
const String8& physicalCameraId,
- std::vector<int> *surfaceIds, int streamSetId, bool isShared, uint64_t consumerUsage) {
+ std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
+ uint64_t consumerUsage) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Mutex::Autolock l(mLock);
ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
- " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s", mId.string(),
- mNextStreamId, width, height, format, dataSpace, rotation, consumerUsage, isShared,
- physicalCameraId.string());
+ " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d",
+ mId.string(), mNextStreamId, width, height, format, dataSpace, rotation,
+ consumerUsage, isShared, physicalCameraId.string(), isMultiResolution);
status_t res;
bool wasActive = false;
@@ -1414,7 +1418,7 @@
}
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, blobBufferSize, format, dataSpace, rotation,
- mTimestampOffset, physicalCameraId, streamSetId);
+ mTimestampOffset, physicalCameraId, streamSetId, isMultiResolution);
} else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
ssize_t rawOpaqueBufferSize = getRawOpaqueBufferSize(width, height);
if (rawOpaqueBufferSize <= 0) {
@@ -1423,20 +1427,19 @@
}
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
- mTimestampOffset, physicalCameraId, streamSetId);
+ mTimestampOffset, physicalCameraId, streamSetId, isMultiResolution);
} else if (isShared) {
newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
width, height, format, consumerUsage, dataSpace, rotation,
- mTimestampOffset, physicalCameraId, streamSetId,
- mUseHalBufManager);
+ mTimestampOffset, physicalCameraId, streamSetId, mUseHalBufManager);
} else if (consumers.size() == 0 && hasDeferredConsumer) {
newStream = new Camera3OutputStream(mNextStreamId,
width, height, format, consumerUsage, dataSpace, rotation,
- mTimestampOffset, physicalCameraId, streamSetId);
+ mTimestampOffset, physicalCameraId, streamSetId, isMultiResolution);
} else {
newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
width, height, format, dataSpace, rotation,
- mTimestampOffset, physicalCameraId, streamSetId);
+ mTimestampOffset, physicalCameraId, streamSetId, isMultiResolution);
}
size_t consumerCount = consumers.size();
@@ -2549,8 +2552,9 @@
if (mInputStream != NULL && notifyRequestThread) {
while (true) {
camera_stream_buffer_t inputBuffer;
+ camera3::Size inputBufferSize;
status_t res = mInputStream->getInputBuffer(&inputBuffer,
- /*respectHalLimit*/ false);
+ &inputBufferSize, /*respectHalLimit*/ false);
if (res != OK) {
// Exhausted acquiring all input buffers.
break;
@@ -2587,6 +2591,7 @@
camera_stream_configuration config;
config.operation_mode = mOperatingMode;
config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
+ config.input_is_multi_resolution = false;
Vector<camera3::camera_stream_t*> streams;
streams.setCapacity(config.num_streams);
@@ -2602,6 +2607,8 @@
return INVALID_OPERATION;
}
streams.add(inputStream);
+
+ config.input_is_multi_resolution = mIsInputStreamMultiResolution;
}
for (size_t i = 0; i < mOutputStreams.size(); i++) {
@@ -2999,6 +3006,10 @@
mSupportOfflineProcessing(supportOfflineProcessing) {
// Check with hardware service manager if we can downcast these interfaces
// Somewhat expensive, so cache the results at startup
+ auto castResult_3_7 = device::V3_7::ICameraDeviceSession::castFrom(mHidlSession);
+ if (castResult_3_7.isOk()) {
+ mHidlSession_3_7 = castResult_3_7;
+ }
auto castResult_3_6 = device::V3_6::ICameraDeviceSession::castFrom(mHidlSession);
if (castResult_3_6.isOk()) {
mHidlSession_3_6 = castResult_3_6;
@@ -3032,6 +3043,7 @@
}
void Camera3Device::HalInterface::clear() {
+ mHidlSession_3_7.clear();
mHidlSession_3_6.clear();
mHidlSession_3_5.clear();
mHidlSession_3_4.clear();
@@ -3158,15 +3170,23 @@
if (!valid()) return INVALID_OPERATION;
status_t res = OK;
+ if (config->input_is_multi_resolution && mHidlSession_3_7 == nullptr) {
+ ALOGE("%s: Camera device doesn't support multi-resolution input stream", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
// Convert stream config to HIDL
std::set<int> activeStreams;
device::V3_2::StreamConfiguration requestedConfiguration3_2;
device::V3_4::StreamConfiguration requestedConfiguration3_4;
+ device::V3_7::StreamConfiguration requestedConfiguration3_7;
requestedConfiguration3_2.streams.resize(config->num_streams);
requestedConfiguration3_4.streams.resize(config->num_streams);
+ requestedConfiguration3_7.streams.resize(config->num_streams);
for (size_t i = 0; i < config->num_streams; i++) {
device::V3_2::Stream &dst3_2 = requestedConfiguration3_2.streams[i];
device::V3_4::Stream &dst3_4 = requestedConfiguration3_4.streams[i];
+ device::V3_7::Stream &dst3_7 = requestedConfiguration3_7.streams[i];
camera3::camera_stream_t *src = config->streams[i];
Camera3Stream* cam3stream = Camera3Stream::cast(src);
@@ -3207,6 +3227,8 @@
if (src->physical_camera_id != nullptr) {
dst3_4.physicalCameraId = src->physical_camera_id;
}
+ dst3_7.v3_4 = dst3_4;
+ dst3_7.groupId = cam3stream->getHalStreamGroupId();
activeStreams.insert(streamId);
// Create Buffer ID map if necessary
@@ -3227,6 +3249,10 @@
requestedConfiguration3_4.sessionParams.setToExternal(
reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
get_camera_metadata_size(sessionParams));
+ requestedConfiguration3_7.operationMode = operationMode;
+ requestedConfiguration3_7.sessionParams.setToExternal(
+ reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
+ get_camera_metadata_size(sessionParams));
// Invoke configureStreams
device::V3_3::HalStreamConfiguration finalConfiguration;
@@ -3273,7 +3299,17 @@
};
// See which version of HAL we have
- if (mHidlSession_3_6 != nullptr) {
+ if (mHidlSession_3_7 != nullptr) {
+ ALOGV("%s: v3.7 device found", __FUNCTION__);
+ requestedConfiguration3_7.streamConfigCounter = mNextStreamConfigCounter++;
+ requestedConfiguration3_7.multiResolutionInputImage = config->input_is_multi_resolution;
+ auto err = mHidlSession_3_7->configureStreams_3_7(
+ requestedConfiguration3_7, configStream36Cb);
+ res = postprocConfigStream36(err);
+ if (res != OK) {
+ return res;
+ }
+ } else if (mHidlSession_3_6 != nullptr) {
ALOGV("%s: v3.6 device found", __FUNCTION__);
device::V3_5::StreamConfiguration requestedConfiguration3_5;
requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
@@ -3531,6 +3567,11 @@
if (!valid()) return INVALID_OPERATION;
sp<device::V3_4::ICameraDeviceSession> hidlSession_3_4;
+ sp<device::V3_7::ICameraDeviceSession> hidlSession_3_7;
+ auto castResult_3_7 = device::V3_7::ICameraDeviceSession::castFrom(mHidlSession);
+ if (castResult_3_7.isOk()) {
+ hidlSession_3_7 = castResult_3_7;
+ }
auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
if (castResult_3_4.isOk()) {
hidlSession_3_4 = castResult_3_4;
@@ -3538,8 +3579,11 @@
hardware::hidl_vec<device::V3_2::CaptureRequest> captureRequests;
hardware::hidl_vec<device::V3_4::CaptureRequest> captureRequests_3_4;
+ hardware::hidl_vec<device::V3_7::CaptureRequest> captureRequests_3_7;
size_t batchSize = requests.size();
- if (hidlSession_3_4 != nullptr) {
+ if (hidlSession_3_7 != nullptr) {
+ captureRequests_3_7.resize(batchSize);
+ } else if (hidlSession_3_4 != nullptr) {
captureRequests_3_4.resize(batchSize);
} else {
captureRequests.resize(batchSize);
@@ -3549,7 +3593,10 @@
status_t res = OK;
for (size_t i = 0; i < batchSize; i++) {
- if (hidlSession_3_4 != nullptr) {
+ if (hidlSession_3_7 != nullptr) {
+ res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_7[i].v3_4.v3_2,
+ /*out*/&handlesCreated, /*out*/&inflightBuffers);
+ } else if (hidlSession_3_4 != nullptr) {
res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_4[i].v3_2,
/*out*/&handlesCreated, /*out*/&inflightBuffers);
} else {
@@ -3582,7 +3629,9 @@
for (size_t i = 0; i < batchSize; i++) {
camera_capture_request_t* request = requests[i];
device::V3_2::CaptureRequest* captureRequest;
- if (hidlSession_3_4 != nullptr) {
+ if (hidlSession_3_7 != nullptr) {
+ captureRequest = &captureRequests_3_7[i].v3_4.v3_2;
+ } else if (hidlSession_3_4 != nullptr) {
captureRequest = &captureRequests_3_4[i].v3_2;
} else {
captureRequest = &captureRequests[i];
@@ -3609,33 +3658,42 @@
captureRequest->fmqSettingsSize = 0u;
}
- if (hidlSession_3_4 != nullptr) {
- captureRequests_3_4[i].physicalCameraSettings.resize(request->num_physcam_settings);
+ // hidl session 3.7 specific handling.
+ if (hidlSession_3_7 != nullptr) {
+ captureRequests_3_7[i].inputWidth = request->input_width;
+ captureRequests_3_7[i].inputHeight = request->input_height;
+ }
+
+ // hidl session 3.7 and 3.4 specific handling.
+ if (hidlSession_3_7 != nullptr || hidlSession_3_4 != nullptr) {
+ hardware::hidl_vec<device::V3_4::PhysicalCameraSetting>& physicalCameraSettings =
+ (hidlSession_3_7 != nullptr) ?
+ captureRequests_3_7[i].v3_4.physicalCameraSettings :
+ captureRequests_3_4[i].physicalCameraSettings;
+ physicalCameraSettings.resize(request->num_physcam_settings);
for (size_t j = 0; j < request->num_physcam_settings; j++) {
if (request->physcam_settings != nullptr) {
size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
reinterpret_cast<const uint8_t*>(request->physcam_settings[j]),
settingsSize)) {
- captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0);
- captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize =
- settingsSize;
+ physicalCameraSettings[j].settings.resize(0);
+ physicalCameraSettings[j].fmqSettingsSize = settingsSize;
} else {
if (mRequestMetadataQueue != nullptr) {
ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
}
- captureRequests_3_4[i].physicalCameraSettings[j].settings.setToExternal(
+ physicalCameraSettings[j].settings.setToExternal(
reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
request->physcam_settings[j])),
get_camera_metadata_size(request->physcam_settings[j]));
- captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = 0u;
+ physicalCameraSettings[j].fmqSettingsSize = 0u;
}
} else {
captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = 0u;
captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0);
}
- captureRequests_3_4[i].physicalCameraSettings[j].physicalCameraId =
- request->physcam_id[j];
+ physicalCameraSettings[j].physicalCameraId = request->physcam_id[j];
}
}
}
@@ -3646,7 +3704,10 @@
status = s;
*numRequestProcessed = n;
};
- if (hidlSession_3_4 != nullptr) {
+ if (hidlSession_3_7 != nullptr) {
+ err = hidlSession_3_7->processCaptureRequest_3_7(captureRequests_3_7, cachesToRemove,
+ resultCallback);
+ } else if (hidlSession_3_4 != nullptr) {
err = hidlSession_3_4->processCaptureRequest_3_4(captureRequests_3_4, cachesToRemove,
resultCallback);
} else {
@@ -4055,8 +4116,9 @@
// Abort the input buffers for reprocess requests.
if ((*it)->mInputStream != NULL) {
camera_stream_buffer_t inputBuffer;
+ camera3::Size inputBufferSize;
status_t res = (*it)->mInputStream->getInputBuffer(&inputBuffer,
- /*respectHalLimit*/ false);
+ &inputBufferSize, /*respectHalLimit*/ false);
if (res != OK) {
ALOGW("%s: %d: couldn't get input buffer while clearing the request "
"list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
@@ -4262,33 +4324,34 @@
void Camera3Device::RequestThread::updateNextRequest(NextRequest& nextRequest) {
// Update the latest request sent to HAL
- if (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchanged
+ camera_capture_request_t& halRequest = nextRequest.halRequest;
+ if (halRequest.settings != NULL) { // Don't update if they were unchanged
Mutex::Autolock al(mLatestRequestMutex);
- camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings);
+ camera_metadata_t* cloned = clone_camera_metadata(halRequest.settings);
mLatestRequest.acquire(cloned);
mLatestPhysicalRequest.clear();
- for (uint32_t i = 0; i < nextRequest.halRequest.num_physcam_settings; i++) {
- cloned = clone_camera_metadata(nextRequest.halRequest.physcam_settings[i]);
- mLatestPhysicalRequest.emplace(nextRequest.halRequest.physcam_id[i],
+ for (uint32_t i = 0; i < halRequest.num_physcam_settings; i++) {
+ cloned = clone_camera_metadata(halRequest.physcam_settings[i]);
+ mLatestPhysicalRequest.emplace(halRequest.physcam_id[i],
CameraMetadata(cloned));
}
sp<Camera3Device> parent = mParent.promote();
if (parent != NULL) {
parent->monitorMetadata(TagMonitor::REQUEST,
- nextRequest.halRequest.frame_number,
+ halRequest.frame_number,
0, mLatestRequest, mLatestPhysicalRequest);
}
}
- if (nextRequest.halRequest.settings != NULL) {
+ if (halRequest.settings != NULL) {
nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock(
- nextRequest.halRequest.settings);
+ halRequest.settings);
}
- cleanupPhysicalSettings(nextRequest.captureRequest, &nextRequest.halRequest);
+ cleanupPhysicalSettings(nextRequest.captureRequest, &halRequest);
}
bool Camera3Device::RequestThread::updateSessionParameters(const CameraMetadata& settings) {
@@ -4651,6 +4714,9 @@
// Fill in buffers
if (captureRequest->mInputStream != NULL) {
halRequest->input_buffer = &captureRequest->mInputBuffer;
+
+ halRequest->input_width = captureRequest->mInputBufferSize.width;
+ halRequest->input_height = captureRequest->mInputBufferSize.height;
totalNumBuffers += 1;
} else {
halRequest->input_buffer = NULL;
@@ -4754,13 +4820,7 @@
}
String8 physicalCameraId = outputStream->getPhysicalCameraId();
-
if (!physicalCameraId.isEmpty()) {
- // Physical stream isn't supported for input request.
- if (halRequest->input_buffer) {
- CLOGE("Physical stream is not supported for input request");
- return INVALID_OPERATION;
- }
requestedPhysicalCameras.insert(physicalCameraId);
}
halRequest->num_output_buffers++;
@@ -5237,7 +5297,8 @@
// Since RequestThread::clear() removes buffers from the input stream,
// get the right buffer here before unlocking mRequestLock
if (nextRequest->mInputStream != NULL) {
- res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer);
+ res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer,
+ &nextRequest->mInputBufferSize);
if (res != OK) {
// Can't get input buffer from gralloc queue - this could be due to
// disconnected queue or other producer misbehavior, so not a fatal
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 09fa30a..018dbe5 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -35,6 +35,7 @@
#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.6/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.2/ICameraDeviceCallback.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
@@ -52,6 +53,7 @@
#include "device3/InFlightRequest.h"
#include "device3/Camera3OutputInterface.h"
#include "device3/Camera3OfflineSession.h"
+#include "device3/Camera3StreamInterface.h"
#include "utils/TagMonitor.h"
#include "utils/LatencyHistogram.h"
#include <camera_metadata_hidden.h>
@@ -71,7 +73,6 @@
class Camera3Stream;
class Camera3ZslStream;
-class Camera3OutputStreamInterface;
class Camera3StreamInterface;
} // namespace camera3
@@ -133,17 +134,19 @@
const String8& physicalCameraId,
std::vector<int> *surfaceIds = nullptr,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
- bool isShared = false, uint64_t consumerUsage = 0) override;
+ bool isShared = false, bool isMultiResolution = false,
+ uint64_t consumerUsage = 0) override;
status_t createStream(const std::vector<sp<Surface>>& consumers,
bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
const String8& physicalCameraId,
std::vector<int> *surfaceIds = nullptr,
int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
- bool isShared = false, uint64_t consumerUsage = 0) override;
+ bool isShared = false, bool isMultiResolution = false,
+ uint64_t consumerUsage = 0) override;
status_t createInputStream(
- uint32_t width, uint32_t height, int format,
+ uint32_t width, uint32_t height, int format, bool isMultiResolution,
int *id) override;
status_t getStreamInfo(int id, StreamInfo *streamInfo) override;
@@ -418,6 +421,8 @@
sp<hardware::camera::device::V3_5::ICameraDeviceSession> mHidlSession_3_5;
// Valid if ICameraDeviceSession is @3.6 or newer
sp<hardware::camera::device::V3_6::ICameraDeviceSession> mHidlSession_3_6;
+ // Valid if ICameraDeviceSession is @3.7 or newer
+ sp<hardware::camera::device::V3_7::ICameraDeviceSession> mHidlSession_3_7;
std::shared_ptr<RequestMetadataQueue> mRequestMetadataQueue;
@@ -490,6 +495,7 @@
camera3::StreamSet mOutputStreams;
sp<camera3::Camera3Stream> mInputStream;
+ bool mIsInputStreamMultiResolution;
SessionStatsBuilder mSessionStatsBuilder;
int mNextStreamId;
@@ -523,6 +529,7 @@
PhysicalCameraSettingsList mSettingsList;
sp<camera3::Camera3Stream> mInputStream;
camera_stream_buffer_t mInputBuffer;
+ camera3::Size mInputBufferSize;
Vector<sp<camera3::Camera3OutputStreamInterface> >
mOutputStreams;
SurfaceMap mOutputSurfaces;
@@ -748,7 +755,7 @@
* Helper function to get the largest Jpeg resolution (in area)
* Return Size(0, 0) if static metatdata is invalid
*/
- Size getMaxJpegResolution() const;
+ camera3::Size getMaxJpegResolution() const;
/**
* Helper function to get the offset between MONOTONIC and BOOTTIME
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index f6acda8..a837900 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -32,10 +32,10 @@
Camera3IOStreamBase::Camera3IOStreamBase(int id, camera_stream_type_t type,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- const String8& physicalCameraId, int setId) :
+ const String8& physicalCameraId, int setId, bool isMultiResolution) :
Camera3Stream(id, type,
width, height, maxSize, format, dataSpace, rotation,
- physicalCameraId, setId),
+ physicalCameraId, setId, isMultiResolution),
mTotalBufferCount(0),
mHandoutTotalBufferCount(0),
mHandoutOutputBufferCount(0),
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index 719fa14..2e744ee 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -36,7 +36,7 @@
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
- int setId = CAMERA3_STREAM_SET_ID_INVALID);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false);
public:
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
index ad70a3a..b00a963 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
@@ -46,10 +46,14 @@
}
status_t Camera3InputStream::getInputBufferLocked(
- camera_stream_buffer *buffer) {
+ camera_stream_buffer *buffer, Size *size) {
ATRACE_CALL();
status_t res;
+ if (size == nullptr) {
+ ALOGE("%s: size must not be null", __FUNCTION__);
+ return BAD_VALUE;
+ }
// FIXME: will not work in (re-)registration
if (mState == STATE_IN_CONFIG || mState == STATE_IN_RECONFIG) {
ALOGE("%s: Stream %d: Buffer registration for input streams"
@@ -77,10 +81,12 @@
return res;
}
+ size->width = bufferItem.mGraphicBuffer->getWidth();
+ size->height = bufferItem.mGraphicBuffer->getHeight();
+
anb = bufferItem.mGraphicBuffer->getNativeBuffer();
assert(anb != NULL);
fenceFd = bufferItem.mFence->dup();
-
/**
* FenceFD now owned by HAL except in case of error,
* in which case we reassign it to acquire_fence
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.h b/services/camera/libcameraservice/device3/Camera3InputStream.h
index 03afa17..46221d1 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.h
@@ -70,7 +70,7 @@
* Camera3Stream interface
*/
- virtual status_t getInputBufferLocked(camera_stream_buffer *buffer);
+ virtual status_t getInputBufferLocked(camera_stream_buffer *buffer, Size *size);
virtual status_t returnInputBufferLocked(
const camera_stream_buffer &buffer);
virtual status_t getInputBufferProducerLocked(
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index c835f51..3ec3b6b 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -44,10 +44,10 @@
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
- int setId) :
+ int setId, bool isMultiResolution) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
- physicalCameraId, setId),
+ physicalCameraId, setId, isMultiResolution),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
@@ -70,9 +70,11 @@
sp<Surface> consumer,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- nsecs_t timestampOffset, const String8& physicalCameraId, int setId) :
+ nsecs_t timestampOffset, const String8& physicalCameraId, int setId,
+ bool isMultiResolution) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height, maxSize,
- format, dataSpace, rotation, physicalCameraId, setId),
+ format, dataSpace, rotation, physicalCameraId, setId,
+ isMultiResolution),
mConsumer(consumer),
mTransform(0),
mTraceFirstBuffer(true),
@@ -102,10 +104,10 @@
uint32_t width, uint32_t height, int format,
uint64_t consumerUsage, android_dataspace dataSpace,
camera_stream_rotation_t rotation, nsecs_t timestampOffset,
- const String8& physicalCameraId, int setId) :
+ const String8& physicalCameraId, int setId, bool isMultiResolution) :
Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
/*maxSize*/0, format, dataSpace, rotation,
- physicalCameraId, setId),
+ physicalCameraId, setId, isMultiResolution),
mConsumer(nullptr),
mTransform(0),
mTraceFirstBuffer(true),
@@ -141,11 +143,11 @@
camera_stream_rotation_t rotation,
const String8& physicalCameraId,
uint64_t consumerUsage, nsecs_t timestampOffset,
- int setId) :
+ int setId, bool isMultiResolution) :
Camera3IOStreamBase(id, type, width, height,
/*maxSize*/0,
format, dataSpace, rotation,
- physicalCameraId, setId),
+ physicalCameraId, setId, isMultiResolution),
mTransform(0),
mTraceFirstBuffer(true),
mUseMonoTimestamp(false),
@@ -570,10 +572,12 @@
!(isConsumedByHWComposer() || isConsumedByHWTexture())) {
uint64_t consumerUsage = 0;
getEndpointUsage(&consumerUsage);
+ uint32_t width = (mMaxSize == 0) ? getWidth() : mMaxSize;
+ uint32_t height = (mMaxSize == 0) ? getHeight() : 1;
StreamInfo streamInfo(
- getId(), getStreamSetId(), getWidth(), getHeight(), getFormat(), getDataSpace(),
+ getId(), getStreamSetId(), width, height, getFormat(), getDataSpace(),
mUsage | consumerUsage, mTotalBufferCount,
- /*isConfigured*/true);
+ /*isConfigured*/true, isMultiResolution());
wp<Camera3OutputStream> weakThis(this);
res = mBufferManager->registerStream(weakThis,
streamInfo);
@@ -604,7 +608,8 @@
if (mUseBufferManager) {
sp<GraphicBuffer> gb;
- res = mBufferManager->getBufferForStream(getId(), getStreamSetId(), &gb, fenceFd);
+ res = mBufferManager->getBufferForStream(getId(), getStreamSetId(),
+ isMultiResolution(), &gb, fenceFd);
if (res == OK) {
// Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a
// successful return.
@@ -693,7 +698,8 @@
sp<GraphicBuffer> gb;
res = mBufferManager->getBufferForStream(
- getId(), getStreamSetId(), &gb, fenceFd, /*noFreeBuffer*/true);
+ getId(), getStreamSetId(), isMultiResolution(),
+ &gb, fenceFd, /*noFreeBuffer*/true);
if (res == OK) {
// Attach this buffer to the bufferQueue: the buffer will be in dequeue state after
@@ -740,7 +746,8 @@
onBuffersRemovedLocked(removedBuffers);
if (notifyBufferManager && mUseBufferManager && removedBuffers.size() > 0) {
- mBufferManager->onBuffersRemoved(getId(), getStreamSetId(), removedBuffers.size());
+ mBufferManager->onBuffersRemoved(getId(), getStreamSetId(), isMultiResolution(),
+ removedBuffers.size());
}
}
}
@@ -802,7 +809,7 @@
// Since device is already idle, there is no getBuffer call to buffer manager, unregister the
// stream at this point should be safe.
if (mUseBufferManager) {
- res = mBufferManager->unregisterStream(getId(), getStreamSetId());
+ res = mBufferManager->unregisterStream(getId(), getStreamSetId(), isMultiResolution());
if (res != OK) {
ALOGE("%s: Unable to unregister stream %d from buffer manager "
"(error %d %s)", __FUNCTION__, mId, res, strerror(-res));
@@ -914,7 +921,8 @@
ALOGV("Stream %d: Buffer released", stream->getId());
bool shouldFreeBuffer = false;
status_t res = stream->mBufferManager->onBufferReleased(
- stream->getId(), stream->getStreamSetId(), &shouldFreeBuffer);
+ stream->getId(), stream->getStreamSetId(), stream->isMultiResolution(),
+ &shouldFreeBuffer);
if (res != OK) {
ALOGE("%s: signaling buffer release to buffer manager failed: %s (%d).", __FUNCTION__,
strerror(-res), res);
@@ -927,7 +935,7 @@
stream->detachBufferLocked(&buffer, /*fenceFd*/ nullptr);
if (buffer.get() != nullptr) {
stream->mBufferManager->notifyBufferRemoved(
- stream->getId(), stream->getStreamSetId());
+ stream->getId(), stream->getStreamSetId(), stream->isMultiResolution());
}
}
}
@@ -945,7 +953,7 @@
stream->onBuffersRemovedLocked(buffers);
if (stream->mUseBufferManager) {
stream->mBufferManager->onBuffersRemoved(stream->getId(),
- stream->getStreamSetId(), buffers.size());
+ stream->getStreamSetId(), stream->isMultiResolution(), buffers.size());
}
ALOGV("Stream %d: %zu Buffers discarded.", stream->getId(), buffers.size());
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 366d22a..c82f2a6 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -48,6 +48,7 @@
uint64_t combinedUsage;
size_t totalBufferCount;
bool isConfigured;
+ bool isMultiRes;
explicit StreamInfo(int id = CAMERA3_STREAM_ID_INVALID,
int setId = CAMERA3_STREAM_SET_ID_INVALID,
uint32_t w = 0,
@@ -56,7 +57,8 @@
android_dataspace ds = HAL_DATASPACE_UNKNOWN,
uint64_t usage = 0,
size_t bufferCount = 0,
- bool configured = false) :
+ bool configured = false,
+ bool multiRes = false) :
streamId(id),
streamSetId(setId),
width(w),
@@ -65,7 +67,8 @@
dataSpace(ds),
combinedUsage(usage),
totalBufferCount(bufferCount),
- isConfigured(configured){}
+ isConfigured(configured),
+ isMultiRes(multiRes) {}
};
/**
@@ -84,7 +87,7 @@
uint32_t width, uint32_t height, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
- int setId = CAMERA3_STREAM_SET_ID_INVALID);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false);
/**
* Set up a stream for formats that have a variable buffer size for the same
@@ -96,7 +99,7 @@
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
nsecs_t timestampOffset, const String8& physicalCameraId,
- int setId = CAMERA3_STREAM_SET_ID_INVALID);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false);
/**
* Set up a stream with deferred consumer for formats that have 2 dimensions, such as
@@ -107,7 +110,7 @@
uint64_t consumerUsage, android_dataspace dataSpace,
camera_stream_rotation_t rotation, nsecs_t timestampOffset,
const String8& physicalCameraId,
- int setId = CAMERA3_STREAM_SET_ID_INVALID);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false);
virtual ~Camera3OutputStream();
@@ -232,7 +235,7 @@
android_dataspace dataSpace, camera_stream_rotation_t rotation,
const String8& physicalCameraId,
uint64_t consumerUsage = 0, nsecs_t timestampOffset = 0,
- int setId = CAMERA3_STREAM_SET_ID_INVALID);
+ int setId = CAMERA3_STREAM_SET_ID_INVALID, bool isMultiResolution = false);
/**
* Note that we release the lock briefly in this function
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.h b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
index 772fe6e..142889a 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.h
@@ -46,6 +46,7 @@
uint32_t num_streams;
camera_stream_t **streams;
uint32_t operation_mode;
+ bool input_is_multi_resolution;
} camera_stream_configuration_t;
typedef struct camera_capture_request {
@@ -57,6 +58,8 @@
uint32_t num_physcam_settings;
const char **physcam_id;
const camera_metadata_t **physcam_settings;
+ int32_t input_width;
+ int32_t input_height;
} camera_capture_request_t;
typedef struct camera_capture_result {
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 4cb954e..c6e7002 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -49,7 +49,7 @@
camera_stream_type type,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- const String8& physicalCameraId, int setId) :
+ const String8& physicalCameraId, int setId, bool isMultiResolution) :
camera_stream(),
mId(id),
mSetId(setId),
@@ -73,7 +73,8 @@
mDataSpaceOverridden(false),
mOriginalDataSpace(dataSpace),
mPhysicalCameraId(physicalCameraId),
- mLastTimestamp(0) {
+ mLastTimestamp(0),
+ mIsMultiResolution(isMultiResolution) {
camera_stream::stream_type = type;
camera_stream::width = width;
@@ -99,6 +100,14 @@
return mSetId;
}
+int Camera3Stream::getHalStreamGroupId() const {
+ return mIsMultiResolution ? mSetId : -1;
+}
+
+bool Camera3Stream::isMultiResolution() const {
+ return mIsMultiResolution;
+}
+
uint32_t Camera3Stream::getWidth() const {
return camera_stream::width;
}
@@ -743,11 +752,16 @@
return res;
}
-status_t Camera3Stream::getInputBuffer(camera_stream_buffer *buffer, bool respectHalLimit) {
+status_t Camera3Stream::getInputBuffer(camera_stream_buffer *buffer,
+ Size* size, bool respectHalLimit) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
status_t res = OK;
+ if (size == nullptr) {
+ ALOGE("%s: size must not be null", __FUNCTION__);
+ return BAD_VALUE;
+ }
// This function should be only called when the stream is configured already.
if (mState != STATE_CONFIGURED) {
ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d",
@@ -769,7 +783,7 @@
}
}
- res = getInputBufferLocked(buffer);
+ res = getInputBufferLocked(buffer, size);
if (res == OK) {
fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
if (buffer->buffer) {
@@ -918,7 +932,7 @@
ALOGE("%s: This type of stream does not support output", __FUNCTION__);
return INVALID_OPERATION;
}
-status_t Camera3Stream::getInputBufferLocked(camera_stream_buffer *) {
+status_t Camera3Stream::getInputBufferLocked(camera_stream_buffer *, Size *) {
ALOGE("%s: This type of stream does not support input", __FUNCTION__);
return INVALID_OPERATION;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 55ed2f2..45d8478 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -147,6 +147,14 @@
* Get the output stream set id.
*/
int getStreamSetId() const;
+ /**
+ * Is this stream part of a multi-resolution stream set
+ */
+ bool isMultiResolution() const;
+ /**
+ * Get the HAL stream group id for a multi-resolution stream set
+ */
+ int getHalStreamGroupId() const;
/**
* Get the stream's dimensions and format
@@ -356,10 +364,13 @@
* For bidirectional streams, this method applies to the input-side
* buffers.
*
+ * This method also returns the size of the returned input buffer.
+ *
* Normally this call will block until the handed out buffer count is less than the stream
* max buffer count; if respectHalLimit is set to false, this is ignored.
*/
- status_t getInputBuffer(camera_stream_buffer *buffer, bool respectHalLimit = true);
+ status_t getInputBuffer(camera_stream_buffer *buffer,
+ Size* size, bool respectHalLimit = true);
/**
* Return a buffer to the stream after use by the HAL.
@@ -487,7 +498,7 @@
Camera3Stream(int id, camera_stream_type type,
uint32_t width, uint32_t height, size_t maxSize, int format,
android_dataspace dataSpace, camera_stream_rotation_t rotation,
- const String8& physicalCameraId, int setId);
+ const String8& physicalCameraId, int setId, bool isMultiResolution);
wp<Camera3StreamBufferFreedListener> mBufferFreedListener;
@@ -509,7 +520,7 @@
virtual status_t getBuffersLocked(std::vector<OutstandingBuffer>*);
- virtual status_t getInputBufferLocked(camera_stream_buffer *buffer);
+ virtual status_t getInputBufferLocked(camera_stream_buffer *buffer, Size* size);
virtual status_t returnInputBufferLocked(
const camera_stream_buffer &buffer);
@@ -608,6 +619,7 @@
String8 mPhysicalCameraId;
nsecs_t mLastTimestamp;
+ bool mIsMultiResolution = false;
bool mSupportOfflineProcessing = false;
}; // class Camera3Stream
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index c558b07..a567cb4 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -72,6 +72,12 @@
int release_fence;
} camera_stream_buffer_t;
+struct Size {
+ uint32_t width;
+ uint32_t height;
+ explicit Size(uint32_t w = 0, uint32_t h = 0) : width(w), height(h){}
+};
+
enum {
/**
* This stream set ID indicates that the set ID is invalid, and this stream doesn't intend to
@@ -352,7 +358,8 @@
* Normally this call will block until the handed out buffer count is less than the stream
* max buffer count; if respectHalLimit is set to false, this is ignored.
*/
- virtual status_t getInputBuffer(camera_stream_buffer *buffer, bool respectHalLimit = true) = 0;
+ virtual status_t getInputBuffer(camera_stream_buffer *buffer,
+ Size *size, bool respectHalLimit = true) = 0;
/**
* Return a buffer to the stream after use by the HAL.