Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dda1eb77 authored by Emilian Peev's avatar Emilian Peev
Browse files

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
parent a71fffd7
Loading
Loading
Loading
Loading
+25 −4
Original line number Diff line number Diff line
@@ -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) {
+69 −49
Original line number Diff line number Diff line
@@ -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,19 +1923,24 @@ 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);

            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];
                CaptureRequest& request = requests[frameNumber];
                std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
                outputBuffers.resize(halStreams.size());

                size_t k = 0;
                inflightReq->mOutstandingBufferIds.resize(halStreams.size());
                std::vector<buffer_handle_t> graphicBuffers;
                graphicBuffers.reserve(halStreams.size());

                for (const auto& halStream : halStreams) {
                    buffer_handle_t buffer_handle;
                    if (useHalBufManager) {
@@ -1936,16 +1948,17 @@ TEST_P(CameraAidlTest, process10BitDynamicRangeRequest) {
                                            NativeHandle(), BufferStatus::OK,
                                            NativeHandle(), NativeHandle()};
                    } else {
                    allocateGraphicBuffer(previewStream.width, previewStream.height,
                                          android_convertGralloc1To0Usage(
                        auto usage = android_convertGralloc1To0Usage(
                                static_cast<uint64_t>(halStream.producerUsage),
                                                  static_cast<uint64_t>(halStream.consumerUsage)),
                                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()};
                        outputBuffers[k] = {halStream.id, bufferId,
                            android::makeToAidl(buffer_handle), BufferStatus::OK, NativeHandle(),
                            NativeHandle()};
                        bufferId++;
                    }
                    k++;
@@ -1961,18 +1974,24 @@ TEST_P(CameraAidlTest, process10BitDynamicRangeRequest) {

                {
                    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);
            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++) {
+19 −7
Original line number Diff line number Diff line
@@ -2639,8 +2639,20 @@ void CameraAidlTest::configureStreams(const std::string& name,

    outputStreams.clear();
    Size maxSize;
    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);
    }
}

+4 −0
Original line number Diff line number Diff line
@@ -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;
+6 −2
Original line number Diff line number Diff line
@@ -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)};
Loading