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

Commit 5051b530 authored by Eino-Ville Talvala's avatar Eino-Ville Talvala Committed by Android (Google) Code Review
Browse files

Merge "Camera: Add preview callback surface support"

parents 96c9b6e0 3ee3550a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -255,6 +255,14 @@ void Camera::setPreviewCallbackFlags(int flag)
    mCamera->setPreviewCallbackFlag(flag);
}

status_t Camera::setPreviewCallbackTarget(
        const sp<IGraphicBufferProducer>& callbackProducer)
{
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->setPreviewCallbackTarget(callbackProducer);
}

// callback from camera service
void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
{
+21 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ enum {
    DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
    SET_PREVIEW_TEXTURE,
    SET_PREVIEW_CALLBACK_FLAG,
    SET_PREVIEW_CALLBACK_TARGET,
    START_PREVIEW,
    STOP_PREVIEW,
    AUTO_FOCUS,
@@ -90,6 +91,18 @@ public:
        remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply);
    }

    status_t setPreviewCallbackTarget(
            const sp<IGraphicBufferProducer>& callbackProducer)
    {
        ALOGV("setPreviewCallbackTarget");
        Parcel data, reply;
        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
        sp<IBinder> b(callbackProducer->asBinder());
        data.writeStrongBinder(b);
        remote()->transact(SET_PREVIEW_CALLBACK_TARGET, data, &reply);
        return reply.readInt32();
    }

    // start preview mode, must call setPreviewDisplay first
    status_t startPreview()
    {
@@ -285,6 +298,14 @@ status_t BnCamera::onTransact(
            setPreviewCallbackFlag(callback_flag);
            return NO_ERROR;
        } break;
        case SET_PREVIEW_CALLBACK_TARGET: {
            ALOGV("SET_PREVIEW_CALLBACK_TARGET");
            CHECK_INTERFACE(ICamera, data, reply);
            sp<IGraphicBufferProducer> cp =
                interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
            reply->writeInt32(setPreviewCallbackTarget(cp));
            return NO_ERROR;
        }
        case START_PREVIEW: {
            ALOGV("START_PREVIEW");
            CHECK_INTERFACE(ICamera, data, reply);
+8 −0
Original line number Diff line number Diff line
@@ -121,7 +121,15 @@ public:

            void        setListener(const sp<CameraListener>& listener);
            void        setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener);

            // Configure preview callbacks to app. Only one of the older
            // callbacks or the callback surface can be active at the same time;
            // enabling one will disable the other if active. Flags can be
            // disabled by calling it with CAMERA_FRAME_CALLBACK_FLAG_NOOP, and
            // Target by calling it with a NULL interface.
            void        setPreviewCallbackFlags(int preview_callback_flag);
            status_t    setPreviewCallbackTarget(
                    const sp<IGraphicBufferProducer>& callbackProducer);

            sp<ICameraRecordingProxy> getRecordingProxy();

+8 −1
Original line number Diff line number Diff line
@@ -51,8 +51,15 @@ public:
            const sp<IGraphicBufferProducer>& bufferProducer) = 0;

    // set the preview callback flag to affect how the received frames from
    // preview are handled.
    // preview are handled. Enabling preview callback flags disables any active
    // preview callback surface set by setPreviewCallbackTarget().
    virtual void            setPreviewCallbackFlag(int flag) = 0;
    // set a buffer interface to use for client-received preview frames instead
    // of preview callback buffers. Passing a valid interface here disables any
    // active preview callbacks set by setPreviewCallbackFlag(). Passing NULL
    // disables the use of the callback target.
    virtual status_t        setPreviewCallbackTarget(
            const sp<IGraphicBufferProducer>& callbackProducer) = 0;

    // start preview mode, must call setPreviewDisplay first
    virtual status_t        startPreview() = 0;
+83 −12
Original line number Diff line number Diff line
@@ -578,7 +578,21 @@ void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
        params.previewCallbackOneShot = true;
    }
    if (params.previewCallbackFlags != (uint32_t)flag) {

        if (flag != CAMERA_FRAME_CALLBACK_FLAG_NOOP) {
            // Disable any existing preview callback window when enabling
            // preview callback flags
            res = mCallbackProcessor->setCallbackWindow(NULL);
            if (res != OK) {
                ALOGE("%s: Camera %d: Unable to clear preview callback surface:"
                        " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
                return;
            }
            params.previewCallbackSurface = false;
        }

        params.previewCallbackFlags = flag;

        switch(params.state) {
            case Parameters::PREVIEW:
                res = startPreviewL(params, true);
@@ -599,6 +613,59 @@ void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {

}

status_t Camera2Client::setPreviewCallbackTarget(
        const sp<IGraphicBufferProducer>& callbackProducer) {
    ATRACE_CALL();
    ALOGV("%s: E", __FUNCTION__);
    Mutex::Autolock icl(mBinderSerializationLock);
    status_t res;
    if ( (res = checkPid(__FUNCTION__) ) != OK) return res;

    sp<ANativeWindow> window;
    if (callbackProducer != 0) {
        window = new Surface(callbackProducer);
    }

    res = mCallbackProcessor->setCallbackWindow(window);
    if (res != OK) {
        ALOGE("%s: Camera %d: Unable to set preview callback surface: %s (%d)",
                __FUNCTION__, mCameraId, strerror(-res), res);
        return res;
    }

    SharedParameters::Lock l(mParameters);

    if (window != NULL) {
        // Disable traditional callbacks when a valid callback target is given
        l.mParameters.previewCallbackFlags = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
        l.mParameters.previewCallbackOneShot = false;
        l.mParameters.previewCallbackSurface = true;
    } else {
        // Disable callback target if given a NULL interface.
        l.mParameters.previewCallbackSurface = false;
    }

    switch(l.mParameters.state) {
        case Parameters::PREVIEW:
            res = startPreviewL(l.mParameters, true);
            break;
        case Parameters::RECORD:
        case Parameters::VIDEO_SNAPSHOT:
            res = startRecordingL(l.mParameters, true);
            break;
        default:
            break;
    }
    if (res != OK) {
        ALOGE("%s: Camera %d: Unable to refresh request in state %s",
                __FUNCTION__, mCameraId,
                Parameters::getStateName(l.mParameters.state));
    }

    return OK;
}


status_t Camera2Client::startPreview() {
    ATRACE_CALL();
    ALOGV("%s: E", __FUNCTION__);
@@ -645,8 +712,10 @@ status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
    }

    Vector<uint8_t> outputStreams;
    bool callbacksEnabled = params.previewCallbackFlags &
        CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
    bool callbacksEnabled = (params.previewCallbackFlags &
            CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ||
            params.previewCallbackSurface;

    if (callbacksEnabled) {
        res = mCallbackProcessor->updateStream(params);
        if (res != OK) {
@@ -860,8 +929,10 @@ status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
    }

    Vector<uint8_t> outputStreams;
    bool callbacksEnabled = params.previewCallbackFlags &
        CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
    bool callbacksEnabled = (params.previewCallbackFlags &
            CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ||
            params.previewCallbackSurface;

    if (callbacksEnabled) {
        res = mCallbackProcessor->updateStream(params);
        if (res != OK) {
Loading