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

Commit 90e59c98 authored by Jianing Wei's avatar Jianing Wei
Browse files

CameraService: Add support for burst capture and repeating burst.

Bug: 10749500
Change-Id: I292a485b222e5cf97388d76bf0d956a6ac54bb2f
parent a4414818
Loading
Loading
Loading
Loading
+111 −1
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,

    int32_t requestId = mRequestIdCounter++;
    metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
    ALOGV("%s: Camera %d: Submitting request with ID %d",
    ALOGV("%s: Camera %d: Creating request with ID %d",
          __FUNCTION__, mCameraId, requestId);

    if (streaming) {
@@ -186,6 +186,116 @@ status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,
    return res;
}

status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests,
                                               bool streaming) {
    ATRACE_CALL();
    ALOGV("%s-start of function", __FUNCTION__);

    status_t res;
    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;

    Mutex::Autolock icl(mBinderSerializationLock);

    if (!mDevice.get()) return DEAD_OBJECT;

    if (requests.empty()) {
        ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
              __FUNCTION__, mCameraId);
        return BAD_VALUE;
    }

    List<const CameraMetadata> metadataRequestList;
    int32_t requestId = mRequestIdCounter;
    uint32_t loopCounter = 0;

    for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end(); ++it) {
        sp<CaptureRequest> request = *it;
        if (request == 0) {
            ALOGE("%s: Camera %d: Sent null request.",
                    __FUNCTION__, mCameraId);
            return BAD_VALUE;
        }

        CameraMetadata metadata(request->mMetadata);
        if (metadata.isEmpty()) {
            ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
                   __FUNCTION__, mCameraId);
            return BAD_VALUE;
        } else if (request->mSurfaceList.isEmpty()) {
            ALOGE("%s: Camera %d: Requests must have at least one surface target. "
                  "Rejecting request.", __FUNCTION__, mCameraId);
            return BAD_VALUE;
        }

        if (!enforceRequestPermissions(metadata)) {
            // Callee logs
            return PERMISSION_DENIED;
        }

        /**
         * Write in the output stream IDs which we calculate from
         * the capture request's list of surface targets
         */
        Vector<int32_t> outputStreamIds;
        outputStreamIds.setCapacity(request->mSurfaceList.size());
        for (Vector<sp<Surface> >::iterator surfaceIt = 0;
                surfaceIt != request->mSurfaceList.end(); ++surfaceIt) {
            sp<Surface> surface = *surfaceIt;
            if (surface == 0) continue;

            sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
            int idx = mStreamMap.indexOfKey(gbp->asBinder());

            // Trying to submit request with surface that wasn't created
            if (idx == NAME_NOT_FOUND) {
                ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
                      " we have not called createStream on",
                      __FUNCTION__, mCameraId);
                return BAD_VALUE;
            }

            int streamId = mStreamMap.valueAt(idx);
            outputStreamIds.push_back(streamId);
            ALOGV("%s: Camera %d: Appending output stream %d to request",
                  __FUNCTION__, mCameraId, streamId);
        }

        metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
                        outputStreamIds.size());

        metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
        loopCounter++; // loopCounter starts from 1
        ALOGV("%s: Camera %d: Creating request with ID %d (%d of %d)",
              __FUNCTION__, mCameraId, requestId, loopCounter, requests.size());

        metadataRequestList.push_back(metadata);
    }
    mRequestIdCounter++;

    if (streaming) {
        res = mDevice->setStreamingRequestList(metadataRequestList);
        if (res != OK) {
            ALOGE("%s: Camera %d:  Got error %d after trying to set streaming "
                  "request", __FUNCTION__, mCameraId, res);
        } else {
            mStreamingRequestList.push_back(requestId);
        }
    } else {
        res = mDevice->captureList(metadataRequestList);
        if (res != OK) {
            ALOGE("%s: Camera %d: Got error %d after trying to set capture",
                __FUNCTION__, mCameraId, res);
        }
    }

    ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
    if (res == OK) {
        return requestId;
    }

    return res;
}

status_t CameraDeviceClient::cancelRequest(int requestId) {
    ATRACE_CALL();
    ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
+5 −2
Original line number Diff line number Diff line
@@ -63,7 +63,10 @@ public:
     */

    // Note that the callee gets a copy of the metadata.
    virtual int           submitRequest(sp<CaptureRequest> request,
    virtual status_t           submitRequest(sp<CaptureRequest> request,
                                             bool streaming = false);
    // List of requests are copied.
    virtual status_t           submitRequestList(List<sp<CaptureRequest> > requests,
                                                 bool streaming = false);
    virtual status_t      cancelRequest(int requestId);

+11 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <utils/String16.h>
#include <utils/Vector.h>
#include <utils/Timers.h>
#include <utils/List.h>

#include "hardware/camera2.h"
#include "camera/CameraMetadata.h"
@@ -57,12 +58,22 @@ class CameraDeviceBase : public virtual RefBase {
     */
    virtual status_t capture(CameraMetadata &request) = 0;

    /**
     * Submit a list of requests.
     */
    virtual status_t captureList(const List<const CameraMetadata> &requests) = 0;

    /**
     * Submit request for streaming. The CameraDevice makes a copy of the
     * passed-in buffer and the caller retains ownership.
     */
    virtual status_t setStreamingRequest(const CameraMetadata &request) = 0;

    /**
     * Submit a list of requests for streaming.
     */
    virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests) = 0;

    /**
     * Clear the streaming request slot.
     */
+12 −0
Original line number Diff line number Diff line
@@ -221,6 +221,12 @@ status_t Camera2Device::capture(CameraMetadata &request) {
    return OK;
}

status_t Camera2Device::captureList(const List<const CameraMetadata> &requests) {
    ATRACE_CALL();
    ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__);
    return INVALID_OPERATION;
}


status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
    ATRACE_CALL();
@@ -229,6 +235,12 @@ status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
    return mRequestQueue.setStreamSlot(streamRequest.release());
}

status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests) {
    ATRACE_CALL();
    ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__);
    return INVALID_OPERATION;
}

status_t Camera2Device::clearStreamingRequest() {
    ATRACE_CALL();
    return mRequestQueue.setStreamSlot(NULL);
+2 −0
Original line number Diff line number Diff line
@@ -48,7 +48,9 @@ class Camera2Device: public CameraDeviceBase {
    virtual status_t dump(int fd, const Vector<String16>& args);
    virtual const CameraMetadata& info() const;
    virtual status_t capture(CameraMetadata &request);
    virtual status_t captureList(const List<const CameraMetadata> &requests);
    virtual status_t setStreamingRequest(const CameraMetadata &request);
    virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests);
    virtual status_t clearStreamingRequest();
    virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout);
    virtual status_t createStream(sp<ANativeWindow> consumer,
Loading