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:
commit
2d5d3855ed
6 changed files with 120 additions and 59 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue