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

Commit be83fa71 authored by Yin-Chia Yeh's avatar Yin-Chia Yeh
Browse files

Camera: add buffer freed notification interface

To cleanup caches of obsolete buffers.
This CL addressed the input stream bit, the output
stream hook will be a followup CL.
Also cleanup some dead API in CameraDeviceBase.h

Test: fix CTS ReprocessCaptureTest
Bug: 34461678
Change-Id: I801cd81c29becaa45630ed0a5c2dab8df1278a6a
parent 32efa2fd
Loading
Loading
Loading
Loading
+0 −27
Original line number Diff line number Diff line
@@ -144,12 +144,6 @@ class CameraDeviceBase : public virtual RefBase {
    virtual status_t createInputStream(uint32_t width, uint32_t height,
            int32_t format, /*out*/ int32_t *id) = 0;

    /**
     * Create an input reprocess stream that uses buffers from an existing
     * output stream.
     */
    virtual status_t createReprocessStreamFromStream(int outputId, int *id) = 0;

    /**
     * Get information about a given stream.
     */
@@ -168,12 +162,6 @@ class CameraDeviceBase : public virtual RefBase {
     */
    virtual status_t deleteStream(int id) = 0;

    /**
     * Delete reprocess stream. Must not be called if there are requests in
     * flight which reference that stream.
     */
    virtual status_t deleteReprocessStream(int id) = 0;

    /**
     * Take the currently-defined set of streams and configure the HAL to use
     * them. This is a long-running operation (may be several hundered ms).
@@ -288,21 +276,6 @@ class CameraDeviceBase : public virtual RefBase {
     */
    virtual status_t triggerPrecaptureMetering(uint32_t id) = 0;

    /**
     * Abstract interface for clients that want to listen to reprocess buffer
     * release events
     */
    struct BufferReleasedListener : public virtual RefBase {
        virtual void onBufferReleased(buffer_handle_t *handle) = 0;
    };

    /**
     * Push a buffer to be reprocessed into a reprocessing stream, and
     * provide a listener to call once the buffer is returned by the HAL
     */
    virtual status_t pushReprocessBuffer(int reprocessStreamId,
            buffer_handle_t *buffer, wp<BufferReleasedListener> listener) = 0;

    /**
     * Flush all pending and in-flight requests. Blocks until flush is
     * complete.
+44 −28
Original line number Diff line number Diff line
@@ -1399,15 +1399,6 @@ status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
    return OK;
}

status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
    ATRACE_CALL();
    (void)outputId; (void)id;

    CLOGE("Unimplemented");
    return INVALID_OPERATION;
}


status_t Camera3Device::getStreamInfo(int id,
        uint32_t *width, uint32_t *height,
        uint32_t *format, android_dataspace *dataSpace) {
@@ -1523,14 +1514,6 @@ status_t Camera3Device::deleteStream(int id) {
    return res;
}

status_t Camera3Device::deleteReprocessStream(int id) {
    ATRACE_CALL();
    (void)id;

    CLOGE("Unimplemented");
    return INVALID_OPERATION;
}

status_t Camera3Device::configureStreams(int operatingMode) {
    ATRACE_CALL();
    ALOGV("%s: E", __FUNCTION__);
@@ -1856,15 +1839,6 @@ status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
                                        sizeof(trigger)/sizeof(trigger[0]));
}

status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
        buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
    ATRACE_CALL();
    (void)reprocessStreamId; (void)buffer; (void)listener;

    CLOGE("Unimplemented");
    return INVALID_OPERATION;
}

status_t Camera3Device::flush(int64_t *frameNumber) {
    ATRACE_CALL();
    ALOGV("%s: Camera %s: Flushing all requests", __FUNCTION__, mId.string());
@@ -3154,7 +3128,9 @@ status_t Camera3Device::HalInterface::configureStreams(camera3_stream_configurat
            Stream &dst = requestedConfiguration.streams[i];
            camera3_stream_t *src = config->streams[i];

            int streamId = Camera3Stream::cast(src)->getId();
            Camera3Stream* cam3stream = Camera3Stream::cast(src);
            cam3stream->setBufferFreedListener(this);
            int streamId = cam3stream->getId();
            StreamType streamType;
            switch (src->stream_type) {
                case CAMERA3_STREAM_OUTPUT:
@@ -3359,9 +3335,21 @@ status_t Camera3Device::HalInterface::processBatchCaptureRequests(
        wrapAsHidlRequest(requests[i], /*out*/&captureRequests[i], /*out*/&handlesCreated);
    }

    std::vector<device::V3_2::BufferCache> cachesToRemove;
    {
        std::lock_guard<std::mutex> lock(mBufferIdMapLock);
        for (auto& pair : mFreedBuffers) {
            // The stream might have been removed since onBufferFreed
            if (mBufferIdMaps.find(pair.first) != mBufferIdMaps.end()) {
                cachesToRemove.push_back({pair.first, pair.second});
            }
        }
        mFreedBuffers.clear();
    }

    common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
    *numRequestProcessed = 0;
    mHidlSession->processCaptureRequest(captureRequests,
    mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
            [&status, &numRequestProcessed] (auto s, uint32_t n) {
                status = s;
                *numRequestProcessed = n;
@@ -3469,12 +3457,40 @@ std::pair<bool, uint64_t> Camera3Device::HalInterface::getBufferId(
    auto it = bIdMap.find(buf);
    if (it == bIdMap.end()) {
        bIdMap[buf] = mNextBufferId++;
        ALOGV("stream %d now have %zu buffer caches, buf %p",
                streamId, bIdMap.size(), buf);
        return std::make_pair(true, mNextBufferId - 1);
    } else {
        return std::make_pair(false, it->second);
    }
}

void Camera3Device::HalInterface::onBufferFreed(
        int streamId, const native_handle_t* handle) {
    std::lock_guard<std::mutex> lock(mBufferIdMapLock);
    uint64_t bufferId = BUFFER_ID_NO_BUFFER;
    auto mapIt = mBufferIdMaps.find(streamId);
    if (mapIt == mBufferIdMaps.end()) {
        // streamId might be from a deleted stream here
        ALOGI("%s: stream %d has been removed",
                __FUNCTION__, streamId);
        return;
    }
    BufferIdMap& bIdMap = mapIt->second;
    auto it = bIdMap.find(handle);
    if (it == bIdMap.end()) {
        ALOGW("%s: cannot find buffer %p in stream %d",
                __FUNCTION__, handle, streamId);
        return;
    } else {
        bufferId =  it->second;
        bIdMap.erase(it);
        ALOGV("%s: stream %d now have %zu buffer caches after removing buf %p",
                __FUNCTION__, streamId, bIdMap.size(), handle);
    }
    mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
}

/**
 * RequestThread inner class methods
 */
+5 −6
Original line number Diff line number Diff line
@@ -125,7 +125,6 @@ class Camera3Device :
    status_t createInputStream(
            uint32_t width, uint32_t height, int format,
            int *id) override;
    status_t createReprocessStreamFromStream(int outputId, int *id) override;

    status_t getStreamInfo(int id,
            uint32_t *width, uint32_t *height,
@@ -133,7 +132,6 @@ class Camera3Device :
    status_t setStreamTransform(int id, int transform) override;

    status_t deleteStream(int id) override;
    status_t deleteReprocessStream(int id) override;

    status_t configureStreams(int operatingMode =
            static_cast<int>(hardware::camera::device::V3_2::StreamConfigurationMode::NORMAL_MODE))
@@ -155,9 +153,6 @@ class Camera3Device :
    status_t triggerCancelAutofocus(uint32_t id) override;
    status_t triggerPrecaptureMetering(uint32_t id) override;

    status_t pushReprocessBuffer(int reprocessStreamId,
            buffer_handle_t *buffer, wp<BufferReleasedListener> listener) override;

    status_t flush(int64_t *lastFrameNumber = NULL) override;

    status_t prepare(int streamId) override;
@@ -228,7 +223,7 @@ class Camera3Device :
     * Adapter for legacy HAL / HIDL HAL interface calls; calls either into legacy HALv3 or the
     * HIDL HALv3 interfaces.
     */
    class HalInterface {
    class HalInterface : public camera3::Camera3StreamBufferFreedListener {
      public:
        HalInterface(camera3_device_t *device);
        HalInterface(sp<hardware::camera::device::V3_2::ICameraDeviceSession> &session);
@@ -326,6 +321,10 @@ class Camera3Device :
        //       buffer_handle_t's FD won't change.
        // return pair of (newlySeenBuffer?, bufferId)
        std::pair<bool, uint64_t> getBufferId(const buffer_handle_t& buf, int streamId);

        virtual void onBufferFreed(int streamId, const native_handle_t* handle) override;

        std::vector<std::pair<int, uint64_t>> mFreedBuffers;
    };

    std::unique_ptr<HalInterface> mInterface;
+13 −0
Original line number Diff line number Diff line
@@ -263,6 +263,8 @@ status_t Camera3InputStream::configureQueueLocked() {
        mConsumer->setName(String8::format("Camera3-InputStream-%d", mId));

        mProducer = producer;

        mConsumer->setBufferFreedListener(this);
    }

    res = mConsumer->setDefaultBufferSize(camera3_stream::width,
@@ -288,6 +290,17 @@ status_t Camera3InputStream::getEndpointUsage(uint32_t *usage) const {
    return OK;
}

void Camera3InputStream::onBufferFreed(const wp<GraphicBuffer>& gb) {
    const sp<GraphicBuffer> buffer = gb.promote();
    if (buffer != nullptr) {
        if (mBufferFreedListener != nullptr) {
            mBufferFreedListener->onBufferFreed(mId, buffer->handle);
        }
    } else {
        ALOGE("%s: GraphicBuffer is freed before onBufferFreed callback finishes!", __FUNCTION__);
    }
}

}; // namespace camera3

}; // namespace android
+7 −1
Original line number Diff line number Diff line
@@ -34,7 +34,8 @@ namespace camera3 {
 * buffers by feeding them into the HAL, as well as releasing the buffers back
 * the buffers once the HAL is done with them.
 */
class Camera3InputStream : public Camera3IOStreamBase {
class Camera3InputStream : public Camera3IOStreamBase,
                           public BufferItemConsumer::BufferFreedListener {
  public:
    /**
     * Set up a stream for formats that have fixed size, such as RAW and YUV.
@@ -77,6 +78,11 @@ class Camera3InputStream : public Camera3IOStreamBase {

    virtual status_t getEndpointUsage(uint32_t *usage) const;

    /**
     * BufferItemConsumer::BufferFreedListener interface
     */
    virtual void onBufferFreed(const wp<GraphicBuffer>&) override;

}; // class Camera3InputStream

}; // namespace camera3
Loading