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

Commit e1f813ca authored by Jayant Chowdhary's avatar Jayant Chowdhary Committed by Android (Google) Code Review
Browse files

Merge changes from topic "ndk-prepare-surface"

* changes:
  Fix map key in PreparerThread pending streams.
  camera2 (v)ndk: Add APIs for pre-allocation of surface buffers.
parents ca26080b 57184d51
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ void ACameraCaptureSession_close(ACameraCaptureSession* session) {
    if (session != nullptr) {
        session->closeByApp();
    }

    return;
}

@@ -191,3 +192,42 @@ camera_status_t ACameraCaptureSession_updateSharedOutput(ACameraCaptureSession*
    }
    return session->updateOutputConfiguration(output);
}
EXPORT
camera_status_t ACameraCaptureSession_setWindowPreparedCallback(
        ACameraCaptureSession* session, ACameraCaptureSession_prepareCallbacks *cb) {
    ATRACE_CALL();
    if (session == nullptr || cb == nullptr) {
        ALOGE("%s: Error: session %p / callback %p is null", __FUNCTION__, session, cb);
        return ACAMERA_ERROR_INVALID_PARAMETER;
    }

    if (cb->reserved0 != nullptr || cb->reserved1 != nullptr) {
         ALOGE("%s: Setting reserved 0 and reserved 1 fields of "
               "ACameraCaptureSession_prepareCallbacks is currently not supported "
               " .They must be set to  null", __FUNCTION__);
        return ACAMERA_ERROR_INVALID_PARAMETER;
    }
    if (session->isClosed()) {
        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
        return ACAMERA_ERROR_SESSION_CLOSED;
    }
    session->setWindowPreparedCallback(cb);
    return ACAMERA_OK;
}

EXPORT
camera_status_t ACameraCaptureSession_prepareWindow(
        ACameraCaptureSession* session,
        ACameraWindowType *window) {
    ATRACE_CALL();
    if (session == nullptr || window == nullptr) {
        ALOGE("%s: Error: session %p / window %p is null", __FUNCTION__, session, window);
        return ACAMERA_ERROR_INVALID_PARAMETER;
    }

    if (session->isClosed()) {
        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
        return ACAMERA_ERROR_SESSION_CLOSED;
    }
    return session->prepare(window);
}
 No newline at end of file
+21 −0
Original line number Diff line number Diff line
@@ -146,6 +146,27 @@ camera_status_t ACameraCaptureSession::updateOutputConfiguration(ACaptureSession
    return ret;
}

camera_status_t ACameraCaptureSession::prepare(ACameraWindowType* window) {
#ifdef __ANDROID_VNDK__
    std::shared_ptr<acam::CameraDevice> dev = getDevicePtr();
#else
    sp<acam::CameraDevice> dev = getDeviceSp();
#endif
    if (dev == nullptr) {
        ALOGE("Error: Device associated with session %p has been closed!", this);
        return ACAMERA_ERROR_SESSION_CLOSED;
    }

    camera_status_t ret;
    dev->lockDeviceForSessionOps();
    {
        Mutex::Autolock _l(mSessionLock);
        ret = dev->prepareLocked(window);
    }
    dev->unlockDevice();
    return ret;
}

