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

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

Camera: support libhardware camera device 3.6

Add buffer management API support.

Test: VTS to be written. Need Pixel device impl to verify.
Bug: 120986771
Change-Id: Icdbc621f8cd17aa0868d3ac361867c44793a268c
parent 5279d816
Loading
Loading
Loading
Loading
+67 −19
Original line number Diff line number Diff line
@@ -44,13 +44,15 @@ static constexpr int METADATA_SHRINK_ABS_THRESHOLD = 4096;
static constexpr int METADATA_SHRINK_REL_THRESHOLD = 2;

HandleImporter CameraDeviceSession::sHandleImporter;
buffer_handle_t CameraDeviceSession::sEmptyBuffer = nullptr;

const int CameraDeviceSession::ResultBatcher::NOT_BATCHED;

CameraDeviceSession::CameraDeviceSession(
    camera3_device_t* device,
    const camera_metadata_t* deviceInfo,
    const sp<ICameraDeviceCallback>& callback) :
        camera3_callback_ops({&sProcessCaptureResult, &sNotify}),
        camera3_callback_ops({&sProcessCaptureResult, &sNotify, nullptr, nullptr}),
        mDevice(device),
        mDeviceVersion(device->common.version),
        mFreeBufEarly(shouldFreeBufEarly()),
@@ -246,10 +248,50 @@ void CameraDeviceSession::overrideResultForPrecaptureCancelLocked(
    }
}

Status CameraDeviceSession::importBuffer(int32_t streamId,
        uint64_t bufId, buffer_handle_t buf,
        /*out*/buffer_handle_t** outBufPtr,
        bool allowEmptyBuf) {

    if (buf == nullptr && bufId == BUFFER_ID_NO_BUFFER) {
        if (allowEmptyBuf) {
            *outBufPtr = &sEmptyBuffer;
            return Status::OK;
        } else {
            ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
            return Status::ILLEGAL_ARGUMENT;
        }
    }

    Mutex::Autolock _l(mInflightLock);
    CirculatingBuffers& cbs = mCirculatingBuffers[streamId];
    if (cbs.count(bufId) == 0) {
        // Register a newly seen buffer
        buffer_handle_t importedBuf = buf;
        sHandleImporter.importBuffer(importedBuf);
        if (importedBuf == nullptr) {
            ALOGE("%s: output buffer for stream %d is invalid!", __FUNCTION__, streamId);
            return Status::INTERNAL_ERROR;
        } else {
            cbs[bufId] = importedBuf;
        }
    }
    *outBufPtr = &cbs[bufId];
    return Status::OK;
}

Status CameraDeviceSession::importRequest(
        const CaptureRequest& request,
        hidl_vec<buffer_handle_t*>& allBufPtrs,
        hidl_vec<int>& allFences) {
    return importRequestImpl(request, allBufPtrs, allFences);
}

Status CameraDeviceSession::importRequestImpl(
        const CaptureRequest& request,
        hidl_vec<buffer_handle_t*>& allBufPtrs,
        hidl_vec<int>& allFences,
        bool allowEmptyBuf) {
    bool hasInputBuf = (request.inputBuffer.streamId != -1 &&
            request.inputBuffer.bufferId != 0);
    size_t numOutputBufs = request.outputBuffers.size();
@@ -277,25 +319,15 @@ Status CameraDeviceSession::importRequest(
    }

    for (size_t i = 0; i < numBufs; i++) {
        buffer_handle_t buf = allBufs[i];
        uint64_t bufId = allBufIds[i];
        CirculatingBuffers& cbs = mCirculatingBuffers[streamIds[i]];
        if (cbs.count(bufId) == 0) {
            if (buf == nullptr) {
                ALOGE("%s: bufferId %" PRIu64 " has null buffer handle!", __FUNCTION__, bufId);
                return Status::ILLEGAL_ARGUMENT;
            }
            // Register a newly seen buffer
            buffer_handle_t importedBuf = buf;
            sHandleImporter.importBuffer(importedBuf);
            if (importedBuf == nullptr) {
                ALOGE("%s: output buffer %zu is invalid!", __FUNCTION__, i);
                return Status::INTERNAL_ERROR;
            } else {
                cbs[bufId] = importedBuf;
            }
        Status st = importBuffer(
                streamIds[i], allBufIds[i], allBufs[i], &allBufPtrs[i],
                // Disallow empty buf for input stream, otherwise follow
                // the allowEmptyBuf argument.
                (hasInputBuf && i == numOutputBufs) ? false : allowEmptyBuf);
        if (st != Status::OK) {
            // Detailed error logs printed in importBuffer
            return st;
        }
        allBufPtrs[i] = &cbs[bufId];
    }

    // All buffers are imported. Now validate output buffer acquire fences
@@ -1271,18 +1303,26 @@ Return<void> CameraDeviceSession::close() {
        ATRACE_END();

        // free all imported buffers
        Mutex::Autolock _l(mInflightLock);
        for(auto& pair : mCirculatingBuffers) {
            CirculatingBuffers& buffers = pair.second;
            for (auto& p2 : buffers) {
                sHandleImporter.freeBuffer(p2.second);
            }
            buffers.clear();
        }
        mCirculatingBuffers.clear();

        mClosed = true;
    }
    return Void();
}

uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t&, int) {
    // No need to fill in bufferId by default
    return BUFFER_ID_NO_BUFFER;
}

