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

Commit c894bf67 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Camera: pass StreamSurfaceId instead of Surface"

parents e39076fb 4dfa4cca
Loading
Loading
Loading
Loading
+66 −22
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) {

    mMetadata.clear();
    mSurfaceList.clear();
    mStreamIdxList.clear();
    mSurfaceIdxList.clear();

    status_t err = OK;

@@ -53,6 +55,13 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) {
    }
    ALOGV("%s: Read metadata from parcel", __FUNCTION__);

    int isReprocess = 0;
    if ((err = parcel->readInt32(&isReprocess)) != OK) {
        ALOGE("%s: Failed to read reprocessing from parcel", __FUNCTION__);
        return err;
    }
    mIsReprocess = (isReprocess != 0);

    int32_t size;
    if ((err = parcel->readInt32(&size)) != OK) {
        ALOGE("%s: Failed to read surface list size from parcel", __FUNCTION__);
@@ -61,7 +70,7 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) {
    ALOGV("%s: Read surface list size = %d", __FUNCTION__, size);

    // Do not distinguish null arrays from 0-sized arrays.
    for (int i = 0; i < size; ++i) {
    for (int32_t i = 0; i < size; ++i) {
        // Parcel.writeParcelableArray
        size_t len;
        const char16_t* className = parcel->readString16Inplace(&len);
@@ -88,12 +97,32 @@ status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) {
        mSurfaceList.push_back(surface);
    }

    int isReprocess = 0;
    if ((err = parcel->readInt32(&isReprocess)) != OK) {
        ALOGE("%s: Failed to read reprocessing from parcel", __FUNCTION__);
    int32_t streamSurfaceSize;
    if ((err = parcel->readInt32(&streamSurfaceSize)) != OK) {
        ALOGE("%s: Failed to read streamSurfaceSize from parcel", __FUNCTION__);
        return err;
    }
    mIsReprocess = (isReprocess != 0);

    if (streamSurfaceSize < 0) {
        ALOGE("%s: Bad streamSurfaceSize %d from parcel", __FUNCTION__, streamSurfaceSize);
        return BAD_VALUE;
    }

    for (int32_t i = 0; i < streamSurfaceSize; ++i) {
        int streamIdx;
        if ((err = parcel->readInt32(&streamIdx)) != OK) {
            ALOGE("%s: Failed to read stream index from parcel", __FUNCTION__);
            return err;
        }
        mStreamIdxList.push_back(streamIdx);

        int surfaceIdx;
        if ((err = parcel->readInt32(&surfaceIdx)) != OK) {
            ALOGE("%s: Failed to read surface index from parcel", __FUNCTION__);
            return err;
        }
        mSurfaceIdxList.push_back(surfaceIdx);
    }

    return OK;
}
@@ -110,6 +139,11 @@ status_t CaptureRequest::writeToParcel(android::Parcel* parcel) const {
        return err;
    }

    parcel->writeInt32(mIsReprocess ? 1 : 0);

    if (mSurfaceConverted) {
        parcel->writeInt32(0); // 0-sized array
    } else {
        int32_t size = static_cast<int32_t>(mSurfaceList.size());

        // Send 0-sized arrays when it's empty. Do not send null arrays.
@@ -129,9 +163,19 @@ status_t CaptureRequest::writeToParcel(android::Parcel* parcel) const {
                return err;
            }
        }
    }

    parcel->writeInt32(mIsReprocess ? 1 : 0);

    parcel->writeInt32(mStreamIdxList.size());
    for (size_t i = 0; i < mStreamIdxList.size(); ++i) {
        if ((err = parcel->writeInt32(mStreamIdxList[i])) != OK) {
            ALOGE("%s: Failed to write stream index to parcel", __FUNCTION__);
            return err;
        }
        if ((err = parcel->writeInt32(mSurfaceIdxList[i])) != OK) {
            ALOGE("%s: Failed to write surface index to parcel", __FUNCTION__);
            return err;
        }
    }
    return OK;
}

+16 −0
Original line number Diff line number Diff line
@@ -41,14 +41,30 @@ struct CaptureRequest : public Parcelable {
    virtual ~CaptureRequest();

    CameraMetadata          mMetadata;

    // Used by NDK client to pass surfaces by stream/surface index.
    bool                    mSurfaceConverted = false;

    // Starting in Android O, create a Surface from Parcel will take one extra
    // IPC call.
    Vector<sp<Surface> >    mSurfaceList;
    // Optional way of passing surface list since passing Surface over binder
    // is expensive. Use the stream/surface index from current output configuration
    // to represent an configured output Surface. When stream/surface index is used,
    // set mSurfaceList to zero length to save unparcel time.
    Vector<int>             mStreamIdxList;
    Vector<int>             mSurfaceIdxList; // per stream surface list index

    bool                    mIsReprocess;

    void*                   mContext; // arbitrary user context from NDK apps, null for java apps

    /**
     * Keep impl up-to-date with CaptureRequest.java in frameworks/base
     */
    // used by cameraserver to receive CaptureRequest from java/NDK client
    status_t                readFromParcel(const android::Parcel* parcel) override;
    // used by NDK client to send CaptureRequest to cameraserver
    status_t                writeToParcel(android::Parcel* parcel) const override;
};

