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

Commit ce6f4b06 authored by Changyeon Jo's avatar Changyeon Jo Committed by Android (Google) Code Review
Browse files

Merge changes from topic "evs_memory_management" into rvc-dev

* changes:
  Add CameraStreamExternalBuffering test case
  User allocated EVS camera capture buffers
parents ec78149a 8b068718
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -215,4 +215,22 @@ interface IEvsCamera extends @1.0::IEvsCamera {
     */
     */
    setExtendedInfo_1_1(uint32_t opaqueIdentifier, vec<uint8_t> opaqueValue)
    setExtendedInfo_1_1(uint32_t opaqueIdentifier, vec<uint8_t> opaqueValue)
        generates (EvsResult result);
        generates (EvsResult result);

    /**
     * Import external buffers to capture frames
     *
     * This API must be called with a physical camera device identifier.
     *
     * @param  buffers  A list of buffers allocated by the caller.  EvsCamera
     *                  will use these buffers to capture frames, in addition to
     *                  other buffers already in its buffer pool.
     * @return result   EvsResult::OK if it succeeds to import buffers.
     *                  EvsResult::UNDERLYING_SERVICE_ERROR if this is called
     *                  for logical camera devices or EVS fails to import
     *                  buffers.
     *         delta    The amount of buffer pool size changes after importing
     *                  given buffers.
     */
    importExternalBuffers(vec<BufferDesc> buffers)
        generates (EvsResult result, int32_t delta);
};
};
+8 −0
Original line number Original line Diff line number Diff line
@@ -354,6 +354,14 @@ Return<void> EvsCamera::getExtendedInfo_1_1(uint32_t opaqueIdentifier,
}
}




Return<void>
EvsCamera::importExternalBuffers(const hidl_vec<BufferDesc_1_1>& /* buffers */,
                                 importExternalBuffers_cb _hidl_cb) {
    ALOGW("%s is not implemented yet.", __FUNCTION__);
    _hidl_cb(EvsResult::UNDERLYING_SERVICE_ERROR, 0);
    return {};
}



