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

Commit bbbbe84b authored by Eino-Ville Talvala's avatar Eino-Ville Talvala
Browse files

Camera: Allow direct selection of operating mode

Instead of a true/false switch for high-speed mode, use an integer
enum instead and define the two existing modes, plus the start
of a vendor mode space.

For all non-high-speed modes, use the normal configuration path,
but pass the operating mode to the HAL.

Test: New CTS test passes
Bug: 34853980
Change-Id: I9dc2b2a2164e9779f079a30e936c4117bcf96efe
parent 17d791ad
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -53,6 +53,22 @@ interface ICameraDeviceUser
     */
    void beginConfigure();

    /**
     * The standard operating mode for a camera device; all API guarantees are in force
     */
    const int NORMAL_MODE = 0;

    /**
     * High-speed recording mode; only two outputs targeting preview and video recording may be
     * used, and requests must be batched.
     */
    const int CONSTRAINED_HIGH_SPEED_MODE = 1;

    /**
     * Start of custom vendor modes
     */
    const int VENDOR_MODE_START = 0x8000;

    /**
     * End the device configuration.
     *
@@ -61,8 +77,10 @@ interface ICameraDeviceUser
     * a call to beginConfigure and subsequent createStream/deleteStream calls).  This
     * must be called before any requests can be submitted.
     * <p>
     * @param operatingMode The kind of session to create; either NORMAL_MODE or
     *     CONSTRAINED_HIGH_SPEED_MODE. Must be a non-negative value.
     */
    void endConfigure(boolean isConstrainedHighSpeed);
    void endConfigure(int operatingMode);

    void deleteStream(int streamId);

+11 −2
Original line number Diff line number Diff line
@@ -321,7 +321,7 @@ binder::Status CameraDeviceClient::beginConfigure() {
    return binder::Status::ok();
}

binder::Status CameraDeviceClient::endConfigure(bool isConstrainedHighSpeed) {
binder::Status CameraDeviceClient::endConfigure(int operatingMode) {
    ALOGV("%s: ending configure (%d input stream, %zu output surfaces)",
            __FUNCTION__, mInputStream.configured ? 1 : 0,
            mStreamMap.size());
@@ -335,7 +335,16 @@ binder::Status CameraDeviceClient::endConfigure(bool isConstrainedHighSpeed) {
        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
    }

    if (operatingMode < 0) {
        String8 msg = String8::format(
            "Camera %s: Invalid operating mode %d requested", mCameraIdStr.string(), operatingMode);
        ALOGE("%s: %s", __FUNCTION__, msg.string());
        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
                msg.string());
    }

    // Sanitize the high speed session against necessary capability bit.
    bool isConstrainedHighSpeed = (operatingMode == ICameraDeviceUser::CONSTRAINED_HIGH_SPEED_MODE);
    if (isConstrainedHighSpeed) {
        CameraMetadata staticInfo = mDevice->info();
        camera_metadata_entry_t entry = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
@@ -357,7 +366,7 @@ binder::Status CameraDeviceClient::endConfigure(bool isConstrainedHighSpeed) {
        }
    }

    status_t err = mDevice->configureStreams(isConstrainedHighSpeed);
    status_t err = mDevice->configureStreams(operatingMode);
    if (err == BAD_VALUE) {
        String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided",
                mCameraIdStr.string());
+17 −17
Original line number Diff line number Diff line
@@ -70,70 +70,70 @@ public:
            const hardware::camera2::CaptureRequest& request,
            bool streaming = false,
            /*out*/
            hardware::camera2::utils::SubmitInfo *submitInfo = nullptr);
            hardware::camera2::utils::SubmitInfo *submitInfo = nullptr) override;
    // List of requests are copied.
    virtual binder::Status submitRequestList(
            const std::vector<hardware::camera2::CaptureRequest>& requests,
            bool streaming = false,
            /*out*/
            hardware::camera2::utils::SubmitInfo *submitInfo = nullptr);
            hardware::camera2::utils::SubmitInfo *submitInfo = nullptr) override;
    virtual binder::Status cancelRequest(int requestId,
            /*out*/
            int64_t* lastFrameNumber = NULL);
            int64_t* lastFrameNumber = NULL) override;

    virtual binder::Status beginConfigure();
    virtual binder::Status beginConfigure() override;

    virtual binder::Status endConfigure(bool isConstrainedHighSpeed = false);
    virtual binder::Status endConfigure(int operatingMode) override;

    // Returns -EBUSY if device is not idle
    virtual binder::Status deleteStream(int streamId);
    virtual binder::Status deleteStream(int streamId) override;

    virtual binder::Status createStream(
            const hardware::camera2::params::OutputConfiguration &outputConfiguration,
            /*out*/
            int32_t* newStreamId = NULL);
            int32_t* newStreamId = NULL) override;

    // Create an input stream of width, height, and format.
    virtual binder::Status createInputStream(int width, int height, int format,
            /*out*/
            int32_t* newStreamId = NULL);
            int32_t* newStreamId = NULL) override;

    // Get the buffer producer of the input stream
    virtual binder::Status getInputSurface(
            /*out*/
            view::Surface *inputSurface);
            view::Surface *inputSurface) override;

    // Create a request object from a template.
    virtual binder::Status createDefaultRequest(int templateId,
            /*out*/
            hardware::camera2::impl::CameraMetadataNative* request);
            hardware::camera2::impl::CameraMetadataNative* request) override;

    // Get the static metadata for the camera
    // -- Caller owns the newly allocated metadata
    virtual binder::Status getCameraInfo(
            /*out*/
            hardware::camera2::impl::CameraMetadataNative* cameraCharacteristics);
            hardware::camera2::impl::CameraMetadataNative* cameraCharacteristics) override;

    // Wait until all the submitted requests have finished processing
    virtual binder::Status waitUntilIdle();
    virtual binder::Status waitUntilIdle() override;

    // Flush all active and pending requests as fast as possible
    virtual binder::Status flush(
            /*out*/
            int64_t* lastFrameNumber = NULL);
            int64_t* lastFrameNumber = NULL) override;

    // Prepare stream by preallocating its buffers
    virtual binder::Status prepare(int32_t streamId);
    virtual binder::Status prepare(int32_t streamId) override;

    // Tear down stream resources by freeing its unused buffers
    virtual binder::Status tearDown(int32_t streamId);
    virtual binder::Status tearDown(int32_t streamId) override;

    // Prepare stream by preallocating up to maxCount of its buffers
    virtual binder::Status prepare2(int32_t maxCount, int32_t streamId);
    virtual binder::Status prepare2(int32_t maxCount, int32_t streamId) override;

    // Finalize the output configurations with surfaces not added before.
    virtual binder::Status finalizeOutputConfigurations(int32_t streamId,
            const hardware::camera2::params::OutputConfiguration &outputConfiguration);
            const hardware::camera2::params::OutputConfiguration &outputConfiguration) override;

    /**
     * Interface used by CameraService
+1 −1
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ class CameraDeviceBase : public virtual RefBase {
     * - BAD_VALUE if the set of streams was invalid (e.g. fmts or sizes)
     * - INVALID_OPERATION if the device was in the wrong state
     */
    virtual status_t configureStreams(bool isConstrainedHighSpeed = false) = 0;
    virtual status_t configureStreams(int operatingMode = 0) = 0;

    // get the buffer producer of the input stream
    virtual status_t getInputBufferProducer(
+39 −21
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ namespace android {

Camera3Device::Camera3Device(const String8 &id):
        mId(id),
        mOperatingMode(NO_MODE),
        mIsConstrainedHighSpeedConfiguration(false),
        mStatus(STATUS_UNINITIALIZED),
        mStatusWaiters(0),
@@ -514,19 +515,25 @@ StreamRotation Camera3Device::mapToStreamRotation(camera3_stream_rotation_t rota
    return StreamRotation::ROTATION_0;
}

StreamConfigurationMode Camera3Device::mapToStreamConfigurationMode(
        camera3_stream_configuration_mode_t operationMode) {
status_t Camera3Device::mapToStreamConfigurationMode(
        camera3_stream_configuration_mode_t operationMode, StreamConfigurationMode *mode) {
    if (mode == nullptr) return BAD_VALUE;
    if (operationMode < CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START) {
        switch(operationMode) {
            case CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE:
            return StreamConfigurationMode::NORMAL_MODE;
                *mode = StreamConfigurationMode::NORMAL_MODE;
                break;
            case CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
            return StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
        case CAMERA3_VENDOR_STREAM_CONFIGURATION_MODE_START:
            // Needs to be mapped by vendor extensions
                *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
                break;
    }
            default:
                ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
    return StreamConfigurationMode::NORMAL_MODE;
                return BAD_VALUE;
        }
    } else {
        *mode = static_cast<StreamConfigurationMode>(operationMode);
    }
    return OK;
}

camera3_buffer_status_t Camera3Device::mapHidlBufferStatus(BufferStatus status) {
@@ -677,8 +684,12 @@ status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
        lines.appendFormat("    Error cause: %s\n", mErrorCause.string());
    }
    lines.appendFormat("    Stream configuration:\n");
    lines.appendFormat("    Operation mode: %s \n", mIsConstrainedHighSpeedConfiguration ?
            "CONSTRAINED HIGH SPEED VIDEO" : "NORMAL");
    const char *mode =
            mOperatingMode == static_cast<int>(StreamConfigurationMode::NORMAL_MODE) ? "NORMAL" :
            mOperatingMode == static_cast<int>(
                StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ? "CONSTRAINED_HIGH_SPEED" :
            "CUSTOM";
    lines.appendFormat("    Operation mode: %s (%d) \n", mode, mOperatingMode);

    if (mInputStream != NULL) {
        write(fd, lines.string(), lines.size());
@@ -1501,16 +1512,21 @@ status_t Camera3Device::deleteReprocessStream(int id) {
    return INVALID_OPERATION;
}

status_t Camera3Device::configureStreams(bool isConstrainedHighSpeed) {
status_t Camera3Device::configureStreams(int operatingMode) {
    ATRACE_CALL();
    ALOGV("%s: E", __FUNCTION__);

    Mutex::Autolock il(mInterfaceLock);
    Mutex::Autolock l(mLock);

    if (mIsConstrainedHighSpeedConfiguration != isConstrainedHighSpeed) {
    bool isConstrainedHighSpeed =
            static_cast<int>(StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ==
            operatingMode;

    if (mOperatingMode != operatingMode) {
        mNeedConfig = true;
        mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
        mOperatingMode = operatingMode;
    }

    return configureStreamsLocked();
@@ -2188,9 +2204,7 @@ status_t Camera3Device::configureStreamsLocked() {
    ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());

    camera3_stream_configuration config;
    config.operation_mode = mIsConstrainedHighSpeedConfiguration ?
            CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE :
            CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE;
    config.operation_mode = mOperatingMode;
    config.num_streams = (mInputStream != NULL) + mOutputStreams.size();

    Vector<camera3_stream_t*> streams;
@@ -3149,8 +3163,12 @@ status_t Camera3Device::HalInterface::configureStreams(camera3_stream_configurat
            }
        }

        requestedConfiguration.operationMode = mapToStreamConfigurationMode(
                (camera3_stream_configuration_mode_t) config->operation_mode);
        res = mapToStreamConfigurationMode(
                (camera3_stream_configuration_mode_t) config->operation_mode,
                /*out*/ &requestedConfiguration.operationMode);
        if (res != OK) {
            return res;
        }

        // Invoke configureStreams

Loading