Merge "Camera: Import gralloc buffers before metadata queries" into stage-aosp-tm-ts-dev am: f9daf08b7b am: ee100afbbd

Original change: https://googleplex-android-review.googlesource.com/c/platform/hardware/interfaces/+/19125050

Change-Id: Ib81bd2c22beb4c1ae50f90bf0ffe6d00252e2a41
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot 2022-08-11 19:12:49 +00:00 committed by Automerger Merge Worker
commit 2d5d3855ed
6 changed files with 120 additions and 59 deletions

View file

@ -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) {

View file

@ -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++) {

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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)};

View file

@ -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;