bool EvsCamera::setAvailableFrames_Locked(unsigned bufferCount) {
bool EvsCamera::setAvailableFrames_Locked(unsigned bufferCount) {
    if (bufferCount < 1) {
    if (bufferCount < 1) {
+2 −0
Original line number Original line Diff line number Diff line
@@ -82,6 +82,8 @@ public:
                                          const hidl_vec<uint8_t>& opaqueValue) override;
                                          const hidl_vec<uint8_t>& opaqueValue) override;
    Return<void>      getExtendedInfo_1_1(uint32_t opaqueIdentifier,
    Return<void>      getExtendedInfo_1_1(uint32_t opaqueIdentifier,
                                          getExtendedInfo_1_1_cb _hidl_cb) override;
                                          getExtendedInfo_1_1_cb _hidl_cb) override;
    Return<void>      importExternalBuffers(const hidl_vec<BufferDesc_1_1>& buffers,
                                            importExternalBuffers_cb _hidl_cb) override;


    static sp<EvsCamera> Create(const char *deviceName);
    static sp<EvsCamera> Create(const char *deviceName);
    static sp<EvsCamera> Create(const char *deviceName,
    static sp<EvsCamera> Create(const char *deviceName,
+3 −0
Original line number Original line Diff line number Diff line
@@ -70,6 +70,9 @@ struct BufferDesc {
     */
     */
    int64_t timestamp;
    int64_t timestamp;


    /**
     * Frame metadata.  This is opaque to EVS manager.
     */
    vec<uint8_t> metadata;
    vec<uint8_t> metadata;
};
};


+137 −0
Original line number Original line Diff line number Diff line
@@ -50,6 +50,8 @@ static const float kNanoToSeconds = 0.000000001f;
#include <system/camera_metadata.h>
#include <system/camera_metadata.h>
#include <ui/DisplayConfig.h>
#include <ui/DisplayConfig.h>
#include <ui/DisplayState.h>
#include <ui/DisplayState.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferAllocator.h>


#include <gtest/gtest.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/GtestPrinter.h>
@@ -66,6 +68,7 @@ using ::android::hardware::hidl_string;
using ::android::sp;
using ::android::sp;
using ::android::wp;
using ::android::wp;
using ::android::hardware::camera::device::V3_2::Stream;
using ::android::hardware::camera::device::V3_2::Stream;
using ::android::hardware::automotive::evs::V1_1::BufferDesc;
using ::android::hardware::automotive::evs::V1_0::DisplayDesc;
using ::android::hardware::automotive::evs::V1_0::DisplayDesc;
using ::android::hardware::automotive::evs::V1_0::DisplayState;
using ::android::hardware::automotive::evs::V1_0::DisplayState;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
@@ -2230,6 +2233,140 @@ TEST_P(EvsHidlTest, LogicalCameraMetadata) {
}
}




/*
 * CameraStreamExternalBuffering:
 * This is same with CameraStreamBuffering except frame buffers are allocated by
 * the test client and then imported by EVS framework.
 */
TEST_P(EvsHidlTest, CameraStreamExternalBuffering) {
    LOG(INFO) << "Starting CameraStreamExternalBuffering test";

    // Arbitrary constant (should be > 1 and less than crazy)
    static const unsigned int kBuffersToHold = 6;

    // Get the camera list
    loadCameraList();

    // Using null stream configuration makes EVS uses the default resolution and
    // output format.
    Stream nullCfg = {};

    // Acquire the graphics buffer allocator
    android::GraphicBufferAllocator& alloc(android::GraphicBufferAllocator::get());
    const auto usage = GRALLOC_USAGE_HW_TEXTURE |
                       GRALLOC_USAGE_SW_READ_RARELY |
                       GRALLOC_USAGE_SW_WRITE_OFTEN;
    const auto format = HAL_PIXEL_FORMAT_RGBA_8888;
    const auto width = 640;
    const auto height = 360;

    // Allocate buffers to use
    hidl_vec<BufferDesc> buffers;
    for (auto i = 0; i < kBuffersToHold; ++i) {
        unsigned pixelsPerLine;
        buffer_handle_t memHandle = nullptr;
        android::status_t result = alloc.allocate(width,
                                                  height,
                                                  format,
                                                  1,
                                                  usage,
                                                  &memHandle,
                                                  &pixelsPerLine,
                                                  0,
                                                  "EvsApp");
        if (result != android::NO_ERROR) {
            LOG(ERROR) << __FUNCTION__ << " failed to allocate memory.";
        } else {
            BufferDesc buf;
            AHardwareBuffer_Desc* pDesc =
                reinterpret_cast<AHardwareBuffer_Desc *>(&buf.buffer.description);
            pDesc->width = width;
            pDesc->height = height;
            pDesc->layers = 1;
            pDesc->format = format;
            pDesc->usage = usage;
            pDesc->stride = pixelsPerLine;
            buf.buffer.nativeHandle = memHandle;
            buf.bufferId = i;   // Unique number to identify this buffer
            buffers[i] = buf;
        }
    }

    // Test each reported camera
    for (auto&& cam: cameraInfo) {
        bool isLogicalCam = false;
        getPhysicalCameraIds(cam.v1.cameraId, isLogicalCam);

        sp<IEvsCamera_1_1> pCam =
            IEvsCamera_1_1::castFrom(pEnumerator->openCamera_1_1(cam.v1.cameraId, nullCfg))
            .withDefault(nullptr);
        ASSERT_NE(pCam, nullptr);

        // Store a camera handle for a clean-up
        activeCameras.push_back(pCam);

        // Request to import buffers
        EvsResult result = EvsResult::OK;
        int delta = 0;
        pCam->importExternalBuffers(buffers,
                                    [&] (auto _result, auto _delta) {
                                        result = _result;
                                        delta = _delta;
                                    });
        if (isLogicalCam) {
            EXPECT_EQ(result, EvsResult::UNDERLYING_SERVICE_ERROR);
            continue;
        }

        EXPECT_EQ(result, EvsResult::OK);
        EXPECT_GE(delta, 0);

        // Set up a frame receiver object which will fire up its own thread.
        sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
                                                         nullptr,
                                                         FrameHandler::eNoAutoReturn);

        // Start the camera's video stream
        bool startResult = frameHandler->startStream();
        ASSERT_TRUE(startResult);

        // Check that the video stream stalls once we've gotten exactly the number of buffers
        // we requested since we told the frameHandler not to return them.
        sleep(1);   // 1 second should be enough for at least 5 frames to be delivered worst case
        unsigned framesReceived = 0;
        frameHandler->getFramesCounters(&framesReceived, nullptr);
        ASSERT_EQ(kBuffersToHold, framesReceived) << "Stream didn't stall at expected buffer limit";


        // Give back one buffer
        bool didReturnBuffer = frameHandler->returnHeldBuffer();
        EXPECT_TRUE(didReturnBuffer);

        // Once we return a buffer, it shouldn't take more than 1/10 second to get a new one
        // filled since we require 10fps minimum -- but give a 10% allowance just in case.
        usleep(110 * kMillisecondsToMicroseconds);
        frameHandler->getFramesCounters(&framesReceived, nullptr);
        EXPECT_EQ(kBuffersToHold+1, framesReceived) << "Stream should've resumed";

        // Even when the camera pointer goes out of scope, the FrameHandler object will
        // keep the stream alive unless we tell it to shutdown.
        // Also note that the FrameHandle and the Camera have a mutual circular reference, so
        // we have to break that cycle in order for either of them to get cleaned up.
        frameHandler->shutdown();

        // Explicitly release the camera
        pEnumerator->closeCamera(pCam);
        activeCameras.clear();
    }

    // Release buffers
    for (auto& b : buffers) {
        alloc.free(b.buffer.nativeHandle);
    }
    buffers.resize(0);
}


/*
/*
 * UltrasonicsArrayOpenClean:
 * UltrasonicsArrayOpenClean:
 * Opens each ultrasonics arrays reported by the enumerator and then explicitly closes it via a
 * Opens each ultrasonics arrays reported by the enumerator and then explicitly closes it via a
Loading