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

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

Camera2: State must be STOPPED before JPEG callback is fired.

Move handling of JPEG callback to CaptureSequencer instead of
JpegProcessor, so that we can be sure the camera state is updated to
STOPPED before the JPEG callback is sent to the application layer.

Bug: 7172743
Change-Id: Ie8752d946d3eb8254230c77f10e5c38a83dc5371
parent da1c5c15
Loading
Loading
Loading
Loading
+31 −15
Original line number Diff line number Diff line
@@ -96,11 +96,13 @@ void CaptureSequencer::onFrameAvailable(int32_t frameId,
    }
}

void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp) {
void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp,
        sp<MemoryBase> captureBuffer) {
    ATRACE_CALL();
    ALOGV("%s", __FUNCTION__);
    Mutex::Autolock l(mInputMutex);
    mCaptureTimestamp = timestamp;
    mCaptureBuffer = captureBuffer;
    if (!mNewCaptureReceived) {
        mNewCaptureReceived = true;
        mNewCaptureSignal.signal();
@@ -195,7 +197,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageIdle(sp<Camera2Client> &c
}

CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &client) {
    status_t res;
    status_t res = OK;
    ATRACE_CALL();
    mCaptureId++;

@@ -204,6 +206,7 @@ CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &c
        mBusy = false;
    }

    {
        SharedParameters::Lock l(client->getParameters());
        switch (l.mParameters.state) {
            case Parameters::STILL_CAPTURE:
@@ -217,7 +220,20 @@ CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp<Camera2Client> &c
                        "in state %s!",
                        __FUNCTION__, client->getCameraId(),
                        Parameters::getStateName(l.mParameters.state));
                res = INVALID_OPERATION;
        }
    }
    if (mCaptureBuffer != 0 && res == OK) {
        Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
        ALOGV("%s: Sending still image to client", __FUNCTION__);
        if (l.mCameraClient != 0) {
            l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
                    mCaptureBuffer, NULL);
        } else {
            ALOGV("%s: No client!", __FUNCTION__);
        }
    }
    mCaptureBuffer.clear();

    return IDLE;
}
+4 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#ifndef ANDROID_SERVERS_CAMERA_CAMERA2_CAPTURESEQUENCER_H
#define ANDROID_SERVERS_CAMERA_CAMERA2_CAPTURESEQUENCER_H

#include <binder/MemoryBase.h>
#include <utils/Thread.h>
#include <utils/String16.h>
#include <utils/Vector.h>
@@ -58,8 +59,8 @@ class CaptureSequencer:
    // Notifications from the frame processor
    virtual void onFrameAvailable(int32_t frameId, CameraMetadata &frame);

    // Notifications from the capture processor
    void onCaptureAvailable(nsecs_t timestamp);
    // Notifications from the JPEG processor
    void onCaptureAvailable(nsecs_t timestamp, sp<MemoryBase> captureBuffer);

    void dump(int fd, const Vector<String16>& args);

@@ -85,6 +86,7 @@ class CaptureSequencer:

    bool mNewCaptureReceived;
    nsecs_t mCaptureTimestamp;
    sp<MemoryBase> mCaptureBuffer;
    Condition mNewCaptureSignal;

    /**
+4 −14
Original line number Diff line number Diff line
@@ -230,11 +230,6 @@ status_t JpegProcessor::processNewCapture(sp<Camera2Client> &client) {
        return OK;
    }

    sp<CaptureSequencer> sequencer = mSequencer.promote();
    if (sequencer != 0) {
        sequencer->onCaptureAvailable(imgBuffer.timestamp);
    }

    // TODO: Optimize this to avoid memcopy
    void* captureMemory = mCaptureHeap->mHeap->getBase();
    size_t size = mCaptureHeap->mHeap->getSize();
@@ -242,16 +237,11 @@ status_t JpegProcessor::processNewCapture(sp<Camera2Client> &client) {

    mCaptureConsumer->unlockBuffer(imgBuffer);

    captureHeap = mCaptureHeap;

    Camera2Client::SharedCameraClient::Lock l(client->mSharedCameraClient);
    ALOGV("%s: Sending still image to client", __FUNCTION__);
    if (l.mCameraClient != 0) {
        l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
                captureHeap->mBuffers[0], NULL);
    } else {
        ALOGV("%s: No client!", __FUNCTION__);
    sp<CaptureSequencer> sequencer = mSequencer.promote();
    if (sequencer != 0) {
        sequencer->onCaptureAvailable(imgBuffer.timestamp, mCaptureHeap->mBuffers[0]);
    }

    return OK;
}