mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
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
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "HandleImporter.h"
|
||||
|
||||
#include <gralloctypes/Gralloc4.h>
|
||||
#include "aidl/android/hardware/graphics/common/Smpte2086.h"
|
||||
#include <log/log.h>
|
||||
|
||||
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<M> mapper, buffer_handle_
|
||||
bool isMetadataPesent(const sp<IMapperV4> mapper, const buffer_handle_t& buf,
|
||||
MetadataType metadataType) {
|
||||
auto buffer = const_cast<native_handle_t*>(buf);
|
||||
mapper->get(buffer, metadataType, [] (const auto& tmpError,
|
||||
bool ret = false;
|
||||
hidl_vec<uint8_t> 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<Smpte2086> realSmpte2086;
|
||||
gralloc4::decodeSmpte2086(vec, &realSmpte2086);
|
||||
ret = realSmpte2086.has_value();
|
||||
} else if (metadataType == gralloc4::MetadataType_Smpte2094_10) {
|
||||
std::optional<std::vector<uint8_t>> realSmpte2094_10;
|
||||
gralloc4::decodeSmpte2094_10(vec, &realSmpte2094_10);
|
||||
ret = realSmpte2094_10.has_value();
|
||||
} else if (metadataType == gralloc4::MetadataType_Smpte2094_40) {
|
||||
std::optional<std::vector<uint8_t>> realSmpte2094_40;
|
||||
gralloc4::decodeSmpte2094_40(vec, &realSmpte2094_40);
|
||||
ret = realSmpte2094_40.has_value();
|
||||
} else {
|
||||
ALOGE("%s: Unknown metadata type!", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<PlaneLayout> getPlaneLayouts(const sp<IMapperV4> mapper, buffer_handle_t& buf) {
|
||||
|
||||
@@ -1739,6 +1739,10 @@ TEST_P(CameraAidlTest, processUltraHighResolutionRequest) {
|
||||
|
||||
std::list<PixelFormat> pixelFormats = {PixelFormat::YCBCR_420_888, PixelFormat::RAW16};
|
||||
for (PixelFormat format : pixelFormats) {
|
||||
previewStream.usage =
|
||||
static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
|
||||
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<std::string> 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<DeviceCb> cb;
|
||||
for (const auto& profile : profileList) {
|
||||
previewStream.usage =
|
||||
static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
|
||||
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<buffer_handle_t> graphicBuffers;
|
||||
graphicBuffers.reserve(halStreams.size());
|
||||
mInflightMap.clear();
|
||||
// Stream as long as needed to fill the Hal inflight queue
|
||||
std::vector<CaptureRequest> requests(halStreams[0].maxBuffers);
|
||||
|
||||
std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
|
||||
static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
|
||||
partialResultCount, std::unordered_set<std::string>(), resultQueue);
|
||||
for (int32_t frameNumber = 0; frameNumber < requests.size(); frameNumber++) {
|
||||
std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
|
||||
static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
|
||||
partialResultCount, std::unordered_set<std::string>(), resultQueue);
|
||||
|
||||
std::vector<CaptureRequest> requests(1);
|
||||
CaptureRequest& request = requests[0];
|
||||
std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
|
||||
outputBuffers.resize(halStreams.size());
|
||||
CaptureRequest& request = requests[frameNumber];
|
||||
std::vector<StreamBuffer>& 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<uint64_t>(halStream.producerUsage),
|
||||
static_cast<uint64_t>(halStream.consumerUsage)),
|
||||
halStream.overrideFormat, &buffer_handle);
|
||||
size_t k = 0;
|
||||
inflightReq->mOutstandingBufferIds.resize(halStreams.size());
|
||||
std::vector<buffer_handle_t> 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<uint64_t>(halStream.producerUsage),
|
||||
static_cast<uint64_t>(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<std::mutex> l(mLock);
|
||||
mInflightMap[frameNumber] = inflightReq;
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> l(mLock);
|
||||
mInflightMap.clear();
|
||||
mInflightMap[frameNumber] = inflightReq;
|
||||
}
|
||||
|
||||
int32_t numRequestProcessed = 0;
|
||||
std::vector<BufferCache> 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<int32_t> {halStreams[0].id});
|
||||
ASSERT_TRUE(returnStatus.isOk());
|
||||
|
||||
for (int32_t frameNumber = 0; frameNumber < requests.size(); frameNumber++) {
|
||||
const auto& inflightReq = mInflightMap[frameNumber];
|
||||
std::unique_lock<std::mutex> 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<int32_t> streamIds(halStreams.size());
|
||||
for (size_t i = 0; i < streamIds.size(); i++) {
|
||||
|
||||
@@ -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<int32_t>(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<Stream> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -399,6 +399,10 @@ class CameraAidlTest : public ::testing::TestWithParam<std::string> {
|
||||
// Result metadata
|
||||
::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult;
|
||||
|
||||
// Inflight buffers
|
||||
using OutstandingBuffers = std::unordered_map<uint64_t, buffer_handle_t>;
|
||||
std::vector<OutstandingBuffers> mOutstandingBufferIds;
|
||||
|
||||
// A copy-able StreamBuffer using buffer_handle_t instead of AIDLs NativeHandle
|
||||
struct NativeStreamBuffer {
|
||||
int32_t streamId;
|
||||
|
||||
@@ -155,7 +155,7 @@ ScopedAStatus DeviceCb::requestStreamBuffers(const std::vector<BufferRequest>& 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)};
|
||||
|
||||
@@ -73,7 +73,7 @@ class DeviceCb : public BnCameraDeviceCallback {
|
||||
std::vector<Stream> mStreams;
|
||||
std::vector<HalStream> mHalStreams;
|
||||
int64_t mNextBufferId = 1;
|
||||
using OutstandingBuffers = std::unordered_map<uint64_t, NativeHandle>;
|
||||
using OutstandingBuffers = std::unordered_map<uint64_t, buffer_handle_t>;
|
||||
// size == mStreams.size(). Tracking each streams outstanding buffers
|
||||
std::vector<OutstandingBuffers> mOutstandingBufferIds;
|
||||
std::condition_variable mFlushedCondition;
|
||||
|
||||
Reference in New Issue
Block a user