From dda1eb771c6b52bb9a020bee707560d24a6b04fe Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Thu, 28 Jul 2022 16:37:40 -0700 Subject: [PATCH] Camera: Import gralloc buffers before metadata queries Raw buffer handles do not support metadata queries and need to be imported first. Additionally map the result buffer ids to the inflight buffers and queue the maximum amount of inflight buffers as advertised by Hal. Since we will be streaming a set of buffers, use an appropriate preview size. Bug: 237576060 Test: adb shell /data/nativetest64/VtsAidlHalCameraProvider_TargetTest/VtsAidlHalCameraProvider_TargetTest --gtest_filter=PerInstance/CameraAidlTest.process10BitDynamicRangeRequest/0_android_hardware_camera_provider_ICameraProvider_internal_0 Change-Id: Id854c2a8d1588a151240d1b32197dbace7e1a057 --- camera/common/1.0/default/HandleImporter.cpp | 29 ++++- .../VtsAidlHalCameraProvider_TargetTest.cpp | 110 +++++++++++------- camera/provider/aidl/vts/camera_aidl_test.cpp | 26 +++-- camera/provider/aidl/vts/camera_aidl_test.h | 4 + camera/provider/aidl/vts/device_cb.cpp | 8 +- camera/provider/aidl/vts/device_cb.h | 2 +- 6 files changed, 120 insertions(+), 59 deletions(-) diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp index fbe8686766..d2fdf02457 100644 --- a/camera/common/1.0/default/HandleImporter.cpp +++ b/camera/common/1.0/default/HandleImporter.cpp @@ -18,6 +18,7 @@ #include "HandleImporter.h" #include +#include "aidl/android/hardware/graphics/common/Smpte2086.h" #include namespace android { @@ -30,6 +31,7 @@ namespace helper { using aidl::android::hardware::graphics::common::PlaneLayout; using aidl::android::hardware::graphics::common::PlaneLayoutComponent; using aidl::android::hardware::graphics::common::PlaneLayoutComponentType; +using aidl::android::hardware::graphics::common::Smpte2086; using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType; using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error; using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error; @@ -127,16 +129,35 @@ YCbCrLayout HandleImporter::lockYCbCrInternal(const sp mapper, buffer_handle_ bool isMetadataPesent(const sp mapper, const buffer_handle_t& buf, MetadataType metadataType) { auto buffer = const_cast(buf); - mapper->get(buffer, metadataType, [] (const auto& tmpError, + bool ret = false; + hidl_vec vec; + mapper->get(buffer, metadataType, [&] (const auto& tmpError, const auto& tmpMetadata) { if (tmpError == MapperErrorV4::NONE) { - return tmpMetadata.size() > 0; + vec = tmpMetadata; } else { ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError); - return false; }}); - return false; + if (vec.size() > 0) { + if (metadataType == gralloc4::MetadataType_Smpte2086){ + std::optional realSmpte2086; + gralloc4::decodeSmpte2086(vec, &realSmpte2086); + ret = realSmpte2086.has_value(); + } else if (metadataType == gralloc4::MetadataType_Smpte2094_10) { + std::optional> realSmpte2094_10; + gralloc4::decodeSmpte2094_10(vec, &realSmpte2094_10); + ret = realSmpte2094_10.has_value(); + } else if (metadataType == gralloc4::MetadataType_Smpte2094_40) { + std::optional> realSmpte2094_40; + gralloc4::decodeSmpte2094_40(vec, &realSmpte2094_40); + ret = realSmpte2094_40.has_value(); + } else { + ALOGE("%s: Unknown metadata type!", __FUNCTION__); + } + } + + return ret; } std::vector getPlaneLayouts(const sp mapper, buffer_handle_t& buf) { diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp index fe03732aff..70ab7a02b3 100644 --- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp +++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp @@ -1739,6 +1739,10 @@ TEST_P(CameraAidlTest, processUltraHighResolutionRequest) { std::list pixelFormats = {PixelFormat::YCBCR_420_888, PixelFormat::RAW16}; for (PixelFormat format : pixelFormats) { + previewStream.usage = + static_cast( + GRALLOC1_CONSUMER_USAGE_CPU_READ); + previewStream.dataSpace = Dataspace::UNKNOWN; configureStreams(name, mProvider, format, &mSession, &previewStream, &halStreams, &supportsPartialResults, &partialResultCount, &useHalBufManager, &cb, 0, /*maxResolution*/ true); @@ -1843,7 +1847,6 @@ TEST_P(CameraAidlTest, processUltraHighResolutionRequest) { TEST_P(CameraAidlTest, process10BitDynamicRangeRequest) { std::vector cameraDeviceNames = getCameraDeviceNames(mProvider); int64_t bufferId = 1; - int32_t frameNumber = 1; CameraMetadata settings; for (const auto& name : cameraDeviceNames) { @@ -1866,7 +1869,7 @@ TEST_P(CameraAidlTest, process10BitDynamicRangeRequest) { CameraMetadata req; android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings; ndk::ScopedAStatus ret = - mSession->constructDefaultRequestSettings(RequestTemplate::STILL_CAPTURE, &req); + mSession->constructDefaultRequestSettings(RequestTemplate::PREVIEW, &req); ASSERT_TRUE(ret.isOk()); const camera_metadata_t* metadata = @@ -1896,6 +1899,10 @@ TEST_P(CameraAidlTest, process10BitDynamicRangeRequest) { Stream previewStream; std::shared_ptr cb; for (const auto& profile : profileList) { + previewStream.usage = + static_cast( + GRALLOC1_CONSUMER_USAGE_HWCOMPOSER); + previewStream.dataSpace = getDataspace(PixelFormat::IMPLEMENTATION_DEFINED); configureStreams(name, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, &mSession, &previewStream, &halStreams, &supportsPartialResults, &partialResultCount, &useHalBufManager, &cb, 0, @@ -1916,63 +1923,75 @@ TEST_P(CameraAidlTest, process10BitDynamicRangeRequest) { // Don't use the queue onwards. } - std::vector graphicBuffers; - graphicBuffers.reserve(halStreams.size()); + mInflightMap.clear(); + // Stream as long as needed to fill the Hal inflight queue + std::vector requests(halStreams[0].maxBuffers); - std::shared_ptr inflightReq = std::make_shared( - static_cast(halStreams.size()), false, supportsPartialResults, - partialResultCount, std::unordered_set(), resultQueue); + for (int32_t frameNumber = 0; frameNumber < requests.size(); frameNumber++) { + std::shared_ptr inflightReq = std::make_shared( + static_cast(halStreams.size()), false, supportsPartialResults, + partialResultCount, std::unordered_set(), resultQueue); - std::vector requests(1); - CaptureRequest& request = requests[0]; - std::vector& outputBuffers = request.outputBuffers; - outputBuffers.resize(halStreams.size()); + CaptureRequest& request = requests[frameNumber]; + std::vector& outputBuffers = request.outputBuffers; + outputBuffers.resize(halStreams.size()); - size_t k = 0; - for (const auto& halStream : halStreams) { - buffer_handle_t buffer_handle; - if (useHalBufManager) { - outputBuffers[k] = {halStream.id, 0, - NativeHandle(), BufferStatus::OK, - NativeHandle(), NativeHandle()}; - } else { - allocateGraphicBuffer(previewStream.width, previewStream.height, - android_convertGralloc1To0Usage( - static_cast(halStream.producerUsage), - static_cast(halStream.consumerUsage)), - halStream.overrideFormat, &buffer_handle); + size_t k = 0; + inflightReq->mOutstandingBufferIds.resize(halStreams.size()); + std::vector graphicBuffers; + graphicBuffers.reserve(halStreams.size()); - graphicBuffers.push_back(buffer_handle); - outputBuffers[k] = { - halStream.id, bufferId, android::makeToAidl(buffer_handle), - BufferStatus::OK, NativeHandle(), NativeHandle()}; - bufferId++; + for (const auto& halStream : halStreams) { + buffer_handle_t buffer_handle; + if (useHalBufManager) { + outputBuffers[k] = {halStream.id, 0, + NativeHandle(), BufferStatus::OK, + NativeHandle(), NativeHandle()}; + } else { + auto usage = android_convertGralloc1To0Usage( + static_cast(halStream.producerUsage), + static_cast(halStream.consumerUsage)); + allocateGraphicBuffer(previewStream.width, previewStream.height, usage, + halStream.overrideFormat, &buffer_handle); + + inflightReq->mOutstandingBufferIds[halStream.id][bufferId] = buffer_handle; + graphicBuffers.push_back(buffer_handle); + outputBuffers[k] = {halStream.id, bufferId, + android::makeToAidl(buffer_handle), BufferStatus::OK, NativeHandle(), + NativeHandle()}; + bufferId++; + } + k++; } - k++; - } - request.inputBuffer = { - -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()}; - request.frameNumber = frameNumber; - request.fmqSettingsSize = 0; - request.settings = settings; - request.inputWidth = 0; - request.inputHeight = 0; + request.inputBuffer = { + -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()}; + request.frameNumber = frameNumber; + request.fmqSettingsSize = 0; + request.settings = settings; + request.inputWidth = 0; + request.inputHeight = 0; + + { + std::unique_lock l(mLock); + mInflightMap[frameNumber] = inflightReq; + } - { - std::unique_lock l(mLock); - mInflightMap.clear(); - mInflightMap[frameNumber] = inflightReq; } int32_t numRequestProcessed = 0; std::vector cachesToRemove; ndk::ScopedAStatus returnStatus = - mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed); + mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed); ASSERT_TRUE(returnStatus.isOk()); - ASSERT_EQ(numRequestProcessed, 1u); + ASSERT_EQ(numRequestProcessed, requests.size()); - { + returnStatus = mSession->repeatingRequestEnd(requests.size() - 1, + std::vector {halStreams[0].id}); + ASSERT_TRUE(returnStatus.isOk()); + + for (int32_t frameNumber = 0; frameNumber < requests.size(); frameNumber++) { + const auto& inflightReq = mInflightMap[frameNumber]; std::unique_lock l(mLock); while (!inflightReq->errorCodeValid && ((0 < inflightReq->numBuffersLeft) || (!inflightReq->haveResultMetadata))) { @@ -1985,6 +2004,7 @@ TEST_P(CameraAidlTest, process10BitDynamicRangeRequest) { ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u); verify10BitMetadata(mHandleImporter, *inflightReq, profile); } + if (useHalBufManager) { std::vector streamIds(halStreams.size()); for (size_t i = 0; i < streamIds.size(); i++) { diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp index c11fc0cd2b..20f32bfe21 100644 --- a/camera/provider/aidl/vts/camera_aidl_test.cpp +++ b/camera/provider/aidl/vts/camera_aidl_test.cpp @@ -2639,8 +2639,20 @@ void CameraAidlTest::configureStreams(const std::string& name, outputStreams.clear(); Size maxSize; - auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution); - ASSERT_EQ(Status::OK, rc); + if (maxResolution) { + auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution); + ASSERT_EQ(Status::OK, rc); + } else { + AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight, + static_cast(format)}; + auto rc = getAvailableOutputStreams(staticMeta, outputStreams, &previewThreshold); + + ASSERT_EQ(Status::OK, rc); + ASSERT_FALSE(outputStreams.empty()); + maxSize.width = outputStreams[0].width; + maxSize.height = outputStreams[0].height; + } + std::vector streams(1); streams[0] = {0, @@ -2648,9 +2660,8 @@ void CameraAidlTest::configureStreams(const std::string& name, maxSize.width, maxSize.height, format, - static_cast<::aidl::android::hardware::graphics::common::BufferUsage>( - GRALLOC1_CONSUMER_USAGE_CPU_READ), - Dataspace::UNKNOWN, + previewStream->usage, + previewStream->dataSpace, StreamRotation::ROTATION_0, "", 0, @@ -2736,7 +2747,8 @@ void CameraAidlTest::verify10BitMetadata( HandleImporter& importer, const InFlightRequest& request, aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap profile) { - for (const auto& b : request.resultOutputBuffers) { + for (auto b : request.resultOutputBuffers) { + importer.importBuffer(b.buffer.buffer); bool smpte2086Present = importer.isSmpte2086Present(b.buffer.buffer); bool smpte2094_10Present = importer.isSmpte2094_10Present(b.buffer.buffer); bool smpte2094_40Present = importer.isSmpte2094_40Present(b.buffer.buffer); @@ -2753,7 +2765,6 @@ void CameraAidlTest::verify10BitMetadata( ASSERT_FALSE(smpte2094_40Present); break; case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: - ASSERT_FALSE(smpte2086Present); ASSERT_FALSE(smpte2094_10Present); ASSERT_TRUE(smpte2094_40Present); break; @@ -2774,6 +2785,7 @@ void CameraAidlTest::verify10BitMetadata( profile); ADD_FAILURE(); } + importer.freeBuffer(b.buffer.buffer); } } diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h index ac4b2c9d0e..d828cee4a8 100644 --- a/camera/provider/aidl/vts/camera_aidl_test.h +++ b/camera/provider/aidl/vts/camera_aidl_test.h @@ -399,6 +399,10 @@ class CameraAidlTest : public ::testing::TestWithParam { // Result metadata ::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult; + // Inflight buffers + using OutstandingBuffers = std::unordered_map; + std::vector mOutstandingBufferIds; + // A copy-able StreamBuffer using buffer_handle_t instead of AIDLs NativeHandle struct NativeStreamBuffer { int32_t streamId; diff --git a/camera/provider/aidl/vts/device_cb.cpp b/camera/provider/aidl/vts/device_cb.cpp index e5f2f1eae4..4698b4ae89 100644 --- a/camera/provider/aidl/vts/device_cb.cpp +++ b/camera/provider/aidl/vts/device_cb.cpp @@ -155,7 +155,7 @@ ScopedAStatus DeviceCb::requestStreamBuffers(const std::vector& b BufferStatus::OK, NativeHandle(), NativeHandle(), }; - mOutstandingBufferIds[idx][mNextBufferId++] = ::android::dupToAidl(handle); + mOutstandingBufferIds[idx][mNextBufferId++] = handle; } atLeastOneStreamOk = true; bufRets[i].streamId = stream.id; @@ -427,9 +427,13 @@ bool DeviceCb::processCaptureResultLocked( } CameraAidlTest::InFlightRequest::StreamBufferAndTimestamp streamBufferAndTimestamp; + auto outstandingBuffers = mUseHalBufManager ? mOutstandingBufferIds : + request->mOutstandingBufferIds; + auto outputBuffer = outstandingBuffers.empty() ? ::android::makeFromAidl(buffer.buffer) : + outstandingBuffers[buffer.streamId][buffer.bufferId]; streamBufferAndTimestamp.buffer = {buffer.streamId, buffer.bufferId, - ::android::makeFromAidl(buffer.buffer), + outputBuffer, buffer.status, ::android::makeFromAidl(buffer.acquireFence), ::android::makeFromAidl(buffer.releaseFence)}; diff --git a/camera/provider/aidl/vts/device_cb.h b/camera/provider/aidl/vts/device_cb.h index 82ca10ddcb..3ae7d10596 100644 --- a/camera/provider/aidl/vts/device_cb.h +++ b/camera/provider/aidl/vts/device_cb.h @@ -73,7 +73,7 @@ class DeviceCb : public BnCameraDeviceCallback { std::vector mStreams; std::vector mHalStreams; int64_t mNextBufferId = 1; - using OutstandingBuffers = std::unordered_map; + using OutstandingBuffers = std::unordered_map; // size == mStreams.size(). Tracking each streams outstanding buffers std::vector mOutstandingBufferIds; std::condition_variable mFlushedCondition;