From 52e9ad48ddd3c2e7c90a9002a2a65a5d63125b78 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Wed, 19 Sep 2012 17:09:15 -0700 Subject: 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 --- .../libcameraservice/camera2/CaptureSequencer.cpp | 46 +++++++++++++++------- .../libcameraservice/camera2/CaptureSequencer.h | 6 ++- .../libcameraservice/camera2/JpegProcessor.cpp | 18 ++------- 3 files changed, 39 insertions(+), 31 deletions(-) (limited to 'services/camera') diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp index 24ecf28..941ad15 100644 --- a/services/camera/libcameraservice/camera2/CaptureSequencer.cpp +++ b/services/camera/libcameraservice/camera2/CaptureSequencer.cpp @@ -96,11 +96,13 @@ void CaptureSequencer::onFrameAvailable(int32_t frameId, } } -void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp) { +void CaptureSequencer::onCaptureAvailable(nsecs_t timestamp, + sp 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 &c } CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp &client) { - status_t res; + status_t res = OK; ATRACE_CALL(); mCaptureId++; @@ -204,20 +206,34 @@ CaptureSequencer::CaptureState CaptureSequencer::manageDone(sp &c mBusy = false; } - SharedParameters::Lock l(client->getParameters()); - switch (l.mParameters.state) { - case Parameters::STILL_CAPTURE: - l.mParameters.state = Parameters::STOPPED; - break; - case Parameters::VIDEO_SNAPSHOT: - l.mParameters.state = Parameters::RECORD; - break; - default: - ALOGE("%s: Camera %d: Still image produced unexpectedly " - "in state %s!", - __FUNCTION__, client->getCameraId(), - Parameters::getStateName(l.mParameters.state)); + { + SharedParameters::Lock l(client->getParameters()); + switch (l.mParameters.state) { + case Parameters::STILL_CAPTURE: + l.mParameters.state = Parameters::STOPPED; + break; + case Parameters::VIDEO_SNAPSHOT: + l.mParameters.state = Parameters::RECORD; + break; + default: + ALOGE("%s: Camera %d: Still image produced unexpectedly " + "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; } diff --git a/services/camera/libcameraservice/camera2/CaptureSequencer.h b/services/camera/libcameraservice/camera2/CaptureSequencer.h index 474bdac..f0d1e79 100644 --- a/services/camera/libcameraservice/camera2/CaptureSequencer.h +++ b/services/camera/libcameraservice/camera2/CaptureSequencer.h @@ -17,6 +17,7 @@ #ifndef ANDROID_SERVERS_CAMERA_CAMERA2_CAPTURESEQUENCER_H #define ANDROID_SERVERS_CAMERA_CAMERA2_CAPTURESEQUENCER_H +#include #include #include #include @@ -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 captureBuffer); void dump(int fd, const Vector& args); @@ -85,6 +86,7 @@ class CaptureSequencer: bool mNewCaptureReceived; nsecs_t mCaptureTimestamp; + sp mCaptureBuffer; Condition mNewCaptureSignal; /** diff --git a/services/camera/libcameraservice/camera2/JpegProcessor.cpp b/services/camera/libcameraservice/camera2/JpegProcessor.cpp index b230d2d..7ab9c87 100644 --- a/services/camera/libcameraservice/camera2/JpegProcessor.cpp +++ b/services/camera/libcameraservice/camera2/JpegProcessor.cpp @@ -230,11 +230,6 @@ status_t JpegProcessor::processNewCapture(sp &client) { return OK; } - sp 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 &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 sequencer = mSequencer.promote(); + if (sequencer != 0) { + sequencer->onCaptureAvailable(imgBuffer.timestamp, mCaptureHeap->mBuffers[0]); } + return OK; } -- cgit v1.1