status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result,
                                                 const camera3_capture_result *hal_result) {
    uint32_t frameNumber = hal_result->frame_number;
@@ -1396,6 +1436,14 @@ status_t CameraDeviceSession::constructCaptureResult(CaptureResult& result,
        result.outputBuffers[i].streamId =
                static_cast<Camera3Stream*>(hal_result->output_buffers[i].stream)->mId;
        result.outputBuffers[i].buffer = nullptr;
        if (hal_result->output_buffers[i].buffer != nullptr) {
            result.outputBuffers[i].bufferId = getCapResultBufferId(
                    *(hal_result->output_buffers[i].buffer),
                    result.outputBuffers[i].streamId);
        } else {
            result.outputBuffers[i].bufferId = 0;
        }

        result.outputBuffers[i].status = (BufferStatus) hal_result->output_buffers[i].status;
        // skip acquire fence since it's of no use to camera service
        if (hal_result->output_buffers[i].release_fence != -1) {
+20 −1
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ protected:
    std::map<uint32_t, bool> mInflightRawBoostPresent;
    ::android::hardware::camera::common::V1_0::helper::CameraMetadata mOverridenRequest;

    static const uint64_t BUFFER_ID_NO_BUFFER = 0;
    // buffers currently ciculating between HAL and camera service
    // key: bufferId sent via HIDL interface
    // value: imported buffer_handle_t
@@ -171,6 +172,7 @@ protected:
    std::map<int, CirculatingBuffers> mCirculatingBuffers;

    static HandleImporter sHandleImporter;
    static buffer_handle_t sEmptyBuffer;

    bool mInitFail;
    bool mFirstRequest = false;
@@ -301,11 +303,23 @@ protected:
    Status initStatus() const;

    // Validate and import request's input buffer and acquire fence
    Status importRequest(
    virtual Status importRequest(
            const CaptureRequest& request,
            hidl_vec<buffer_handle_t*>& allBufPtrs,
            hidl_vec<int>& allFences);

    Status importRequestImpl(
            const CaptureRequest& request,
            hidl_vec<buffer_handle_t*>& allBufPtrs,
            hidl_vec<int>& allFences,
            // Optional argument for ICameraDeviceSession@3.5 impl
            bool allowEmptyBuf = false);

    Status importBuffer(int32_t streamId,
            uint64_t bufId, buffer_handle_t buf,
            /*out*/buffer_handle_t** outBufPtr,
            bool allowEmptyBuf);

    static void cleanupInflightFences(
            hidl_vec<int>& allFences, size_t numFences);

@@ -332,6 +346,11 @@ protected:
    static callbacks_process_capture_result_t sProcessCaptureResult;
    static callbacks_notify_t sNotify;

    // By default camera service uses frameNumber/streamId pair to retrieve the buffer that
    // was sent to HAL. Override this implementation if HAL is using buffers from buffer management
    // APIs to send output buffer.
    virtual uint64_t getCapResultBufferId(const buffer_handle_t& buf, int streamId);

    status_t constructCaptureResult(CaptureResult& result,
                                const camera3_capture_result *hal_result);

+16 −7
Original line number Diff line number Diff line
@@ -87,6 +87,14 @@ CameraDeviceSession::~CameraDeviceSession() {
Return<void> CameraDeviceSession::configureStreams_3_4(
        const StreamConfiguration& requestedConfiguration,
        ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb)  {
    configureStreams_3_4_Impl(requestedConfiguration, _hidl_cb);
    return Void();
}

void CameraDeviceSession::configureStreams_3_4_Impl(
        const StreamConfiguration& requestedConfiguration,
        ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb,
        uint32_t streamConfigCounter)  {
    Status status = initStatus();
    HalStreamConfiguration outStreams;

@@ -97,7 +105,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4(
                ALOGE("%s: trying to configureStreams with physical camera id with V3.2 callback",
                        __FUNCTION__);
                _hidl_cb(Status::INTERNAL_ERROR, outStreams);
                return Void();
                return;
            }
        }
    }
@@ -109,7 +117,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4(
        ALOGE("%s: trying to configureStreams while there are still %zu inflight buffers!",
                __FUNCTION__, mInflightBuffers.size());
        _hidl_cb(Status::INTERNAL_ERROR, outStreams);
        return Void();
        return;
    }

    if (!mInflightAETriggerOverrides.empty()) {
@@ -117,7 +125,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4(
                " trigger overrides!", __FUNCTION__,
                mInflightAETriggerOverrides.size());
        _hidl_cb(Status::INTERNAL_ERROR, outStreams);
        return Void();
        return;
    }

    if (!mInflightRawBoostPresent.empty()) {
@@ -125,12 +133,12 @@ Return<void> CameraDeviceSession::configureStreams_3_4(
                " boost overrides!", __FUNCTION__,
                mInflightRawBoostPresent.size());
        _hidl_cb(Status::INTERNAL_ERROR, outStreams);
        return Void();
        return;
    }

    if (status != Status::OK) {
        _hidl_cb(status, outStreams);
        return Void();
        return;
    }

    const camera_metadata_t *paramBuffer = nullptr;
@@ -139,11 +147,12 @@ Return<void> CameraDeviceSession::configureStreams_3_4(
    }

    camera3_stream_configuration_t stream_list{};
    stream_list.stream_configuration_counter = streamConfigCounter;
    hidl_vec<camera3_stream_t*> streams;
    stream_list.session_parameters = paramBuffer;
    if (!preProcessConfigurationLocked_3_4(requestedConfiguration, &stream_list, &streams)) {
        _hidl_cb(Status::INTERNAL_ERROR, outStreams);
        return Void();
        return;
    }

    ATRACE_BEGIN("camera3->configure_streams");
@@ -168,7 +177,7 @@ Return<void> CameraDeviceSession::configureStreams_3_4(
    }

    _hidl_cb(status, outStreams);
    return Void();
    return;
}

bool CameraDeviceSession::preProcessConfigurationLocked_3_4(
+6 −0
Original line number Diff line number Diff line
@@ -87,6 +87,12 @@ protected:
    void postProcessConfigurationFailureLocked_3_4(
            const StreamConfiguration& requestedConfiguration);

    void configureStreams_3_4_Impl(
            const StreamConfiguration& requestedConfiguration,
            ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb,
            // Optional argument for ICameraDeviceSession@3.5 impl
            uint32_t streamConfigCounter = 0);

    Return<void> processCaptureRequest_3_4(
            const hidl_vec<V3_4::CaptureRequest>& requests,
            const hidl_vec<V3_2::BufferCache>& cachesToRemove,
+302 −4
Original line number Diff line number Diff line
@@ -15,8 +15,10 @@
 */

#define LOG_TAG "CamDevSession@3.5-impl"
#define ATRACE_TAG ATRACE_TAG_CAMERA
#include <android/log.h>

#include <vector>
#include <utils/Trace.h>
#include "CameraDeviceSession.h"

@@ -33,13 +35,26 @@ CameraDeviceSession::CameraDeviceSession(
    const sp<V3_2::ICameraDeviceCallback>& callback) :
        V3_4::implementation::CameraDeviceSession(device, deviceInfo, callback) {

    mHasCallback_3_5 = false;
    mCallback_3_5 = nullptr;

    auto castResult = ICameraDeviceCallback::castFrom(callback);
    if (castResult.isOk()) {
        sp<ICameraDeviceCallback> callback3_5 = castResult;
        if (callback3_5 != nullptr) {
            mHasCallback_3_5 = true;
            mCallback_3_5 = callback3_5;
        }
    }

    if (mCallback_3_5 != nullptr) {
        camera_metadata_entry bufMgrVersion = mDeviceInfo.find(
                ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
        if (bufMgrVersion.count > 0) {
            mSupportBufMgr = (bufMgrVersion.data.u8[0] ==
                    ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
            if (mSupportBufMgr) {
                request_stream_buffers = sRequestStreamBuffers;
                return_stream_buffers = sReturnStreamBuffers;
            }
        }
    }
}
@@ -50,14 +65,297 @@ CameraDeviceSession::~CameraDeviceSession() {
Return<void> CameraDeviceSession::configureStreams_3_5(
        const StreamConfiguration& requestedConfiguration,
        ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb)  {
    return configureStreams_3_4(requestedConfiguration.v3_4, _hidl_cb);
    configureStreams_3_4_Impl(requestedConfiguration.v3_4, _hidl_cb,
            requestedConfiguration.streamConfigCounter);
    return Void();
}

Return<void> CameraDeviceSession::signalStreamFlush(
        const hidl_vec<int32_t>& /*requests*/, uint32_t /*streamConfigCounter*/) {
        const hidl_vec<int32_t>& streamIds, uint32_t streamConfigCounter) {
    std::vector<camera3_stream_t*> streams(streamIds.size());
    {
        Mutex::Autolock _l(mInflightLock);
        for (size_t i = 0; i < streamIds.size(); i++) {
            int32_t id = streamIds[i];
            if (mStreamMap.count(id) == 0) {
                ALOGE("%s: unknown streamId %d", __FUNCTION__, id);
                return Void();
            }
            streams[i] = &mStreamMap[id];
        }
    }
    if (mDevice->ops->signal_stream_flush != nullptr) {
        mDevice->ops->signal_stream_flush(mDevice,
                streamConfigCounter, streams.size(), streams.data());
    }
    return Void();
}

Status CameraDeviceSession::importRequest(
        const CaptureRequest& request,
        hidl_vec<buffer_handle_t*>& allBufPtrs,
        hidl_vec<int>& allFences) {
    if (mSupportBufMgr) {
        return importRequestImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ true);
    }
    return importRequestImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ false);
}

void CameraDeviceSession::pushBufferId(
        const buffer_handle_t& buf, uint64_t bufferId, int streamId) {
    std::lock_guard<std::mutex> lock(mBufferIdMapLock);

    // emplace will return existing entry if there is one.
    auto pair = mBufferIdMaps.emplace(streamId, BufferIdMap{});
    BufferIdMap& bIdMap = pair.first->second;
    bIdMap[buf] = bufferId;
}

uint64_t CameraDeviceSession::popBufferId(
        const buffer_handle_t& buf, int streamId) {
    std::lock_guard<std::mutex> lock(mBufferIdMapLock);

    auto streamIt = mBufferIdMaps.find(streamId);
    if (streamIt == mBufferIdMaps.end()) {
        return BUFFER_ID_NO_BUFFER;
    }
    BufferIdMap& bIdMap = streamIt->second;
    auto it = bIdMap.find(buf);
    if (it == bIdMap.end()) {
        return BUFFER_ID_NO_BUFFER;
    }
    uint64_t bufId = it->second;
    bIdMap.erase(it);
    if (bIdMap.empty()) {
        mBufferIdMaps.erase(streamIt);
    }
    return bufId;
}

uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t& buf, int streamId) {
    if (mSupportBufMgr) {
        return popBufferId(buf, streamId);
    }
    return BUFFER_ID_NO_BUFFER;
}

Camera3Stream* CameraDeviceSession::getStreamPointer(int32_t streamId) {
    Mutex::Autolock _l(mInflightLock);
    if (mStreamMap.count(streamId) == 0) {
        ALOGE("%s: unknown streamId %d", __FUNCTION__, streamId);
        return nullptr;
    }
    return &mStreamMap[streamId];
}

void CameraDeviceSession::cleanupInflightBufferFences(
        std::vector<int>& fences, std::vector<std::pair<buffer_handle_t, int>>& bufs) {
    hidl_vec<int> hFences = fences;
    cleanupInflightFences(hFences, fences.size());
    for (auto& p : bufs) {
        popBufferId(p.first, p.second);
    }
}

camera3_buffer_request_status_t CameraDeviceSession::requestStreamBuffers(
        uint32_t num_buffer_reqs,
        const camera3_buffer_request_t *buffer_reqs,
        /*out*/uint32_t *num_returned_buf_reqs,
        /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs) {
    ATRACE_CALL();
    *num_returned_buf_reqs = 0;
    hidl_vec<BufferRequest> hBufReqs(num_buffer_reqs);
    for (size_t i = 0; i < num_buffer_reqs; i++) {
        hBufReqs[i].streamId =
                static_cast<Camera3Stream*>(buffer_reqs[i].stream)->mId;
        hBufReqs[i].numBuffersRequested = buffer_reqs[i].num_buffers_requested;
    }

    ATRACE_BEGIN("HIDL requestStreamBuffers");
    BufferRequestStatus status;
    hidl_vec<StreamBufferRet> bufRets;
    auto err = mCallback_3_5->requestStreamBuffers(hBufReqs,
            [&status, &bufRets]
            (BufferRequestStatus s, const hidl_vec<StreamBufferRet>& rets) {
                status = s;
                bufRets = std::move(rets);
            });
    if (!err.isOk()) {
        ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
        return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
    }
    ATRACE_END();

    if (status == BufferRequestStatus::OK || status == BufferRequestStatus::FAILED_PARTIAL) {
        if (bufRets.size() != num_buffer_reqs) {
            ALOGE("%s: expect %d buffer requests returned, only got %zu",
                    __FUNCTION__, num_buffer_reqs, bufRets.size());
            return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
        }

        for (size_t i = 0; i < num_buffer_reqs; i++) {
            // maybe we can query all streams in one call to avoid frequent locking device here?
            Camera3Stream* stream = getStreamPointer(bufRets[i].streamId);
            if (stream == nullptr) {
                ALOGE("%s: unknown streamId %d", __FUNCTION__, bufRets[i].streamId);
                return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
            }
            returned_buf_reqs[i].stream = stream;
        }

        std::vector<int> importedFences;
        std::vector<std::pair<buffer_handle_t, int>> importedBuffers;
        for (size_t i = 0; i < num_buffer_reqs; i++) {
            int streamId = bufRets[i].streamId;
            switch (bufRets[i].val.getDiscriminator()) {
                case StreamBuffersVal::hidl_discriminator::error:
                    returned_buf_reqs[i].num_output_buffers = 0;
                    switch (bufRets[i].val.error()) {
                        case StreamBufferRequestError::NO_BUFFER_AVAILABLE:
                            returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_NO_BUFFER_AVAILABLE;
                            break;
                        case StreamBufferRequestError::MAX_BUFFER_EXCEEDED:
                            returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_MAX_BUFFER_EXCEEDED;
                            break;
                        case StreamBufferRequestError::STREAM_DISCONNECTED:
                            returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_STREAM_DISCONNECTED;
                            break;
                        case StreamBufferRequestError::UNKNOWN_ERROR:
                            returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_UNKNOWN_ERROR;
                            break;
                        default:
                            ALOGE("%s: Unknown StreamBufferRequestError %d",
                                    __FUNCTION__, bufRets[i].val.error());
                            cleanupInflightBufferFences(importedFences, importedBuffers);
                            return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
                    }
                    break;
                case StreamBuffersVal::hidl_discriminator::buffers: {
                    const hidl_vec<StreamBuffer>& hBufs = bufRets[i].val.buffers();
                    camera3_stream_buffer_t* outBufs = returned_buf_reqs[i].output_buffers;
                    for (size_t b = 0; b < hBufs.size(); b++) {
                        const StreamBuffer& hBuf = hBufs[b];
                        camera3_stream_buffer_t& outBuf = outBufs[b];
                        // maybe add importBuffers API to avoid frequent locking device?
                        Status s = importBuffer(streamId,
                                hBuf.bufferId, hBuf.buffer.getNativeHandle(),
                                /*out*/&(outBuf.buffer),
                                /*allowEmptyBuf*/false);
                        if (s != Status::OK) {
                            ALOGE("%s: import stream %d bufferId %" PRIu64 " failed!",
                                    __FUNCTION__, streamId, hBuf.bufferId);
                            cleanupInflightBufferFences(importedFences, importedBuffers);
                            // Buffer import should never fail - restart HAL since something is very
                            // wrong.
                            assert(false);
                            return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
                        }

                        pushBufferId(*(outBuf.buffer), hBuf.bufferId, streamId);
                        importedBuffers.push_back(std::make_pair(*(outBuf.buffer), streamId));

                        if (!sHandleImporter.importFence(
                                hBuf.acquireFence,
                                outBuf.acquire_fence)) {
                            ALOGE("%s: stream %d bufferId %" PRIu64 "acquire fence is invalid",
                                    __FUNCTION__, streamId, hBuf.bufferId);
                            cleanupInflightBufferFences(importedFences, importedBuffers);
                            return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
                        }
                        importedFences.push_back(outBuf.acquire_fence);
                        outBuf.stream = returned_buf_reqs[i].stream;
                        outBuf.status = CAMERA3_BUFFER_STATUS_OK;
                        outBuf.release_fence = -1;
                    }
                    returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_OK;
                } break;
                default:
                    ALOGE("%s: unknown StreamBuffersVal discrimator!", __FUNCTION__);
                    cleanupInflightBufferFences(importedFences, importedBuffers);
                    return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
            }
        }

        *num_returned_buf_reqs = num_buffer_reqs;

        return (status == BufferRequestStatus::OK) ?
                CAMERA3_BUF_REQ_OK : CAMERA3_BUF_REQ_FAILED_PARTIAL;
    }

    switch (status) {
        case BufferRequestStatus::FAILED_CONFIGURING:
            return CAMERA3_BUF_REQ_FAILED_CONFIGURING;
        case BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS:
            return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS;
        case BufferRequestStatus::FAILED_UNKNOWN:
        default:
            return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
    }
}

void CameraDeviceSession::returnStreamBuffers(
        uint32_t num_buffers,
        const camera3_stream_buffer_t* const* buffers) {
    ATRACE_CALL();
    hidl_vec<StreamBuffer> hBufs(num_buffers);

    for (size_t i = 0; i < num_buffers; i++) {
        hBufs[i].streamId =
                static_cast<Camera3Stream*>(buffers[i]->stream)->mId;
        hBufs[i].buffer = nullptr; // use bufferId
        hBufs[i].bufferId = popBufferId(*(buffers[i]->buffer), hBufs[i].streamId);
        if (hBufs[i].bufferId == BUFFER_ID_NO_BUFFER) {
            ALOGE("%s: unknown buffer is returned to stream %d",
                    __FUNCTION__, hBufs[i].streamId);
        }
        // ERROR since the buffer is not for application to consume
        hBufs[i].status = BufferStatus::ERROR;
        // skip acquire fence since it's of no use to camera service
        if (buffers[i]->release_fence != -1) {
            native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
            handle->data[0] = buffers[i]->release_fence;
            hBufs[i].releaseFence.setTo(handle, /*shouldOwn*/true);
        }
    }

    mCallback_3_5->returnStreamBuffers(hBufs);
    return;
}

/**
 * Static callback forwarding methods from HAL to instance
 */
camera3_buffer_request_status_t CameraDeviceSession::sRequestStreamBuffers(
        const struct camera3_callback_ops *cb,
        uint32_t num_buffer_reqs,
        const camera3_buffer_request_t *buffer_reqs,
        /*out*/uint32_t *num_returned_buf_reqs,
        /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs) {
    CameraDeviceSession *d =
            const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));

    if (num_buffer_reqs == 0 || buffer_reqs == nullptr || num_returned_buf_reqs == nullptr ||
            returned_buf_reqs == nullptr) {
        ALOGE("%s: bad argument: numBufReq %d, bufReqs %p, numRetBufReq %p, retBufReqs %p",
                __FUNCTION__, num_buffer_reqs, buffer_reqs,
                num_returned_buf_reqs, returned_buf_reqs);
        return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS;
    }

    return d->requestStreamBuffers(num_buffer_reqs, buffer_reqs,
            num_returned_buf_reqs, returned_buf_reqs);
}

void CameraDeviceSession::sReturnStreamBuffers(
        const struct camera3_callback_ops *cb,
        uint32_t num_buffers,
        const camera3_stream_buffer_t* const* buffers) {
    CameraDeviceSession *d =
            const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));

    d->returnStreamBuffers(num_buffers, buffers);
}

} // namespace implementation
}  // namespace V3_5
}  // namespace device
Loading