diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp index 41c953bbe2..3d56cd2328 100644 --- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp +++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp @@ -89,12 +89,27 @@ void FrameProcessorBase::dump(int fd, const Vector& /*args*/) { write(fd, result.string(), result.size()); CameraMetadata lastFrame; + std::map lastPhysicalFrames; { // Don't race while dumping metadata Mutex::Autolock al(mLastFrameMutex); lastFrame = CameraMetadata(mLastFrame); + + for (const auto& physicalFrame : mLastPhysicalFrames) { + lastPhysicalFrames.emplace(String8(physicalFrame.mPhysicalCameraId), + physicalFrame.mPhysicalCameraMetadata); + } + } + lastFrame.dump(fd, /*verbosity*/2, /*indentation*/6); + + for (const auto& physicalFrame : lastPhysicalFrames) { + result = String8::format(" Latest received frame for physical camera %s:\n", + physicalFrame.first.c_str()); + write(fd, result.string(), result.size()); + CameraMetadata lastPhysicalMetadata = CameraMetadata(physicalFrame.second); + lastPhysicalMetadata.sort(); + lastPhysicalMetadata.dump(fd, /*verbosity*/2, /*indentation*/6); } - lastFrame.dump(fd, 2, 6); } bool FrameProcessorBase::threadLoop() { @@ -145,6 +160,8 @@ void FrameProcessorBase::processNewFrames(const sp &device) { if (!result.mMetadata.isEmpty()) { Mutex::Autolock al(mLastFrameMutex); mLastFrame.acquire(result.mMetadata); + + mLastPhysicalFrames = std::move(result.mPhysicalMetadatas); } } if (res != NOT_ENOUGH_DATA) { diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.h b/services/camera/libcameraservice/common/FrameProcessorBase.h index 00763a4cc2..ae6d15d3e5 100644 --- a/services/camera/libcameraservice/common/FrameProcessorBase.h +++ b/services/camera/libcameraservice/common/FrameProcessorBase.h @@ -83,6 +83,8 @@ class FrameProcessorBase: public Thread { const sp &device); CameraMetadata mLastFrame; + std::vector mLastPhysicalFrames; + }; diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 415b2d80a5..dcbcabaa52 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -1306,7 +1306,7 @@ status_t Camera3Device::readOneCameraMetadataLocked( void Camera3Device::processOneCaptureResultLocked( const hardware::camera::device::V3_2::CaptureResult& result, const hardware::hidl_vec< - hardware::camera::device::V3_4::PhysicalCameraMetadata> physicalCameraMetadatas) { + hardware::camera::device::V3_4::PhysicalCameraMetadata> physicalCameraMetadata) { camera3_capture_result r; status_t res; r.frame_number = result.frameNumber; @@ -1322,21 +1322,21 @@ void Camera3Device::processOneCaptureResultLocked( r.result = reinterpret_cast(resultMetadata.data()); // Read and validate physical camera metadata - size_t physResultCount = physicalCameraMetadatas.size(); + size_t physResultCount = physicalCameraMetadata.size(); std::vector physCamIds(physResultCount); std::vector phyCamMetadatas(physResultCount); std::vector physResultMetadata; physResultMetadata.resize(physResultCount); - for (size_t i = 0; i < physicalCameraMetadatas.size(); i++) { - res = readOneCameraMetadataLocked(physicalCameraMetadatas[i].fmqMetadataSize, - physResultMetadata[i], physicalCameraMetadatas[i].metadata); + for (size_t i = 0; i < physicalCameraMetadata.size(); i++) { + res = readOneCameraMetadataLocked(physicalCameraMetadata[i].fmqMetadataSize, + physResultMetadata[i], physicalCameraMetadata[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()); + physicalCameraMetadata[i].physicalCameraId.c_str()); return; } - physCamIds[i] = physicalCameraMetadatas[i].physicalCameraId.c_str(); + physCamIds[i] = physicalCameraMetadata[i].physicalCameraId.c_str(); phyCamMetadatas[i] = reinterpret_cast( physResultMetadata[i].data()); } @@ -3420,6 +3420,14 @@ void Camera3Device::insertResultLocked(CaptureResult *result, return; } + // Update vendor tag id for physical metadata + for (auto& physicalMetadata : result->mPhysicalMetadatas) { + camera_metadata_t *pmeta = const_cast( + physicalMetadata.mPhysicalCameraMetadata.getAndLock()); + set_camera_metadata_vendor_id(pmeta, mVendorTagId); + physicalMetadata.mPhysicalCameraMetadata.unlock(pmeta); + } + // Valid result, insert into queue List::iterator queuedResult = mResultQueue.insert(mResultQueue.end(), CaptureResult(*result)); @@ -3551,8 +3559,14 @@ void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, } } + std::unordered_map monitoredPhysicalMetadata; + for (auto& m : physicalMetadatas) { + monitoredPhysicalMetadata.emplace(String8(m.mPhysicalCameraId).string(), + CameraMetadata(m.mPhysicalCameraMetadata)); + } mTagMonitor.monitorMetadata(TagMonitor::RESULT, - frameNumber, timestamp.data.i64[0], captureResult.mMetadata); + frameNumber, timestamp.data.i64[0], captureResult.mMetadata, + monitoredPhysicalMetadata); insertResultLocked(&captureResult, frameNumber); } @@ -3966,8 +3980,11 @@ CameraMetadata Camera3Device::getLatestRequestLocked() { void Camera3Device::monitorMetadata(TagMonitor::eventSource source, - int64_t frameNumber, nsecs_t timestamp, const CameraMetadata& metadata) { - mTagMonitor.monitorMetadata(source, frameNumber, timestamp, metadata); + int64_t frameNumber, nsecs_t timestamp, const CameraMetadata& metadata, + const std::unordered_map& physicalMetadata) { + + mTagMonitor.monitorMetadata(source, frameNumber, timestamp, metadata, + physicalMetadata); } /** @@ -5107,28 +5124,7 @@ bool Camera3Device::RequestThread::sendRequestsBatch() { NextRequest& nextRequest = mNextRequests.editItemAt(i); nextRequest.submitted = true; - - // Update the latest request sent to HAL - if (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchanged - Mutex::Autolock al(mLatestRequestMutex); - - camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings); - mLatestRequest.acquire(cloned); - - sp parent = mParent.promote(); - if (parent != NULL) { - parent->monitorMetadata(TagMonitor::REQUEST, - nextRequest.halRequest.frame_number, - 0, mLatestRequest); - } - } - - if (nextRequest.halRequest.settings != NULL) { - nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock( - nextRequest.halRequest.settings); - } - - cleanupPhysicalSettings(nextRequest.captureRequest, &nextRequest.halRequest); + updateNextRequest(nextRequest); if (!triggerRemoveFailed) { // Remove any previously queued triggers (after unlock) @@ -5183,26 +5179,7 @@ bool Camera3Device::RequestThread::sendRequestsOneByOne() { // Mark that the request has be submitted successfully. nextRequest.submitted = true; - // Update the latest request sent to HAL - if (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchanged - Mutex::Autolock al(mLatestRequestMutex); - - camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings); - mLatestRequest.acquire(cloned); - - sp parent = mParent.promote(); - if (parent != NULL) { - parent->monitorMetadata(TagMonitor::REQUEST, nextRequest.halRequest.frame_number, - 0, mLatestRequest); - } - } - - if (nextRequest.halRequest.settings != NULL) { - nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock( - nextRequest.halRequest.settings); - } - - cleanupPhysicalSettings(nextRequest.captureRequest, &nextRequest.halRequest); + updateNextRequest(nextRequest); // Remove any previously queued triggers (after unlock) res = removeTriggers(mPrevRequest); @@ -5264,6 +5241,37 @@ bool Camera3Device::RequestThread::skipHFRTargetFPSUpdate(int32_t tag, return false; } +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 + Mutex::Autolock al(mLatestRequestMutex); + + camera_metadata_t* cloned = clone_camera_metadata(nextRequest.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], + CameraMetadata(cloned)); + } + + sp parent = mParent.promote(); + if (parent != NULL) { + parent->monitorMetadata(TagMonitor::REQUEST, + nextRequest.halRequest.frame_number, + 0, mLatestRequest, mLatestPhysicalRequest); + } + } + + if (nextRequest.halRequest.settings != NULL) { + nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock( + nextRequest.halRequest.settings); + } + + cleanupPhysicalSettings(nextRequest.captureRequest, &nextRequest.halRequest); +} + bool Camera3Device::RequestThread::updateSessionParameters(const CameraMetadata& settings) { ATRACE_CALL(); bool updatesDetected = false; diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index f8245df821..6376e6fd2e 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -554,7 +554,7 @@ class Camera3Device : void processOneCaptureResultLocked( const hardware::camera::device::V3_2::CaptureResult& result, const hardware::hidl_vec< - hardware::camera::device::V3_4::PhysicalCameraMetadata> physicalCameraMetadatas); + hardware::camera::device::V3_4::PhysicalCameraMetadata> physicalCameraMetadata); status_t readOneCameraMetadataLocked(uint64_t fmqResultSize, hardware::camera::device::V3_2::CameraMetadata& resultMetadata, const hardware::camera::device::V3_2::CameraMetadata& result); @@ -910,8 +910,8 @@ class Camera3Device : bool skipHFRTargetFPSUpdate(int32_t tag, const camera_metadata_ro_entry_t& newEntry, const camera_metadata_entry_t& currentEntry); - // Re-configure camera using the latest session parameters. - bool reconfigureCamera(); + // Update next request sent to HAL + void updateNextRequest(NextRequest& nextRequest); wp mParent; wp mStatusTracker; @@ -955,6 +955,7 @@ class Camera3Device : // android.request.id for latest process_capture_request int32_t mLatestRequestId; CameraMetadata mLatestRequest; + std::unordered_map mLatestPhysicalRequest; typedef KeyedVector TriggerMap; Mutex mTriggerMutex; @@ -1263,7 +1264,8 @@ class Camera3Device : TagMonitor mTagMonitor; void monitorMetadata(TagMonitor::eventSource source, int64_t frameNumber, - nsecs_t timestamp, const CameraMetadata& metadata); + nsecs_t timestamp, const CameraMetadata& metadata, + const std::unordered_map& physicalMetadata); metadata_vendor_id_t mVendorTagId; diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp index 2e909a04ad..ef0d919310 100644 --- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp +++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp @@ -82,6 +82,9 @@ void Camera3IOStreamBase::dump(int fd, const Vector &args) const { lines.appendFormat(" Max size: %zu\n", mMaxSize); lines.appendFormat(" Combined usage: %" PRIu64 ", max HAL buffers: %d\n", mUsage | consumerUsage, camera3_stream::max_buffers); + if (strlen(camera3_stream::physical_camera_id) > 0) { + lines.appendFormat(" Physical camera id: %s\n", camera3_stream::physical_camera_id); + } lines.appendFormat(" Frames produced: %d, last timestamp: %" PRId64 " ns\n", mFrameCount, mLastTimestamp); lines.appendFormat(" Total buffers: %zu, currently dequeued: %zu\n", diff --git a/services/camera/libcameraservice/utils/TagMonitor.cpp b/services/camera/libcameraservice/utils/TagMonitor.cpp index f4c49ec995..4037a669cc 100644 --- a/services/camera/libcameraservice/utils/TagMonitor.cpp +++ b/services/camera/libcameraservice/utils/TagMonitor.cpp @@ -100,10 +100,13 @@ void TagMonitor::disableMonitoring() { mMonitoringEnabled = false; mLastMonitoredRequestValues.clear(); mLastMonitoredResultValues.clear(); + mLastMonitoredPhysicalRequestKeys.clear(); + mLastMonitoredPhysicalResultKeys.clear(); } void TagMonitor::monitorMetadata(eventSource source, int64_t frameNumber, nsecs_t timestamp, - const CameraMetadata& metadata) { + const CameraMetadata& metadata, + const std::unordered_map& physicalMetadata) { if (!mMonitoringEnabled) return; std::lock_guard lock(mMonitorMutex); @@ -112,62 +115,77 @@ void TagMonitor::monitorMetadata(eventSource source, int64_t frameNumber, nsecs_ timestamp = systemTime(SYSTEM_TIME_BOOTTIME); } + std::string emptyId; for (auto tag : mMonitoredTagList) { - camera_metadata_ro_entry entry = metadata.find(tag); - CameraMetadata &lastValues = (source == REQUEST) ? - mLastMonitoredRequestValues : mLastMonitoredResultValues; - if (lastValues.isEmpty()) { - lastValues = CameraMetadata(mMonitoredTagList.size()); - const camera_metadata_t *metaBuffer = - lastValues.getAndLock(); - set_camera_metadata_vendor_id( - const_cast (metaBuffer), mVendorTagId); - lastValues.unlock(metaBuffer); + monitorSingleMetadata(source, frameNumber, timestamp, emptyId, tag, metadata); + + for (auto& m : physicalMetadata) { + monitorSingleMetadata(source, frameNumber, timestamp, m.first, tag, m.second); } + } +} - camera_metadata_entry lastEntry = lastValues.find(tag); - - if (entry.count > 0) { - bool isDifferent = false; - if (lastEntry.count > 0) { - // Have a last value, compare to see if changed - if (lastEntry.type == entry.type && - lastEntry.count == entry.count) { - // Same type and count, compare values - size_t bytesPerValue = camera_metadata_type_size[lastEntry.type]; - size_t entryBytes = bytesPerValue * lastEntry.count; - int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes); - if (cmp != 0) { - isDifferent = true; - } - } else { - // Count or type has changed +void TagMonitor::monitorSingleMetadata(eventSource source, int64_t frameNumber, nsecs_t timestamp, + const std::string& cameraId, uint32_t tag, const CameraMetadata& metadata) { + + CameraMetadata &lastValues = (source == REQUEST) ? + (cameraId.empty() ? mLastMonitoredRequestValues : + mLastMonitoredPhysicalRequestKeys[cameraId]) : + (cameraId.empty() ? mLastMonitoredResultValues : + mLastMonitoredPhysicalResultKeys[cameraId]); + + camera_metadata_ro_entry entry = metadata.find(tag); + if (lastValues.isEmpty()) { + lastValues = CameraMetadata(mMonitoredTagList.size()); + const camera_metadata_t *metaBuffer = + lastValues.getAndLock(); + set_camera_metadata_vendor_id( + const_cast (metaBuffer), mVendorTagId); + lastValues.unlock(metaBuffer); + } + + camera_metadata_entry lastEntry = lastValues.find(tag); + + if (entry.count > 0) { + bool isDifferent = false; + if (lastEntry.count > 0) { + // Have a last value, compare to see if changed + if (lastEntry.type == entry.type && + lastEntry.count == entry.count) { + // Same type and count, compare values + size_t bytesPerValue = camera_metadata_type_size[lastEntry.type]; + size_t entryBytes = bytesPerValue * lastEntry.count; + int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes); + if (cmp != 0) { isDifferent = true; } } else { - // No last entry, so always consider to be different + // Count or type has changed isDifferent = true; } + } else { + // No last entry, so always consider to be different + isDifferent = true; + } - if (isDifferent) { - ALOGV("%s: Tag %s changed", __FUNCTION__, - get_local_camera_metadata_tag_name_vendor_id( - tag, mVendorTagId)); - lastValues.update(entry); - mMonitoringEvents.emplace(source, frameNumber, timestamp, entry); - } - } else if (lastEntry.count > 0) { - // Value has been removed - ALOGV("%s: Tag %s removed", __FUNCTION__, + if (isDifferent) { + ALOGV("%s: Tag %s changed", __FUNCTION__, get_local_camera_metadata_tag_name_vendor_id( tag, mVendorTagId)); - lastValues.erase(tag); - entry.tag = tag; - entry.type = get_local_camera_metadata_tag_type_vendor_id(tag, - mVendorTagId); - entry.count = 0; - mMonitoringEvents.emplace(source, frameNumber, timestamp, entry); + lastValues.update(entry); + mMonitoringEvents.emplace(source, frameNumber, timestamp, entry, cameraId); } + } else if (lastEntry.count > 0) { + // Value has been removed + ALOGV("%s: Tag %s removed", __FUNCTION__, + get_local_camera_metadata_tag_name_vendor_id( + tag, mVendorTagId)); + lastValues.erase(tag); + entry.tag = tag; + entry.type = get_local_camera_metadata_tag_type_vendor_id(tag, + mVendorTagId); + entry.count = 0; + mMonitoringEvents.emplace(source, frameNumber, timestamp, entry, cameraId); } } @@ -190,8 +208,9 @@ void TagMonitor::dumpMonitoredMetadata(int fd) { dprintf(fd, " Monitored tag event log:\n"); for (const auto& event : mMonitoringEvents) { int indentation = (event.source == REQUEST) ? 15 : 30; - dprintf(fd, " f%d:%" PRId64 "ns: %*s%s.%s: ", + dprintf(fd, " f%d:%" PRId64 "ns:%*s%*s%s.%s: ", event.frameNumber, event.timestamp, + 2, event.cameraId.c_str(), indentation, event.source == REQUEST ? "REQ:" : "RES:", get_local_camera_metadata_section_name_vendor_id(event.tag, @@ -296,13 +315,14 @@ void TagMonitor::printData(int fd, const uint8_t *data_ptr, uint32_t tag, template TagMonitor::MonitorEvent::MonitorEvent(eventSource src, uint32_t frameNumber, nsecs_t timestamp, - const T &value) : + const T &value, const std::string& cameraId) : source(src), frameNumber(frameNumber), timestamp(timestamp), tag(value.tag), type(value.type), - newData(value.data.u8, value.data.u8 + camera_metadata_type_size[value.type] * value.count) { + newData(value.data.u8, value.data.u8 + camera_metadata_type_size[value.type] * value.count), + cameraId(cameraId) { } TagMonitor::MonitorEvent::~MonitorEvent() { diff --git a/services/camera/libcameraservice/utils/TagMonitor.h b/services/camera/libcameraservice/utils/TagMonitor.h index 2dece6209a..1b7b0330fe 100644 --- a/services/camera/libcameraservice/utils/TagMonitor.h +++ b/services/camera/libcameraservice/utils/TagMonitor.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -62,7 +63,8 @@ class TagMonitor { // Scan through the metadata and update the monitoring information void monitorMetadata(eventSource source, int64_t frameNumber, - nsecs_t timestamp, const CameraMetadata& metadata); + nsecs_t timestamp, const CameraMetadata& metadata, + const std::unordered_map& physicalMetadata); // Dump current event log to the provided fd void dumpMonitoredMetadata(int fd); @@ -72,6 +74,10 @@ class TagMonitor { static void printData(int fd, const uint8_t *data_ptr, uint32_t tag, int type, int count, int indentation); + void monitorSingleMetadata(TagMonitor::eventSource source, int64_t frameNumber, + nsecs_t timestamp, const std::string& cameraId, uint32_t tag, + const CameraMetadata& metadata); + std::atomic mMonitoringEnabled; std::mutex mMonitorMutex; @@ -82,6 +88,9 @@ class TagMonitor { CameraMetadata mLastMonitoredRequestValues; CameraMetadata mLastMonitoredResultValues; + std::unordered_map mLastMonitoredPhysicalRequestKeys; + std::unordered_map mLastMonitoredPhysicalResultKeys; + /** * A monitoring event * Stores a new metadata field value and the timestamp at which it changed. @@ -90,7 +99,7 @@ class TagMonitor { struct MonitorEvent { template MonitorEvent(eventSource src, uint32_t frameNumber, nsecs_t timestamp, - const T &newValue); + const T &newValue, const std::string& cameraId); ~MonitorEvent(); eventSource source; @@ -99,6 +108,7 @@ class TagMonitor { uint32_t tag; uint8_t type; std::vector newData; + std::string cameraId; }; // A ring buffer for tracking the last kMaxMonitorEvents metadata changes