+1 −1
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ camera_status_t ACameraCaptureSession::updateOutputConfiguration(ACaptureSession
    dev->lockDeviceForSessionOps();
    {
        Mutex::Autolock _l(mSessionLock);
        ret = dev->updateOutputConfiguration(output);
        ret = dev->updateOutputConfigurationLocked(output);
    }
    dev->unlockDevice();
    return ret;
+50 −23
Original line number Diff line number Diff line
@@ -289,7 +289,7 @@ CameraDevice::submitRequestsLocked(
    return ACAMERA_OK;
}

camera_status_t CameraDevice::updateOutputConfiguration(ACaptureSessionOutput *output) {
camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
    camera_status_t ret = checkCameraClosedOrErrorLocked();
    if (ret != ACAMERA_OK) {
        return ret;
@@ -361,6 +361,7 @@ camera_status_t CameraDevice::updateOutputConfiguration(ACaptureSessionOutput *o
                return ACAMERA_ERROR_UNKNOWN;
        }
    }
    mConfiguredOutputs[streamId] = std::make_pair(output->mWindow, outConfig);

    return ACAMERA_OK;
}
@@ -373,6 +374,7 @@ CameraDevice::allocateCaptureRequest(
    req->mMetadata = request->settings->getInternalData();
    req->mIsReprocess = false; // NDK does not support reprocessing yet
    req->mContext = request->context;
    req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC

    for (auto outputTarget : request->targets->mOutputs) {
        ANativeWindow* anw = outputTarget.mWindow;
@@ -383,7 +385,31 @@ CameraDevice::allocateCaptureRequest(
            return ret;
        }
        req->mSurfaceList.push_back(surface);

        bool found = false;
        // lookup stream/surface ID
        for (const auto& kvPair : mConfiguredOutputs) {
            int streamId = kvPair.first;
            const OutputConfiguration& outConfig = kvPair.second.second;
            const auto& gbps = outConfig.getGraphicBufferProducers();
            for (int surfaceId = 0; surfaceId < (int) gbps.size(); surfaceId++) {
                if (gbps[surfaceId] == surface->getIGraphicBufferProducer()) {
                    found = true;
                    req->mStreamIdxList.push_back(streamId);
                    req->mSurfaceIdxList.push_back(surfaceId);
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (!found) {
            ALOGE("Unconfigured output target %p in capture request!", anw);
            return ret;
        }
    }

    outReq = req;
    return ACAMERA_OK;
}
@@ -564,17 +590,11 @@ camera_status_t
CameraDevice::getIGBPfromAnw(
        ANativeWindow* anw,
        sp<IGraphicBufferProducer>& out) {
    if (anw == nullptr) {
        ALOGE("Error: output ANativeWindow is null");
        return ACAMERA_ERROR_INVALID_PARAMETER;
    }
    int value;
    int err = (*anw->query)(anw, NATIVE_WINDOW_CONCRETE_TYPE, &value);
    if (err != OK || value != NATIVE_WINDOW_SURFACE) {
        ALOGE("Error: ANativeWindow is not backed by Surface!");
        return ACAMERA_ERROR_INVALID_PARAMETER;
    sp<Surface> surface;
    camera_status_t ret = getSurfaceFromANativeWindow(anw, surface);
    if (ret != ACAMERA_OK) {
        return ret;
    }
    const sp<Surface> surface(static_cast<Surface*>(anw));
    out = surface->getIGraphicBufferProducer();
    return ACAMERA_OK;
}
@@ -809,8 +829,12 @@ CameraDevice::onCaptureErrorLocked(
            setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_SERVICE);
            return;
        }
        ANativeWindow* anw = outputPairIt->second.first;

        const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
        for (const auto& outGbp : gbps) {
            for (auto surface : request->mSurfaceList) {
                if (surface->getIGraphicBufferProducer() == outGbp) {
                    ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
                    ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
                            getId(), anw, frameNumber);

@@ -822,6 +846,9 @@ CameraDevice::onCaptureErrorLocked(
                    msg->setPointer(kAnwKey, (void*) anw);
                    msg->setInt64(kFrameNumberKey, frameNumber);
                    postSessionMsgAndCleanup(msg);
                }
            }
        }
    } else { // Handle other capture failures
        // Fire capture failure callback if there is one registered
        ACameraCaptureSession_captureCallback_failed onError = cbh.mCallbacks.onCaptureFailed;
+2 −2
Original line number Diff line number Diff line
@@ -123,9 +123,9 @@ class CameraDevice final : public RefBase {
            /*out*/int* captureSequenceId,
            bool isRepeating);

    camera_status_t updateOutputConfiguration(ACaptureSessionOutput *output);
    camera_status_t updateOutputConfigurationLocked(ACaptureSessionOutput *output);

    static camera_status_t allocateCaptureRequest(
    camera_status_t allocateCaptureRequest(
            const ACaptureRequest* request, sp<CaptureRequest>& outReq);

    static ACaptureRequest* allocateACaptureRequest(sp<CaptureRequest>& req);
Loading