Camera: Support physical camera metadata in capture result
- Add physical camera metadata in capture result.
- Adjust capture_result book-keeping for physical capture result.
- Adapt to new version of ICameraDeviceCallback.
- Batch physical metadata with logical metadata within one
process_capture_result call.
Test: testLogicalCameraTest CTS test
Bug: 64691172
Change-Id: I63fd343770cbb6183b7c6e4566c698f69801a8e8
diff --git a/camera/CaptureResult.cpp b/camera/CaptureResult.cpp
index e6c0d00..928a6bc 100644
--- a/camera/CaptureResult.cpp
+++ b/camera/CaptureResult.cpp
@@ -60,6 +60,39 @@
return OK;
}
+status_t PhysicalCaptureResultInfo::readFromParcel(const android::Parcel* parcel) {
+ status_t res;
+
+ mPhysicalCameraId.remove(mPhysicalCameraId.size());
+ mPhysicalCameraMetadata.clear();
+
+ if ((res = parcel->readString16(&mPhysicalCameraId)) != OK) {
+ ALOGE("%s: Failed to read camera id: %d", __FUNCTION__, res);
+ return res;
+ }
+
+ if ((res = mPhysicalCameraMetadata.readFromParcel(parcel)) != OK) {
+ ALOGE("%s: Failed to read metadata from parcel: %d", __FUNCTION__, res);
+ return res;
+ }
+ return OK;
+}
+
+status_t PhysicalCaptureResultInfo::writeToParcel(android::Parcel* parcel) const {
+ status_t res;
+ if ((res = parcel->writeString16(mPhysicalCameraId)) != OK) {
+ ALOGE("%s: Failed to write physical camera ID to parcel: %d",
+ __FUNCTION__, res);
+ return res;
+ }
+ if ((res = mPhysicalCameraMetadata.writeToParcel(parcel)) != OK) {
+ ALOGE("%s: Failed to write physical camera metadata to parcel: %d",
+ __FUNCTION__, res);
+ return res;
+ }
+ return OK;
+}
+
CaptureResult::CaptureResult() :
mMetadata(), mResultExtras() {
}
@@ -67,6 +100,7 @@
CaptureResult::CaptureResult(const CaptureResult &otherResult) {
mResultExtras = otherResult.mResultExtras;
mMetadata = otherResult.mMetadata;
+ mPhysicalMetadatas = otherResult.mPhysicalMetadatas;
}
status_t CaptureResult::readFromParcel(android::Parcel *parcel) {
@@ -79,6 +113,7 @@
}
mMetadata.clear();
+ mPhysicalMetadatas.clear();
status_t res = OK;
res = mMetadata.readFromParcel(parcel);
@@ -89,6 +124,34 @@
}
ALOGV("%s: Read metadata from parcel", __FUNCTION__);
+ int32_t physicalMetadataCount;
+ if ((res = parcel->readInt32(&physicalMetadataCount)) != OK) {
+ ALOGE("%s: Failed to read the physical metadata count from parcel: %d", __FUNCTION__, res);
+ return res;
+ }
+ if (physicalMetadataCount < 0) {
+ ALOGE("%s: Invalid physical metadata count from parcel: %d",
+ __FUNCTION__, physicalMetadataCount);
+ return BAD_VALUE;
+ }
+
+ for (int32_t i = 0; i < physicalMetadataCount; i++) {
+ String16 cameraId;
+ if ((res = parcel->readString16(&cameraId)) != OK) {
+ ALOGE("%s: Failed to read camera id: %d", __FUNCTION__, res);
+ return res;
+ }
+
+ CameraMetadata physicalMetadata;
+ if ((res = physicalMetadata.readFromParcel(parcel)) != OK) {
+ ALOGE("%s: Failed to read metadata from parcel: %d", __FUNCTION__, res);
+ return res;
+ }
+
+ mPhysicalMetadatas.emplace(mPhysicalMetadatas.end(), cameraId, physicalMetadata);
+ }
+ ALOGV("%s: Read physical metadata from parcel", __FUNCTION__);
+
res = mResultExtras.readFromParcel(parcel);
if (res != OK) {
ALOGE("%s: Failed to read result extras from parcel.",
@@ -118,6 +181,27 @@
}
ALOGV("%s: Wrote metadata to parcel", __FUNCTION__);
+ int32_t physicalMetadataCount = static_cast<int32_t>(mPhysicalMetadatas.size());
+ res = parcel->writeInt32(physicalMetadataCount);
+ if (res != OK) {
+ ALOGE("%s: Failed to write physical metadata count to parcel: %d",
+ __FUNCTION__, res);
+ return BAD_VALUE;
+ }
+ for (const auto& physicalMetadata : mPhysicalMetadatas) {
+ if ((res = parcel->writeString16(physicalMetadata.mPhysicalCameraId)) != OK) {
+ ALOGE("%s: Failed to write physical camera ID to parcel: %d",
+ __FUNCTION__, res);
+ return res;
+ }
+ if ((res = physicalMetadata.mPhysicalCameraMetadata.writeToParcel(parcel)) != OK) {
+ ALOGE("%s: Failed to write physical camera metadata to parcel: %d",
+ __FUNCTION__, res);
+ return res;
+ }
+ }
+ ALOGV("%s: Wrote physical camera metadata to parcel", __FUNCTION__);
+
res = mResultExtras.writeToParcel(parcel);
if (res != OK) {
ALOGE("%s: Failed to write result extras to parcel", __FUNCTION__);
diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
index 4db7f85..58b19a3 100644
--- a/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
+++ b/camera/aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl
@@ -18,6 +18,7 @@
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
+import android.hardware.camera2.impl.PhysicalCaptureResultInfo;
/** @hide */
interface ICameraDeviceCallbacks
@@ -36,7 +37,8 @@
oneway void onDeviceIdle();
oneway void onCaptureStarted(in CaptureResultExtras resultExtras, long timestamp);
oneway void onResultReceived(in CameraMetadataNative result,
- in CaptureResultExtras resultExtras);
+ in CaptureResultExtras resultExtras,
+ in PhysicalCaptureResultInfo[] physicalCaptureResultInfos);
oneway void onPrepared(int streamId);
/**
diff --git a/camera/aidl/android/hardware/camera2/impl/PhysicalCaptureResultInfo.aidl b/camera/aidl/android/hardware/camera2/impl/PhysicalCaptureResultInfo.aidl
new file mode 100644
index 0000000..78d9b7b
--- /dev/null
+++ b/camera/aidl/android/hardware/camera2/impl/PhysicalCaptureResultInfo.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera2.impl;
+
+/** @hide */
+parcelable PhysicalCaptureResultInfo cpp_header "camera/CaptureResult.h";
diff --git a/camera/include/camera/CaptureResult.h b/camera/include/camera/CaptureResult.h
index 917d953..56fa178 100644
--- a/camera/include/camera/CaptureResult.h
+++ b/camera/include/camera/CaptureResult.h
@@ -91,14 +91,36 @@
virtual status_t readFromParcel(const android::Parcel* parcel) override;
virtual status_t writeToParcel(android::Parcel* parcel) const override;
};
+
+struct PhysicalCaptureResultInfo : public android::Parcelable {
+
+ PhysicalCaptureResultInfo()
+ : mPhysicalCameraId(),
+ mPhysicalCameraMetadata() {
+ }
+ PhysicalCaptureResultInfo(const String16& cameraId,
+ const CameraMetadata& cameraMetadata)
+ : mPhysicalCameraId(cameraId),
+ mPhysicalCameraMetadata(cameraMetadata) {
+ }
+
+ String16 mPhysicalCameraId;
+ CameraMetadata mPhysicalCameraMetadata;
+
+ virtual status_t readFromParcel(const android::Parcel* parcel) override;
+ virtual status_t writeToParcel(android::Parcel* parcel) const override;
+};
+
} // namespace impl
} // namespace camera2
} // namespace hardware
using hardware::camera2::impl::CaptureResultExtras;
+using hardware::camera2::impl::PhysicalCaptureResultInfo;
struct CaptureResult : public virtual LightRefBase<CaptureResult> {
CameraMetadata mMetadata;
+ std::vector<PhysicalCaptureResultInfo> mPhysicalMetadatas;
CaptureResultExtras mResultExtras;
CaptureResult();
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index ef1c61f..907debc 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -1406,7 +1406,9 @@
binder::Status
CameraDevice::ServiceCallback::onResultReceived(
const CameraMetadata& metadata,
- const CaptureResultExtras& resultExtras) {
+ const CaptureResultExtras& resultExtras,
+ const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
+ (void) physicalResultInfos;
binder::Status ret = binder::Status::ok();
sp<CameraDevice> dev = mDevice.promote();
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 1db3dfb..1369148 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -74,7 +74,8 @@
binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras,
int64_t timestamp) override;
binder::Status onResultReceived(const CameraMetadata& metadata,
- const CaptureResultExtras& resultExtras) override;
+ const CaptureResultExtras& resultExtras,
+ const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) override;
binder::Status onPrepared(int streamId) override;
binder::Status onRequestQueueEmpty() override;
binder::Status onRepeatingRequestError(int64_t lastFrameNumber,
diff --git a/camera/tests/CameraBinderTests.cpp b/camera/tests/CameraBinderTests.cpp
index 24c0c51..1de7013 100644
--- a/camera/tests/CameraBinderTests.cpp
+++ b/camera/tests/CameraBinderTests.cpp
@@ -198,9 +198,11 @@
virtual binder::Status onResultReceived(const CameraMetadata& metadata,
- const CaptureResultExtras& resultExtras) {
+ const CaptureResultExtras& resultExtras,
+ const std::vector<PhysicalCaptureResultInfo>& physicalResultInfos) {
(void) metadata;
(void) resultExtras;
+ (void) physicalResultInfos;
Mutex::Autolock l(mLock);
mLastStatus = SENT_RESULT;
mStatusesHit.push_back(mLastStatus);
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index c36c7cf..1ebaea9 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1697,7 +1697,8 @@
// Thread-safe. No lock necessary.
sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
if (remoteCb != NULL) {
- remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
+ remoteCb->onResultReceived(result.mMetadata, result.mResultExtras,
+ result.mPhysicalMetadatas);
}
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 999e258..b868fa6 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -39,6 +39,8 @@
#include <inttypes.h>
+#include <utility>
+
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Timers.h>
@@ -874,11 +876,9 @@
return res;
}
-// Only one processCaptureResult should be called at a time, so
-// the locks won't block. The locks are present here simply to enforce this.
-hardware::Return<void> Camera3Device::processCaptureResult(
+hardware::Return<void> Camera3Device::processCaptureResult_3_4(
const hardware::hidl_vec<
- hardware::camera::device::V3_2::CaptureResult>& results) {
+ hardware::camera::device::V3_4::CaptureResult>& results) {
// Ideally we should grab mLock, but that can lead to deadlock, and
// it's not super important to get up to date value of mStatus for this
// warning print, hence skipping the lock here
@@ -902,45 +902,121 @@
}
}
for (const auto& result : results) {
- processOneCaptureResultLocked(result);
+ processOneCaptureResultLocked(result.v3_2, result.physicalCameraMetadata);
}
mProcessCaptureResultLock.unlock();
return hardware::Void();
}
+// Only one processCaptureResult should be called at a time, so
+// the locks won't block. The locks are present here simply to enforce this.
+hardware::Return<void> Camera3Device::processCaptureResult(
+ const hardware::hidl_vec<
+ hardware::camera::device::V3_2::CaptureResult>& results) {
+ hardware::hidl_vec<hardware::camera::device::V3_4::PhysicalCameraMetadata> noPhysMetadata;
+
+ // Ideally we should grab mLock, but that can lead to deadlock, and
+ // it's not super important to get up to date value of mStatus for this
+ // warning print, hence skipping the lock here
+ if (mStatus == STATUS_ERROR) {
+ // Per API contract, HAL should act as closed after device error
+ // But mStatus can be set to error by framework as well, so just log
+ // a warning here.
+ ALOGW("%s: received capture result in error state.", __FUNCTION__);
+ }
+
+ if (mProcessCaptureResultLock.tryLock() != OK) {
+ // This should never happen; it indicates a wrong client implementation
+ // that doesn't follow the contract. But, we can be tolerant here.
+ ALOGE("%s: callback overlapped! waiting 1s...",
+ __FUNCTION__);
+ if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
+ ALOGE("%s: cannot acquire lock in 1s, dropping results",
+ __FUNCTION__);
+ // really don't know what to do, so bail out.
+ return hardware::Void();
+ }
+ }
+ for (const auto& result : results) {
+ processOneCaptureResultLocked(result, noPhysMetadata);
+ }
+ mProcessCaptureResultLock.unlock();
+ return hardware::Void();
+}
+
+status_t Camera3Device::readOneCameraMetadataLocked(
+ uint64_t fmqResultSize, hardware::camera::device::V3_2::CameraMetadata& resultMetadata,
+ const hardware::camera::device::V3_2::CameraMetadata& result) {
+ if (fmqResultSize > 0) {
+ resultMetadata.resize(fmqResultSize);
+ if (mResultMetadataQueue == nullptr) {
+ return NO_MEMORY; // logged in initialize()
+ }
+ if (!mResultMetadataQueue->read(resultMetadata.data(), fmqResultSize)) {
+ ALOGE("%s: Cannot read camera metadata from fmq, size = %" PRIu64,
+ __FUNCTION__, fmqResultSize);
+ return INVALID_OPERATION;
+ }
+ } else {
+ resultMetadata.setToExternal(const_cast<uint8_t *>(result.data()),
+ result.size());
+ }
+
+ if (resultMetadata.size() != 0) {
+ status_t res;
+ const camera_metadata_t* metadata =
+ reinterpret_cast<const camera_metadata_t*>(resultMetadata.data());
+ size_t expected_metadata_size = resultMetadata.size();
+ if ((res = validate_camera_metadata_structure(metadata, &expected_metadata_size)) != OK) {
+ ALOGE("%s: Invalid camera metadata received by camera service from HAL: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return INVALID_OPERATION;
+ }
+ }
+
+ return OK;
+}
+
void Camera3Device::processOneCaptureResultLocked(
- const hardware::camera::device::V3_2::CaptureResult& result) {
+ const hardware::camera::device::V3_2::CaptureResult& result,
+ const hardware::hidl_vec<
+ hardware::camera::device::V3_4::PhysicalCameraMetadata> physicalCameraMetadatas) {
camera3_capture_result r;
status_t res;
r.frame_number = result.frameNumber;
+ // Read and validate the result metadata.
hardware::camera::device::V3_2::CameraMetadata resultMetadata;
- if (result.fmqResultSize > 0) {
- resultMetadata.resize(result.fmqResultSize);
- if (mResultMetadataQueue == nullptr) {
- return; // logged in initialize()
- }
- if (!mResultMetadataQueue->read(resultMetadata.data(), result.fmqResultSize)) {
- ALOGE("%s: Frame %d: Cannot read camera metadata from fmq, size = %" PRIu64,
- __FUNCTION__, result.frameNumber, result.fmqResultSize);
- return;
- }
- } else {
- resultMetadata.setToExternal(const_cast<uint8_t *>(result.result.data()),
- result.result.size());
+ res = readOneCameraMetadataLocked(result.fmqResultSize, resultMetadata, result.result);
+ if (res != OK) {
+ ALOGE("%s: Frame %d: Failed to read capture result metadata",
+ __FUNCTION__, result.frameNumber);
+ return;
}
+ r.result = reinterpret_cast<const camera_metadata_t*>(resultMetadata.data());
- if (resultMetadata.size() != 0) {
- r.result = reinterpret_cast<const camera_metadata_t*>(resultMetadata.data());
- size_t expected_metadata_size = resultMetadata.size();
- if ((res = validate_camera_metadata_structure(r.result, &expected_metadata_size)) != OK) {
- ALOGE("%s: Frame %d: Invalid camera metadata received by camera service from HAL: %s (%d)",
- __FUNCTION__, result.frameNumber, strerror(-res), res);
+ // Read and validate physical camera metadata
+ size_t physResultCount = physicalCameraMetadatas.size();
+ std::vector<const char*> physCamIds(physResultCount);
+ std::vector<const camera_metadata_t *> phyCamMetadatas(physResultCount);
+ std::vector<hardware::camera::device::V3_2::CameraMetadata> physResultMetadata;
+ physResultMetadata.resize(physResultCount);
+ for (size_t i = 0; i < physicalCameraMetadatas.size(); i++) {
+ res = readOneCameraMetadataLocked(physicalCameraMetadatas[i].fmqMetadataSize,
+ physResultMetadata[i], physicalCameraMetadatas[i].metadata);
+ if (res != OK) {
+ ALOGE("%s: Frame %d: Failed to read capture result metadata for camera %s",
+ __FUNCTION__, result.frameNumber,
+ physicalCameraMetadatas[i].physicalCameraId.c_str());
return;
}
- } else {
- r.result = nullptr;
+ physCamIds[i] = physicalCameraMetadatas[i].physicalCameraId.c_str();
+ phyCamMetadatas[i] = reinterpret_cast<const camera_metadata_t*>(
+ physResultMetadata[i].data());
}
+ r.num_physcam_metadata = physResultCount;
+ r.physcam_ids = physCamIds.data();
+ r.physcam_metadata = phyCamMetadatas.data();
std::vector<camera3_stream_buffer_t> outputBuffers(result.outputBuffers.size());
std::vector<buffer_handle_t> outputBufferHandles(result.outputBuffers.size());
@@ -1806,6 +1882,7 @@
CaptureResult &result = *(mResultQueue.begin());
frame->mResultExtras = result.mResultExtras;
frame->mMetadata.acquire(result.mMetadata);
+ frame->mPhysicalMetadatas = std::move(result.mPhysicalMetadatas);
mResultQueue.erase(mResultQueue.begin());
return OK;
@@ -2579,13 +2656,14 @@
status_t Camera3Device::registerInFlight(uint32_t frameNumber,
int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
- bool hasAppCallback, nsecs_t maxExpectedDuration) {
+ bool hasAppCallback, nsecs_t maxExpectedDuration,
+ std::set<String8>& physicalCameraIds) {
ATRACE_CALL();
Mutex::Autolock l(mInFlightLock);
ssize_t res;
res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
- hasAppCallback, maxExpectedDuration));
+ hasAppCallback, maxExpectedDuration, physicalCameraIds));
if (res < 0) return res;
if (mInFlightMap.size() == 1) {
@@ -2825,7 +2903,8 @@
CaptureResultExtras &resultExtras,
CameraMetadata &collectedPartialResult,
uint32_t frameNumber,
- bool reprocess) {
+ bool reprocess,
+ const std::vector<PhysicalCaptureResultInfo>& physicalMetadatas) {
ATRACE_CALL();
if (pendingMetadata.isEmpty())
return;
@@ -2854,6 +2933,7 @@
CaptureResult captureResult;
captureResult.mResultExtras = resultExtras;
captureResult.mMetadata = pendingMetadata;
+ captureResult.mPhysicalMetadatas = physicalMetadatas;
// Append any previous partials to form a complete result
if (mUsePartialResult && !collectedPartialResult.isEmpty()) {
@@ -2869,6 +2949,15 @@
frameNumber);
return;
}
+ for (auto& physicalMetadata : captureResult.mPhysicalMetadatas) {
+ camera_metadata_entry timestamp =
+ physicalMetadata.mPhysicalCameraMetadata.find(ANDROID_SENSOR_TIMESTAMP);
+ if (timestamp.count == 0) {
+ SET_ERR("No timestamp provided by HAL for physical camera %s frame %d!",
+ String8(physicalMetadata.mPhysicalCameraId).c_str(), frameNumber);
+ return;
+ }
+ }
mTagMonitor.monitorMetadata(TagMonitor::RESULT,
frameNumber, timestamp.data.i64[0], captureResult.mMetadata);
@@ -2904,7 +2993,6 @@
bool isPartialResult = false;
CameraMetadata collectedPartialResult;
- CaptureResultExtras resultExtras;
bool hasInputBufferInRequest = false;
// Get shutter timestamp and resultExtras from list of in-flight requests,
@@ -2945,6 +3033,11 @@
return;
}
isPartialResult = (result->partial_result < mNumPartialResults);
+ if (isPartialResult && result->num_physcam_metadata) {
+ SET_ERR("Result is malformed for frame %d: partial_result not allowed for"
+ " physical camera result", frameNumber);
+ return;
+ }
if (isPartialResult) {
request.collectedPartialResult.append(result->result);
}
@@ -2961,11 +3054,28 @@
// Did we get the (final) result metadata for this capture?
if (result->result != NULL && !isPartialResult) {
+ if (request.physicalCameraIds.size() != result->num_physcam_metadata) {
+ SET_ERR("Requested physical Camera Ids %d not equal to number of metadata %d",
+ request.physicalCameraIds.size(), result->num_physcam_metadata);
+ return;
+ }
if (request.haveResultMetadata) {
SET_ERR("Called multiple times with metadata for frame %d",
frameNumber);
return;
}
+ for (uint32_t i = 0; i < result->num_physcam_metadata; i++) {
+ String8 physicalId(result->physcam_ids[i]);
+ std::set<String8>::iterator cameraIdIter =
+ request.physicalCameraIds.find(physicalId);
+ if (cameraIdIter != request.physicalCameraIds.end()) {
+ request.physicalCameraIds.erase(cameraIdIter);
+ } else {
+ SET_ERR("Total result for frame %d has already returned for camera %s",
+ frameNumber, physicalId.c_str());
+ return;
+ }
+ }
if (mUsePartialResult &&
!request.collectedPartialResult.isEmpty()) {
collectedPartialResult.acquire(
@@ -3010,15 +3120,21 @@
}
if (result->result != NULL && !isPartialResult) {
+ for (uint32_t i = 0; i < result->num_physcam_metadata; i++) {
+ CameraMetadata physicalMetadata;
+ physicalMetadata.append(result->physcam_metadata[i]);
+ request.physicalMetadatas.push_back({String16(result->physcam_ids[i]),
+ physicalMetadata});
+ }
if (shutterTimestamp == 0) {
request.pendingMetadata = result->result;
request.collectedPartialResult = collectedPartialResult;
- } else if (request.hasCallback) {
+ } else if (request.hasCallback) {
CameraMetadata metadata;
metadata = result->result;
sendCaptureResult(metadata, request.resultExtras,
collectedPartialResult, frameNumber,
- hasInputBufferInRequest);
+ hasInputBufferInRequest, request.physicalMetadatas);
}
}
@@ -3204,7 +3320,7 @@
// send pending result and buffers
sendCaptureResult(r.pendingMetadata, r.resultExtras,
r.collectedPartialResult, msg.frame_number,
- r.hasInputBuffer);
+ r.hasInputBuffer, r.physicalMetadatas);
}
returnOutputBuffers(r.pendingOutputBuffers.array(),
r.pendingOutputBuffers.size(), r.shutterTimestamp);
@@ -3219,7 +3335,6 @@
}
}
-
CameraMetadata Camera3Device::getLatestRequestLocked() {
ALOGV("%s", __FUNCTION__);
@@ -4657,6 +4772,7 @@
outputBuffers->insertAt(camera3_stream_buffer_t(), 0,
captureRequest->mOutputStreams.size());
halRequest->output_buffers = outputBuffers->array();
+ std::set<String8> requestedPhysicalCameras;
for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {
sp<Camera3OutputStreamInterface> outputStream = captureRequest->mOutputStreams.editItemAt(j);
@@ -4687,8 +4803,18 @@
return TIMED_OUT;
}
- halRequest->num_output_buffers++;
+ 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++;
}
totalNumBuffers += halRequest->num_output_buffers;
@@ -4711,7 +4837,8 @@
totalNumBuffers, captureRequest->mResultExtras,
/*hasInput*/halRequest->input_buffer != NULL,
hasCallback,
- calculateMaxExpectedDuration(halRequest->settings));
+ calculateMaxExpectedDuration(halRequest->settings),
+ requestedPhysicalCameras);
ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
", burstId = %" PRId32 ".",
__FUNCTION__,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index bf2a577..bc97510 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -19,6 +19,7 @@
#include <utility>
#include <unordered_map>
+#include <set>
#include <utils/Condition.h>
#include <utils/Errors.h>
@@ -33,6 +34,7 @@
#include <android/hardware/camera/device/3.3/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.4/ICameraDeviceSession.h>
#include <android/hardware/camera/device/3.2/ICameraDeviceCallback.h>
+#include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
#include <fmq/MessageQueue.h>
#include <hardware/camera3.h>
@@ -77,7 +79,7 @@
*/
class Camera3Device :
public CameraDeviceBase,
- virtual public hardware::camera::device::V3_2::ICameraDeviceCallback,
+ virtual public hardware::camera::device::V3_4::ICameraDeviceCallback,
private camera3_callback_ops {
public:
@@ -472,9 +474,11 @@
/**
- * Implementation of android::hardware::camera::device::V3_2::ICameraDeviceCallback
+ * Implementation of android::hardware::camera::device::V3_4::ICameraDeviceCallback
*/
-
+ hardware::Return<void> processCaptureResult_3_4(
+ const hardware::hidl_vec<
+ hardware::camera::device::V3_4::CaptureResult>& results) override;
hardware::Return<void> processCaptureResult(
const hardware::hidl_vec<
hardware::camera::device::V3_2::CaptureResult>& results) override;
@@ -484,7 +488,13 @@
// Handle one capture result. Assume that mProcessCaptureResultLock is held.
void processOneCaptureResultLocked(
- const hardware::camera::device::V3_2::CaptureResult& results);
+ const hardware::camera::device::V3_2::CaptureResult& result,
+ const hardware::hidl_vec<
+ hardware::camera::device::V3_4::PhysicalCameraMetadata> physicalCameraMetadatas);
+ status_t readOneCameraMetadataLocked(uint64_t fmqResultSize,
+ hardware::camera::device::V3_2::CameraMetadata& resultMetadata,
+ const hardware::camera::device::V3_2::CameraMetadata& result);
+
// Handle one notify message
void notify(const hardware::camera::device::V3_2::NotifyMsg& msg);
@@ -965,6 +975,12 @@
// REQUEST/RESULT error.
bool skipResultMetadata;
+ // The physical camera ids being requested.
+ std::set<String8> physicalCameraIds;
+
+ // Map of physicalCameraId <-> Metadata
+ std::vector<PhysicalCaptureResultInfo> physicalMetadatas;
+
// Default constructor needed by KeyedVector
InFlightRequest() :
shutterTimestamp(0),
@@ -979,7 +995,8 @@
}
InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput,
- bool hasAppCallback, nsecs_t maxDuration) :
+ bool hasAppCallback, nsecs_t maxDuration,
+ const std::set<String8>& physicalCameraIdSet) :
shutterTimestamp(0),
sensorTimestamp(0),
requestStatus(OK),
@@ -989,7 +1006,8 @@
hasInputBuffer(hasInput),
hasCallback(hasAppCallback),
maxExpectedDuration(maxDuration),
- skipResultMetadata(false) {
+ skipResultMetadata(false),
+ physicalCameraIds(physicalCameraIdSet) {
}
};
@@ -1006,7 +1024,7 @@
status_t registerInFlight(uint32_t frameNumber,
int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
- bool callback, nsecs_t maxExpectedDuration);
+ bool callback, nsecs_t maxExpectedDuration, std::set<String8>& physicalCameraIds);
/**
* Returns the maximum expected time it'll take for all currently in-flight
@@ -1127,7 +1145,9 @@
void sendCaptureResult(CameraMetadata &pendingMetadata,
CaptureResultExtras &resultExtras,
CameraMetadata &collectedPartialResult, uint32_t frameNumber,
- bool reprocess);
+ bool reprocess, const std::vector<PhysicalCaptureResultInfo>& physicalMetadatas);
+
+ bool isLastFullResult(const InFlightRequest& inFlightRequest);
// Insert the result to the result queue after updating frame number and overriding AE
// trigger cancel.
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
index 44eb68a..fb1ff77 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
@@ -115,6 +115,10 @@
return OK;
}
+const String8& Camera3DummyStream::getPhysicalCameraId() const {
+ return DUMMY_ID;
+}
+
status_t Camera3DummyStream::setConsumers(const std::vector<sp<Surface>>& /*consumers*/) {
ALOGE("%s: Stream %d: Dummy stream doesn't support set consumer surface!",
__FUNCTION__, mId);
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.h b/services/camera/libcameraservice/device3/Camera3DummyStream.h
index dcf9160..4627548 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.h
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.h
@@ -63,6 +63,11 @@
virtual status_t dropBuffers(bool /*dropping*/) override;
/**
+ * Query the physical camera id for the output stream.
+ */
+ virtual const String8& getPhysicalCameraId() const override;
+
+ /**
* Return if this output stream is for video encoding.
*/
bool isVideoStream() const;
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index b73e256..b3c3717 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -806,6 +806,11 @@
return OK;
}
+const String8& Camera3OutputStream::getPhysicalCameraId() const {
+ Mutex::Autolock l(mLock);
+ return physicalCameraId();
+}
+
status_t Camera3OutputStream::notifyBufferReleased(ANativeWindowBuffer* /*anwBuffer*/) {
return OK;
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 824aef7..6f36f92 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -174,6 +174,11 @@
virtual status_t dropBuffers(bool dropping) override;
/**
+ * Query the physical camera id for the output stream.
+ */
+ virtual const String8& getPhysicalCameraId() const override;
+
+ /**
* Set the graphic buffer manager to get/return the stream buffers.
*
* It is only legal to call this method when stream is in STATE_CONSTRUCTED state.
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index 08fcf38..a711a6d 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -78,6 +78,11 @@
* Drop buffers if dropping is true. If dropping is false, do not drop buffers.
*/
virtual status_t dropBuffers(bool /*dropping*/) = 0;
+
+ /**
+ * Query the physical camera id for the output stream.
+ */
+ virtual const String8& getPhysicalCameraId() const = 0;
};
} // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 0d91620..1105b75 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -143,6 +143,10 @@
return mOriginalDataSpace;
}
+const String8& Camera3Stream::physicalCameraId() const {
+ return mPhysicalCameraId;
+}
+
status_t Camera3Stream::forceToIdle() {
ATRACE_CALL();
Mutex::Autolock l(mLock);
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index f85dff2..a60cb56 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -165,6 +165,7 @@
void setDataSpaceOverride(bool dataSpaceOverriden);
bool isDataSpaceOverridden() const;
android_dataspace getOriginalDataSpace() const;
+ const String8& physicalCameraId() const;
camera3_stream* asHalStream() override {
return this;