ACameraDevice*
ACameraCaptureSession::getDevice() {
    Mutex::Autolock _l(mSessionLock);
+7 −0
Original line number Diff line number Diff line
@@ -130,6 +130,12 @@ struct ACameraCaptureSession : public RefBase {

    camera_status_t updateOutputConfiguration(ACaptureSessionOutput *output);

    void setWindowPreparedCallback(ACameraCaptureSession_prepareCallbacks *cb) {
        Mutex::Autolock _l(mSessionLock);
        mPreparedCb = *cb;
    }
    camera_status_t prepare(ACameraWindowType *window);

    ACameraDevice* getDevice();

  private:
@@ -156,6 +162,7 @@ struct ACameraCaptureSession : public RefBase {

    bool  mIsClosed = false;
    bool  mClosedByApp = false;
    ACameraCaptureSession_prepareCallbacks mPreparedCb;
    Mutex mSessionLock;
};

+104 −2
Original line number Diff line number Diff line
@@ -342,6 +342,58 @@ camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOut
    return ACAMERA_OK;
}

camera_status_t CameraDevice::prepareLocked(ACameraWindowType *window) {
    camera_status_t ret = checkCameraClosedOrErrorLocked();
    if (ret != ACAMERA_OK) {
        return ret;
    }

    if (window == nullptr) {
        return ACAMERA_ERROR_INVALID_PARAMETER;
    }

    int32_t streamId = -1;
    for (auto& kvPair : mConfiguredOutputs) {
        if (window == kvPair.second.first) {
            streamId = kvPair.first;
            break;
        }
    }
    if (streamId < 0) {
        ALOGE("Error: Invalid output configuration");
        return ACAMERA_ERROR_INVALID_PARAMETER;
    }
    auto remoteRet = mRemote->prepare(streamId);
    if (!remoteRet.isOk()) {
        // TODO:(b/259735869) Do this check for all other binder calls in the
        // ndk as well.
        if (remoteRet.exceptionCode() != EX_SERVICE_SPECIFIC) {
            ALOGE("Camera device %s failed to prepare output window %p: %s", getId(), window,
                    remoteRet.toString8().string());
            return ACAMERA_ERROR_UNKNOWN;

        }
        switch (remoteRet.serviceSpecificErrorCode()) {
            case hardware::ICameraService::ERROR_INVALID_OPERATION:
                ALOGE("Camera device %s invalid operation: %s", getId(),
                        remoteRet.toString8().string());
                return ACAMERA_ERROR_INVALID_OPERATION;
                break;
            case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
                ALOGE("Camera device %s invalid input argument: %s", getId(),
                        remoteRet.toString8().string());
                return ACAMERA_ERROR_INVALID_PARAMETER;
                break;
            default:
                ALOGE("Camera device %s failed to prepare output window %p: %s", getId(), window,
                        remoteRet.toString8().string());
                return ACAMERA_ERROR_UNKNOWN;
        }
    }

    return ACAMERA_OK;
}

camera_status_t
CameraDevice::allocateCaptureRequest(
        const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
@@ -919,6 +971,7 @@ void CameraDevice::CallbackHandler::onMessageReceived(
        case kWhatCaptureSeqEnd:
        case kWhatCaptureSeqAbort:
        case kWhatCaptureBufferLost:
        case kWhatPreparedCb:
            ALOGV("%s: Received msg %d", __FUNCTION__, msg->what());
            break;
        case kWhatCleanUpSessions:
@@ -992,6 +1045,7 @@ void CameraDevice::CallbackHandler::onMessageReceived(
        case kWhatCaptureSeqEnd:
        case kWhatCaptureSeqAbort:
        case kWhatCaptureBufferLost:
        case kWhatPreparedCb:
        {
            sp<RefBase> obj;
            found = msg->findObject(kSessionSpKey, &obj);
@@ -1034,6 +1088,26 @@ void CameraDevice::CallbackHandler::onMessageReceived(
                    (*onState)(context, session.get());
                    break;
                }
                case kWhatPreparedCb:
                {
                    ACameraCaptureSession_prepareCallback onWindowPrepared;
                    found = msg->findPointer(kCallbackFpKey, (void**) &onWindowPrepared);
                    if (!found) {
                        ALOGE("%s: Cannot find state callback!", __FUNCTION__);
                        return;
                    }
                    if (onWindowPrepared == nullptr) {
                        return;
                    }
                    ACameraWindowType* anw;
                    found = msg->findPointer(kAnwKey, (void**) &anw);
                    if (!found) {
                        ALOGE("%s: Cannot find ANativeWindow: %d!", __FUNCTION__, __LINE__);
                        return;
                    }
                    (*onWindowPrepared)(context, anw, session.get());
                    break;
                }
                case kWhatCaptureStart:
                {
                    ACameraCaptureSession_captureCallback_start onStart;
@@ -1729,8 +1803,36 @@ CameraDevice::ServiceCallback::onResultReceived(
}

binder::Status
CameraDevice::ServiceCallback::onPrepared(int) {
    // Prepare not yet implemented in NDK
CameraDevice::ServiceCallback::onPrepared(int streamId) {
    ALOGV("%s: callback for stream id %d", __FUNCTION__, streamId);
    binder::Status ret = binder::Status::ok();
    sp<CameraDevice> dev = mDevice.promote();
    if (dev == nullptr) {
        return ret; // device has been closed
    }
    Mutex::Autolock _l(dev->mDeviceLock);
    if (dev->isClosed() || dev->mRemote == nullptr) {
        return ret;
    }
    auto it = dev->mConfiguredOutputs.find(streamId);
    if (it == dev->mConfiguredOutputs.end()) {
        ALOGE("%s: stream id %d does not exist", __FUNCTION__ , streamId);
        return ret;
    }
    sp<ACameraCaptureSession> session = dev->mCurrentSession.promote();
    if (session == nullptr) {
        ALOGE("%s: Session is dead already", __FUNCTION__ );
        return ret;
    }
    // We've found the window corresponding to the surface id.
    ACameraWindowType *window = it->second.first;
    sp<AMessage> msg = new AMessage(kWhatPreparedCb, dev->mHandler);
    msg->setPointer(kContextKey, session->mPreparedCb.context);
    msg->setPointer(kAnwKey, window);
    msg->setObject(kSessionSpKey, session);
    msg->setPointer(kCallbackFpKey, (void *)session->mPreparedCb.onWindowPrepared);
    dev->postSessionMsgAndCleanup(msg);

    return binder::Status::ok();
}

+4 −1
Original line number Diff line number Diff line
@@ -151,6 +151,8 @@ class CameraDevice final : public RefBase {

    camera_status_t updateOutputConfigurationLocked(ACaptureSessionOutput *output);

    camera_status_t prepareLocked(ACameraWindowType *window);

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

@@ -223,6 +225,7 @@ class CameraDevice final : public RefBase {
        kWhatCaptureSeqEnd,    // onCaptureSequenceCompleted
        kWhatCaptureSeqAbort,  // onCaptureSequenceAborted
        kWhatCaptureBufferLost, // onCaptureBufferLost
        kWhatPreparedCb, // onWindowPrepared
        // Internal cleanup
        kWhatCleanUpSessions   // Cleanup cached sp<ACameraCaptureSession>
    };
Loading