diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2013-04-27 00:10:38 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-04-27 00:10:38 +0000 |
commit | 7081533bea68a71014d708776d0c384c45321ec5 (patch) | |
tree | b353c2b24099757bec6d4ff34f8046ca0b6352d4 | |
parent | c34e097efc5eeefe977972b08a42509e8aa3ccc5 (diff) | |
parent | 02f8457cf788e09e4f0c302dda453f13293009e7 (diff) | |
download | frameworks_av-7081533bea68a71014d708776d0c384c45321ec5.zip frameworks_av-7081533bea68a71014d708776d0c384c45321ec5.tar.gz frameworks_av-7081533bea68a71014d708776d0c384c45321ec5.tar.bz2 |
Merge "Camera2: Fix deadlock on shutdown due to client getting killed." into jb-mr2-dev
11 files changed, 263 insertions, 149 deletions
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp index 9421a77..eae7461 100644 --- a/services/camera/libcameraservice/Camera2Client.cpp +++ b/services/camera/libcameraservice/Camera2Client.cpp @@ -135,6 +135,7 @@ status_t Camera2Client::initialize(camera_module_t *module) Camera2Client::~Camera2Client() { ATRACE_CALL(); + ALOGV("~Camera2Client"); mDestructionStarted = true; @@ -369,6 +370,12 @@ void Camera2Client::disconnect() { ALOGV("Camera %d: Shutting down", mCameraId); + /** + * disconnect() cannot call any methods that might need to promote a + * wp<Camera2Client>, since disconnect can be called from the destructor, at + * which point all such promotions will fail. + */ + stopPreviewL(); { @@ -538,7 +545,12 @@ status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder, break; case Parameters::PREVIEW: // Already running preview - need to stop and create a new stream - mStreamingProcessor->stopStream(); + res = stopStream(); + if (res != OK) { + ALOGE("%s: Unable to stop preview to swap windows: %s (%d)", + __FUNCTION__, strerror(-res), res); + return res; + } state = Parameters::WAITING_FOR_PREVIEW_WINDOW; break; } @@ -745,7 +757,11 @@ void Camera2Client::stopPreviewL() { // no break case Parameters::RECORD: case Parameters::PREVIEW: - mStreamingProcessor->stopStream(); + res = stopStream(); + if (res != OK) { + ALOGE("%s: Camera %d: Can't stop streaming: %s (%d)", + __FUNCTION__, mCameraId, strerror(-res), res); + } res = mDevice->waitUntilDrained(); if (res != OK) { ALOGE("%s: Camera %d: Waiting to stop streaming failed: %s (%d)", diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp index 946cdba..77df152 100644 --- a/services/camera/libcameraservice/Camera2Device.cpp +++ b/services/camera/libcameraservice/Camera2Device.cpp @@ -1133,7 +1133,8 @@ cleanUpBuffers: status_t Camera2Device::StreamAdapter::release() { ATRACE_CALL(); status_t res; - ALOGV("%s: Releasing stream %d", __FUNCTION__, mId); + ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId, + mWidth, mHeight, mFormat); if (mState >= ALLOCATED) { res = mHal2Device->ops->release_stream(mHal2Device, mId); if (res != OK) { diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 2db5224..cdeb92e 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -793,6 +793,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, // tear down the client CameraService::Client::~Client() { + ALOGV("~Client"); mDestructionStarted = true; mCameraService->releaseSound(); @@ -820,10 +821,12 @@ CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService, } CameraService::BasicClient::~BasicClient() { + ALOGV("~BasicClient"); mDestructionStarted = true; } void CameraService::BasicClient::disconnect() { + ALOGV("BasicClient::disconnect"); mCameraService->removeClientByRemote(mRemoteBinder); // client shouldn't be able to call into us anymore mClientPid = 0; @@ -922,6 +925,7 @@ void CameraService::Client::notifyError() { // NOTE: function is idempotent void CameraService::Client::disconnect() { + ALOGV("Client::disconnect"); BasicClient::disconnect(); mCameraService->setCameraFree(mCameraId); mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT, diff --git a/services/camera/libcameraservice/camera2/CallbackProcessor.cpp b/services/camera/libcameraservice/camera2/CallbackProcessor.cpp index 30c14ef..dd37283 100644 --- a/services/camera/libcameraservice/camera2/CallbackProcessor.cpp +++ b/services/camera/libcameraservice/camera2/CallbackProcessor.cpp @@ -30,9 +30,11 @@ namespace android { namespace camera2 { -CallbackProcessor::CallbackProcessor(wp<Camera2Client> client): +CallbackProcessor::CallbackProcessor(sp<Camera2Client> client): Thread(false), mClient(client), + mDevice(client->getCameraDevice()), + mId(client->getCameraId()), mCallbackAvailable(false), mCallbackStreamId(NO_STREAM) { } @@ -56,9 +58,11 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { Mutex::Autolock l(mInputMutex); - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return OK; - sp<CameraDeviceBase> device = client->getCameraDevice(); + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } if (mCallbackConsumer == 0) { // Create CPU buffer queue endpoint @@ -76,7 +80,7 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { ¤tWidth, ¤tHeight, ¤tFormat); if (res != OK) { ALOGE("%s: Camera %d: Error querying callback output stream info: " - "%s (%d)", __FUNCTION__, client->getCameraId(), + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -87,11 +91,11 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { // assuming that all existing use of old callback stream is // completed. ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed", - __FUNCTION__, client->getCameraId(), mCallbackStreamId); + __FUNCTION__, mId, mCallbackStreamId); res = device->deleteStream(mCallbackStreamId); if (res != OK) { ALOGE("%s: Camera %d: Unable to delete old output stream " - "for callbacks: %s (%d)", __FUNCTION__, client->getCameraId(), + "for callbacks: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -108,7 +112,7 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { params.previewFormat, 0, &mCallbackStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for callbacks: " - "%s (%d)", __FUNCTION__, client->getCameraId(), + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -119,15 +123,24 @@ status_t CallbackProcessor::updateStream(const Parameters ¶ms) { status_t CallbackProcessor::deleteStream() { ATRACE_CALL(); + sp<CameraDeviceBase> device; - Mutex::Autolock l(mInputMutex); + { + Mutex::Autolock l(mInputMutex); - if (mCallbackStreamId != NO_STREAM) { - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return OK; - sp<CameraDeviceBase> device = client->getCameraDevice(); + if (mCallbackStreamId == NO_STREAM) { + return OK; + } + device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } + } + device->deleteStream(mCallbackStreamId); - device->deleteStream(mCallbackStreamId); + { + Mutex::Autolock l(mInputMutex); mCallbackHeap.clear(); mCallbackWindow.clear(); @@ -161,13 +174,32 @@ bool CallbackProcessor::threadLoop() { do { sp<Camera2Client> client = mClient.promote(); - if (client == 0) return false; - res = processNewCallback(client); + if (client == 0) { + res = discardNewCallback(); + } else { + res = processNewCallback(client); + } } while (res == OK); return true; } +status_t CallbackProcessor::discardNewCallback() { + ATRACE_CALL(); + status_t res; + CpuConsumer::LockedBuffer imgBuffer; + res = mCallbackConsumer->lockNextBuffer(&imgBuffer); + if (res != OK) { + if (res != BAD_VALUE) { + ALOGE("%s: Camera %d: Error receiving next callback buffer: " + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); + } + return res; + } + mCallbackConsumer->unlockBuffer(imgBuffer); + return OK; +} + status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) { ATRACE_CALL(); status_t res; @@ -181,12 +213,12 @@ status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) { if (res != OK) { if (res != BAD_VALUE) { ALOGE("%s: Camera %d: Error receiving next callback buffer: " - "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); } return res; } ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__, - client->getCameraId()); + mId); { SharedParameters::Lock l(client->getParameters()); @@ -195,7 +227,7 @@ status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) { && l.mParameters.state != Parameters::RECORD && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) { ALOGV("%s: Camera %d: No longer streaming", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, mId); mCallbackConsumer->unlockBuffer(imgBuffer); return OK; } @@ -216,7 +248,7 @@ status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) { if (imgBuffer.format != l.mParameters.previewFormat) { ALOGE("%s: Camera %d: Unexpected format for callback: " - "%x, expected %x", __FUNCTION__, client->getCameraId(), + "%x, expected %x", __FUNCTION__, mId, imgBuffer.format, l.mParameters.previewFormat); mCallbackConsumer->unlockBuffer(imgBuffer); return INVALID_OPERATION; @@ -241,7 +273,7 @@ status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) { "Camera2Client::CallbackHeap"); if (mCallbackHeap->mHeap->getSize() == 0) { ALOGE("%s: Camera %d: Unable to allocate memory for callbacks", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, mId); mCallbackConsumer->unlockBuffer(imgBuffer); return INVALID_OPERATION; } @@ -252,7 +284,7 @@ status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) { if (mCallbackHeapFree == 0) { ALOGE("%s: Camera %d: No free callback buffers, dropping frame", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, mId); mCallbackConsumer->unlockBuffer(imgBuffer); return OK; } @@ -282,7 +314,7 @@ status_t CallbackProcessor::processNewCallback(sp<Camera2Client> &client) { l(client->mSharedCameraCallbacks); if (l.mRemoteCallback != 0) { ALOGV("%s: Camera %d: Invoking client data callback", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, mId); l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mCallbackHeap->mBuffers[heapIdx], NULL); } diff --git a/services/camera/libcameraservice/camera2/CallbackProcessor.h b/services/camera/libcameraservice/camera2/CallbackProcessor.h index e68bb75..1c40a03 100644 --- a/services/camera/libcameraservice/camera2/CallbackProcessor.h +++ b/services/camera/libcameraservice/camera2/CallbackProcessor.h @@ -30,6 +30,7 @@ namespace android { class Camera2Client; +class CameraDeviceBase; namespace camera2 { @@ -39,7 +40,7 @@ namespace camera2 { class CallbackProcessor: public Thread, public CpuConsumer::FrameAvailableListener { public: - CallbackProcessor(wp<Camera2Client> client); + CallbackProcessor(sp<Camera2Client> client); ~CallbackProcessor(); void onFrameAvailable(); @@ -52,6 +53,8 @@ class CallbackProcessor: private: static const nsecs_t kWaitDuration = 10000000; // 10 ms wp<Camera2Client> mClient; + wp<CameraDeviceBase> mDevice; + int mId; mutable Mutex mInputMutex; bool mCallbackAvailable; @@ -72,7 +75,8 @@ class CallbackProcessor: virtual bool threadLoop(); status_t processNewCallback(sp<Camera2Client> &client); - + // Used when shutting down + status_t discardNewCallback(); }; diff --git a/services/camera/libcameraservice/camera2/JpegProcessor.cpp b/services/camera/libcameraservice/camera2/JpegProcessor.cpp index 286fac4..01d7f9c 100644 --- a/services/camera/libcameraservice/camera2/JpegProcessor.cpp +++ b/services/camera/libcameraservice/camera2/JpegProcessor.cpp @@ -35,11 +35,12 @@ namespace android { namespace camera2 { JpegProcessor::JpegProcessor( - wp<Camera2Client> client, + sp<Camera2Client> client, wp<CaptureSequencer> sequencer): Thread(false), - mClient(client), + mDevice(client->getCameraDevice()), mSequencer(sequencer), + mId(client->getCameraId()), mCaptureAvailable(false), mCaptureStreamId(NO_STREAM) { } @@ -64,16 +65,18 @@ status_t JpegProcessor::updateStream(const Parameters ¶ms) { Mutex::Autolock l(mInputMutex); - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return OK; - sp<CameraDeviceBase> device = client->getCameraDevice(); + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } // Find out buffer size for JPEG camera_metadata_ro_entry_t maxJpegSize = params.staticInfo(ANDROID_JPEG_MAX_SIZE); if (maxJpegSize.count == 0) { ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, mId); return INVALID_OPERATION; } @@ -89,7 +92,7 @@ status_t JpegProcessor::updateStream(const Parameters ¶ms) { "Camera2Client::CaptureHeap"); if (mCaptureHeap->getSize() == 0) { ALOGE("%s: Camera %d: Unable to allocate memory for capture", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, mId); return NO_MEMORY; } } @@ -102,18 +105,18 @@ status_t JpegProcessor::updateStream(const Parameters ¶ms) { if (res != OK) { ALOGE("%s: Camera %d: Error querying capture output stream info: " "%s (%d)", __FUNCTION__, - client->getCameraId(), strerror(-res), res); + mId, strerror(-res), res); return res; } if (currentWidth != (uint32_t)params.pictureWidth || currentHeight != (uint32_t)params.pictureHeight) { ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed", - __FUNCTION__, client->getCameraId(), mCaptureStreamId); + __FUNCTION__, mId, mCaptureStreamId); res = device->deleteStream(mCaptureStreamId); if (res != OK) { ALOGE("%s: Camera %d: Unable to delete old output stream " "for capture: %s (%d)", __FUNCTION__, - client->getCameraId(), strerror(-res), res); + mId, strerror(-res), res); return res; } mCaptureStreamId = NO_STREAM; @@ -128,7 +131,7 @@ status_t JpegProcessor::updateStream(const Parameters ¶ms) { &mCaptureStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for capture: " - "%s (%d)", __FUNCTION__, client->getCameraId(), + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -143,9 +146,11 @@ status_t JpegProcessor::deleteStream() { Mutex::Autolock l(mInputMutex); if (mCaptureStreamId != NO_STREAM) { - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return OK; - sp<CameraDeviceBase> device = client->getCameraDevice(); + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } device->deleteStream(mCaptureStreamId); @@ -180,15 +185,13 @@ bool JpegProcessor::threadLoop() { } do { - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return false; - res = processNewCapture(client); + res = processNewCapture(); } while (res == OK); return true; } -status_t JpegProcessor::processNewCapture(sp<Camera2Client> &client) { +status_t JpegProcessor::processNewCapture() { ATRACE_CALL(); status_t res; sp<Camera2Heap> captureHeap; @@ -200,17 +203,17 @@ status_t JpegProcessor::processNewCapture(sp<Camera2Client> &client) { if (res != BAD_VALUE) { ALOGE("%s: Camera %d: Error receiving still image buffer: " "%s (%d)", __FUNCTION__, - client->getCameraId(), strerror(-res), res); + mId, strerror(-res), res); } return res; } ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, - client->getCameraId()); + mId); if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) { ALOGE("%s: Camera %d: Unexpected format for still image: " - "%x, expected %x", __FUNCTION__, client->getCameraId(), + "%x, expected %x", __FUNCTION__, mId, imgBuffer.format, HAL_PIXEL_FORMAT_BLOB); mCaptureConsumer->unlockBuffer(imgBuffer); diff --git a/services/camera/libcameraservice/camera2/JpegProcessor.h b/services/camera/libcameraservice/camera2/JpegProcessor.h index 74f4738..a38611c 100644 --- a/services/camera/libcameraservice/camera2/JpegProcessor.h +++ b/services/camera/libcameraservice/camera2/JpegProcessor.h @@ -29,6 +29,7 @@ namespace android { class Camera2Client; +class CameraDeviceBase; class MemoryHeapBase; namespace camera2 { @@ -41,7 +42,7 @@ class CaptureSequencer; class JpegProcessor: public Thread, public CpuConsumer::FrameAvailableListener { public: - JpegProcessor(wp<Camera2Client> client, wp<CaptureSequencer> sequencer); + JpegProcessor(sp<Camera2Client> client, wp<CaptureSequencer> sequencer); ~JpegProcessor(); // CpuConsumer listener implementation @@ -54,8 +55,9 @@ class JpegProcessor: void dump(int fd, const Vector<String16>& args) const; private: static const nsecs_t kWaitDuration = 10000000; // 10 ms - wp<Camera2Client> mClient; + wp<CameraDeviceBase> mDevice; wp<CaptureSequencer> mSequencer; + int mId; mutable Mutex mInputMutex; bool mCaptureAvailable; @@ -72,7 +74,7 @@ class JpegProcessor: virtual bool threadLoop(); - status_t processNewCapture(sp<Camera2Client> &client); + status_t processNewCapture(); size_t findJpegSize(uint8_t* jpegBuffer, size_t maxSize); }; diff --git a/services/camera/libcameraservice/camera2/StreamingProcessor.cpp b/services/camera/libcameraservice/camera2/StreamingProcessor.cpp index fbc5b93..c36cf87 100644 --- a/services/camera/libcameraservice/camera2/StreamingProcessor.cpp +++ b/services/camera/libcameraservice/camera2/StreamingProcessor.cpp @@ -31,8 +31,10 @@ namespace android { namespace camera2 { -StreamingProcessor::StreamingProcessor(wp<Camera2Client> client): +StreamingProcessor::StreamingProcessor(sp<Camera2Client> client): mClient(client), + mDevice(client->getCameraDevice()), + mId(client->getCameraId()), mActiveRequest(NONE), mPreviewRequestId(Camera2Client::kPreviewRequestIdStart), mPreviewStreamId(NO_STREAM), @@ -40,7 +42,6 @@ StreamingProcessor::StreamingProcessor(wp<Camera2Client> client): mRecordingStreamId(NO_STREAM), mRecordingHeapCount(kDefaultRecordingHeapCount) { - } StreamingProcessor::~StreamingProcessor() { @@ -70,16 +71,19 @@ bool StreamingProcessor::haveValidPreviewWindow() const { status_t StreamingProcessor::updatePreviewRequest(const Parameters ¶ms) { ATRACE_CALL(); status_t res; - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return INVALID_OPERATION; + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } Mutex::Autolock m(mMutex); if (mPreviewRequest.entryCount() == 0) { - res = client->getCameraDevice()->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, + res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, &mPreviewRequest); if (res != OK) { ALOGE("%s: Camera %d: Unable to create default preview request: " - "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } } @@ -87,7 +91,7 @@ status_t StreamingProcessor::updatePreviewRequest(const Parameters ¶ms) { res = params.updateRequest(&mPreviewRequest); if (res != OK) { ALOGE("%s: Camera %d: Unable to update common entries of preview " - "request: %s (%d)", __FUNCTION__, client->getCameraId(), + "request: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -96,7 +100,7 @@ status_t StreamingProcessor::updatePreviewRequest(const Parameters ¶ms) { &mPreviewRequestId, 1); if (res != OK) { ALOGE("%s: Camera %d: Unable to update request id for preview: %s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); + __FUNCTION__, mId, strerror(-res), res); return res; } @@ -108,9 +112,11 @@ status_t StreamingProcessor::updatePreviewStream(const Parameters ¶ms) { Mutex::Autolock m(mMutex); status_t res; - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return INVALID_OPERATION; - sp<CameraDeviceBase> device = client->getCameraDevice(); + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } if (mPreviewStreamId != NO_STREAM) { // Check if stream parameters have to change @@ -119,24 +125,24 @@ status_t StreamingProcessor::updatePreviewStream(const Parameters ¶ms) { ¤tWidth, ¤tHeight, 0); if (res != OK) { ALOGE("%s: Camera %d: Error querying preview stream info: " - "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } if (currentWidth != (uint32_t)params.previewWidth || currentHeight != (uint32_t)params.previewHeight) { ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d", - __FUNCTION__, client->getCameraId(), currentWidth, currentHeight, + __FUNCTION__, mId, currentWidth, currentHeight, params.previewWidth, params.previewHeight); res = device->waitUntilDrained(); if (res != OK) { ALOGE("%s: Camera %d: Error waiting for preview to drain: " - "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } res = device->deleteStream(mPreviewStreamId); if (res != OK) { ALOGE("%s: Camera %d: Unable to delete old output stream " - "for preview: %s (%d)", __FUNCTION__, client->getCameraId(), + "for preview: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -151,7 +157,7 @@ status_t StreamingProcessor::updatePreviewStream(const Parameters ¶ms) { &mPreviewStreamId); if (res != OK) { ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); + __FUNCTION__, mId, strerror(-res), res); return res; } } @@ -160,7 +166,7 @@ status_t StreamingProcessor::updatePreviewStream(const Parameters ¶ms) { params.previewTransform); if (res != OK) { ALOGE("%s: Camera %d: Unable to set preview stream transform: " - "%s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -174,12 +180,14 @@ status_t StreamingProcessor::deletePreviewStream() { Mutex::Autolock m(mMutex); if (mPreviewStreamId != NO_STREAM) { - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return INVALID_OPERATION; - sp<CameraDeviceBase> device = client->getCameraDevice(); + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } ALOGV("%s: for cameraId %d on streamId %d", - __FUNCTION__, client->getCameraId(), mPreviewStreamId); + __FUNCTION__, mId, mPreviewStreamId); res = device->waitUntilDrained(); if (res != OK) { @@ -206,11 +214,9 @@ int StreamingProcessor::getPreviewStreamId() const { status_t StreamingProcessor::setRecordingBufferCount(size_t count) { ATRACE_CALL(); // 32 is the current upper limit on the video buffer count for BufferQueue - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return INVALID_OPERATION; if (count > 32) { ALOGE("%s: Camera %d: Error setting %d as video buffer count value", - __FUNCTION__, client->getCameraId(), count); + __FUNCTION__, mId, count); return BAD_VALUE; } @@ -233,15 +239,18 @@ status_t StreamingProcessor::updateRecordingRequest(const Parameters ¶ms) { status_t res; Mutex::Autolock m(mMutex); - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return INVALID_OPERATION; + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } if (mRecordingRequest.entryCount() == 0) { - res = client->getCameraDevice()->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD, + res = device->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD, &mRecordingRequest); if (res != OK) { ALOGE("%s: Camera %d: Unable to create default recording request:" - " %s (%d)", __FUNCTION__, client->getCameraId(), strerror(-res), res); + " %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } } @@ -249,7 +258,7 @@ status_t StreamingProcessor::updateRecordingRequest(const Parameters ¶ms) { res = params.updateRequest(&mRecordingRequest); if (res != OK) { ALOGE("%s: Camera %d: Unable to update common entries of recording " - "request: %s (%d)", __FUNCTION__, client->getCameraId(), + "request: %s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -258,7 +267,7 @@ status_t StreamingProcessor::updateRecordingRequest(const Parameters ¶ms) { &mRecordingRequestId, 1); if (res != OK) { ALOGE("%s: Camera %d: Unable to update request id for request: %s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); + __FUNCTION__, mId, strerror(-res), res); return res; } @@ -270,9 +279,11 @@ status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) { status_t res; Mutex::Autolock m(mMutex); - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return INVALID_OPERATION; - sp<CameraDeviceBase> device = client->getCameraDevice(); + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } if (mRecordingConsumer == 0) { // Create CPU buffer queue endpoint. We need one more buffer here so that we can @@ -296,7 +307,7 @@ status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) { ¤tWidth, ¤tHeight, 0); if (res != OK) { ALOGE("%s: Camera %d: Error querying recording output stream info: " - "%s (%d)", __FUNCTION__, client->getCameraId(), + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -307,7 +318,7 @@ status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) { if (res != OK) { ALOGE("%s: Camera %d: Unable to delete old output stream " "for recording: %s (%d)", __FUNCTION__, - client->getCameraId(), strerror(-res), res); + mId, strerror(-res), res); return res; } mRecordingStreamId = NO_STREAM; @@ -321,7 +332,7 @@ status_t StreamingProcessor::updateRecordingStream(const Parameters ¶ms) { CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for recording: " - "%s (%d)", __FUNCTION__, client->getCameraId(), + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -337,9 +348,11 @@ status_t StreamingProcessor::deleteRecordingStream() { Mutex::Autolock m(mMutex); if (mRecordingStreamId != NO_STREAM) { - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return INVALID_OPERATION; - sp<CameraDeviceBase> device = client->getCameraDevice(); + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } res = device->waitUntilDrained(); if (res != OK) { @@ -369,10 +382,13 @@ status_t StreamingProcessor::startStream(StreamType type, if (type == NONE) return INVALID_OPERATION; - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return INVALID_OPERATION; + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } - ALOGV("%s: Camera %d: type = %d", __FUNCTION__, client->getCameraId(), type); + ALOGV("%s: Camera %d: type = %d", __FUNCTION__, mId, type); Mutex::Autolock m(mMutex); @@ -384,22 +400,22 @@ status_t StreamingProcessor::startStream(StreamType type, outputStreams); if (res != OK) { ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); + __FUNCTION__, mId, strerror(-res), res); return res; } res = request.sort(); if (res != OK) { ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); + __FUNCTION__, mId, strerror(-res), res); return res; } - res = client->getCameraDevice()->setStreamingRequest(request); + res = device->setStreamingRequest(request); if (res != OK) { ALOGE("%s: Camera %d: Unable to set preview request to start preview: " "%s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); + __FUNCTION__, mId, strerror(-res), res); return res; } mActiveRequest = type; @@ -413,16 +429,19 @@ status_t StreamingProcessor::stopStream() { Mutex::Autolock m(mMutex); - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return INVALID_OPERATION; - sp<CameraDeviceBase> device = client->getCameraDevice(); + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } res = device->clearStreamingRequest(); if (res != OK) { ALOGE("%s: Camera %d: Can't clear stream request: %s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); + __FUNCTION__, mId, strerror(-res), res); return res; } + mActiveRequest = NONE; return OK; @@ -466,7 +485,18 @@ void StreamingProcessor::onFrameAvailable() { nsecs_t timestamp; sp<Camera2Client> client = mClient.promote(); - if (client == 0) return; + if (client == 0) { + // Discard frames during shutdown + BufferItemConsumer::BufferItem imgBuffer; + res = mRecordingConsumer->acquireBuffer(&imgBuffer); + if (res != OK) { + ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)", + __FUNCTION__, mId, strerror(-res), res); + return; + } + mRecordingConsumer->releaseBuffer(imgBuffer); + return; + } { /* acquire SharedParameters before mMutex so we don't dead lock @@ -477,7 +507,7 @@ void StreamingProcessor::onFrameAvailable() { res = mRecordingConsumer->acquireBuffer(&imgBuffer); if (res != OK) { ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); + __FUNCTION__, mId, strerror(-res), res); return; } timestamp = imgBuffer.mTimestamp; @@ -490,7 +520,7 @@ void StreamingProcessor::onFrameAvailable() { l.mParameters.state != Parameters::VIDEO_SNAPSHOT) { ALOGV("%s: Camera %d: Discarding recording image buffers " "received after recording done", __FUNCTION__, - client->getCameraId()); + mId); mRecordingConsumer->releaseBuffer(imgBuffer); return; } @@ -498,14 +528,14 @@ void StreamingProcessor::onFrameAvailable() { if (mRecordingHeap == 0) { const size_t bufferSize = 4 + sizeof(buffer_handle_t); ALOGV("%s: Camera %d: Creating recording heap with %d buffers of " - "size %d bytes", __FUNCTION__, client->getCameraId(), + "size %d bytes", __FUNCTION__, mId, mRecordingHeapCount, bufferSize); mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount, "Camera2Client::RecordingHeap"); if (mRecordingHeap->mHeap->getSize() == 0) { ALOGE("%s: Camera %d: Unable to allocate memory for recording", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, mId); mRecordingConsumer->releaseBuffer(imgBuffer); return; } @@ -513,7 +543,7 @@ void StreamingProcessor::onFrameAvailable() { if (mRecordingBuffers[i].mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT) { ALOGE("%s: Camera %d: Non-empty recording buffers list!", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, mId); } } mRecordingBuffers.clear(); @@ -526,7 +556,7 @@ void StreamingProcessor::onFrameAvailable() { if ( mRecordingHeapFree == 0) { ALOGE("%s: Camera %d: No free recording buffers, dropping frame", - __FUNCTION__, client->getCameraId()); + __FUNCTION__, mId); mRecordingConsumer->releaseBuffer(imgBuffer); return; } @@ -536,7 +566,7 @@ void StreamingProcessor::onFrameAvailable() { mRecordingHeapFree--; ALOGV("%s: Camera %d: Timestamp %lld", - __FUNCTION__, client->getCameraId(), timestamp); + __FUNCTION__, mId, timestamp); ssize_t offset; size_t size; @@ -549,7 +579,7 @@ void StreamingProcessor::onFrameAvailable() { *((uint32_t*)data) = type; *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle; ALOGV("%s: Camera %d: Sending out buffer_handle_t %p", - __FUNCTION__, client->getCameraId(), + __FUNCTION__, mId, imgBuffer.mGraphicBuffer->handle); mRecordingBuffers.replaceAt(imgBuffer, heapIdx); recordingHeap = mRecordingHeap; @@ -568,9 +598,6 @@ void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) { ATRACE_CALL(); status_t res; - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return; - Mutex::Autolock m(mMutex); // Make sure this is for the current heap ssize_t offset; @@ -578,7 +605,7 @@ void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) { sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) { ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release " - "(got %x, expected %x)", __FUNCTION__, client->getCameraId(), + "(got %x, expected %x)", __FUNCTION__, mId, heap->getHeapID(), mRecordingHeap->mHeap->getHeapID()); return; } @@ -586,7 +613,7 @@ void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) { uint32_t type = *(uint32_t*)data; if (type != kMetadataBufferTypeGrallocSource) { ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)", - __FUNCTION__, client->getCameraId(), type, + __FUNCTION__, mId, type, kMetadataBufferTypeGrallocSource); return; } @@ -606,19 +633,19 @@ void StreamingProcessor::releaseRecordingFrame(const sp<IMemory>& mem) { } if (itemIndex == mRecordingBuffers.size()) { ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of " - "outstanding buffers", __FUNCTION__, client->getCameraId(), + "outstanding buffers", __FUNCTION__, mId, imgHandle); return; } ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, - client->getCameraId(), imgHandle); + mId, imgHandle); res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]); if (res != OK) { ALOGE("%s: Camera %d: Unable to free recording frame " "(buffer_handle_t: %p): %s (%d)", __FUNCTION__, - client->getCameraId(), imgHandle, strerror(-res), res); + mId, imgHandle, strerror(-res), res); return; } mRecordingBuffers.replaceAt(itemIndex); diff --git a/services/camera/libcameraservice/camera2/StreamingProcessor.h b/services/camera/libcameraservice/camera2/StreamingProcessor.h index e5732ad..643114e 100644 --- a/services/camera/libcameraservice/camera2/StreamingProcessor.h +++ b/services/camera/libcameraservice/camera2/StreamingProcessor.h @@ -27,6 +27,7 @@ namespace android { class Camera2Client; +class CameraDeviceBase; class IMemory; namespace camera2 { @@ -38,7 +39,7 @@ class Camera2Heap; */ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { public: - StreamingProcessor(wp<Camera2Client> client); + StreamingProcessor(sp<Camera2Client> client); ~StreamingProcessor(); status_t setPreviewWindow(sp<ANativeWindow> window); @@ -86,6 +87,8 @@ class StreamingProcessor: public BufferItemConsumer::FrameAvailableListener { }; wp<Camera2Client> mClient; + wp<CameraDeviceBase> mDevice; + int mId; StreamType mActiveRequest; diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.cpp b/services/camera/libcameraservice/camera2/ZslProcessor.cpp index 769d9bd..2c12fb0 100644 --- a/services/camera/libcameraservice/camera2/ZslProcessor.cpp +++ b/services/camera/libcameraservice/camera2/ZslProcessor.cpp @@ -38,12 +38,14 @@ namespace android { namespace camera2 { ZslProcessor::ZslProcessor( - wp<Camera2Client> client, + sp<Camera2Client> client, wp<CaptureSequencer> sequencer): Thread(false), mState(RUNNING), mClient(client), + mDevice(client->getCameraDevice()), mSequencer(sequencer), + mId(client->getCameraId()), mZslBufferAvailable(false), mZslStreamId(NO_STREAM), mZslReprocessStreamId(NO_STREAM), @@ -69,7 +71,8 @@ void ZslProcessor::onFrameAvailable() { } } -void ZslProcessor::onFrameAvailable(int32_t /*frameId*/, const CameraMetadata &frame) { +void ZslProcessor::onFrameAvailable(int32_t /*frameId*/, + const CameraMetadata &frame) { Mutex::Autolock l(mInputMutex); camera_metadata_ro_entry_t entry; entry = frame.find(ANDROID_SENSOR_TIMESTAMP); @@ -113,8 +116,15 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { Mutex::Autolock l(mInputMutex); sp<Camera2Client> client = mClient.promote(); - if (client == 0) return OK; - sp<CameraDeviceBase> device = client->getCameraDevice(); + if (client == 0) { + ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } if (mZslConsumer == 0) { // Create CPU buffer queue endpoint @@ -136,7 +146,7 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { if (res != OK) { ALOGE("%s: Camera %d: Error querying capture output stream info: " "%s (%d)", __FUNCTION__, - client->getCameraId(), strerror(-res), res); + mId, strerror(-res), res); return res; } if (currentWidth != (uint32_t)params.fastInfo.arrayWidth || @@ -145,16 +155,16 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { if (res != OK) { ALOGE("%s: Camera %d: Unable to delete old reprocess stream " "for ZSL: %s (%d)", __FUNCTION__, - client->getCameraId(), strerror(-res), res); + mId, strerror(-res), res); return res; } ALOGV("%s: Camera %d: Deleting stream %d since the buffer dimensions changed", - __FUNCTION__, client->getCameraId(), mZslStreamId); + __FUNCTION__, mId, mZslStreamId); res = device->deleteStream(mZslStreamId); if (res != OK) { ALOGE("%s: Camera %d: Unable to delete old output stream " "for ZSL: %s (%d)", __FUNCTION__, - client->getCameraId(), strerror(-res), res); + mId, strerror(-res), res); return res; } mZslStreamId = NO_STREAM; @@ -173,7 +183,7 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { &mZslStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create output stream for ZSL: " - "%s (%d)", __FUNCTION__, client->getCameraId(), + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -181,7 +191,7 @@ status_t ZslProcessor::updateStream(const Parameters ¶ms) { &mZslReprocessStreamId); if (res != OK) { ALOGE("%s: Camera %d: Can't create reprocess stream for ZSL: " - "%s (%d)", __FUNCTION__, client->getCameraId(), + "%s (%d)", __FUNCTION__, mId, strerror(-res), res); return res; } @@ -200,14 +210,18 @@ status_t ZslProcessor::deleteStream() { Mutex::Autolock l(mInputMutex); if (mZslStreamId != NO_STREAM) { - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return OK; - sp<CameraDeviceBase> device = client->getCameraDevice(); + sp<CameraDeviceBase> device = mDevice.promote(); + if (device == 0) { + ALOGE("%s: Camera %d: Device does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } + + clearZslQueueLocked(); res = device->deleteReprocessStream(mZslReprocessStreamId); if (res != OK) { ALOGE("%s: Camera %d: Cannot delete ZSL reprocessing stream %d: " - "%s (%d)", __FUNCTION__, client->getCameraId(), + "%s (%d)", __FUNCTION__, mId, mZslReprocessStreamId, strerror(-res), res); return res; } @@ -216,7 +230,7 @@ status_t ZslProcessor::deleteStream() { res = device->deleteStream(mZslStreamId); if (res != OK) { ALOGE("%s: Camera %d: Cannot delete ZSL output stream %d: " - "%s (%d)", __FUNCTION__, client->getCameraId(), + "%s (%d)", __FUNCTION__, mId, mZslStreamId, strerror(-res), res); return res; } @@ -246,7 +260,10 @@ status_t ZslProcessor::pushToReprocess(int32_t requestId) { status_t res; sp<Camera2Client> client = mClient.promote(); - if (client == 0) return INVALID_OPERATION; + if (client == 0) { + ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId); + return INVALID_OPERATION; + } IF_ALOGV() { dumpZslQueue(-1); @@ -309,7 +326,7 @@ status_t ZslProcessor::pushToReprocess(int32_t requestId) { if (res != OK) { ALOGE("%s: Camera %d: Unable to stop preview for ZSL capture: " "%s (%d)", - __FUNCTION__, client->getCameraId(), strerror(-res), res); + __FUNCTION__, mId, strerror(-res), res); return INVALID_OPERATION; } // TODO: have push-and-clear be atomic @@ -328,7 +345,7 @@ status_t ZslProcessor::pushToReprocess(int32_t requestId) { if (res != OK) { ALOGE("%s: Camera %d: Unable to update JPEG entries of ZSL " "capture request: %s (%d)", __FUNCTION__, - client->getCameraId(), + mId, strerror(-res), res); return res; } @@ -397,26 +414,29 @@ bool ZslProcessor::threadLoop() { } do { - sp<Camera2Client> client = mClient.promote(); - if (client == 0) return false; - res = processNewZslBuffer(client); + res = processNewZslBuffer(); } while (res == OK); return true; } -status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) { +status_t ZslProcessor::processNewZslBuffer() { ATRACE_CALL(); status_t res; - + sp<BufferItemConsumer> zslConsumer; + { + Mutex::Autolock l(mInputMutex); + if (mZslConsumer == 0) return OK; + zslConsumer = mZslConsumer; + } ALOGVV("Trying to get next buffer"); BufferItemConsumer::BufferItem item; - res = mZslConsumer->acquireBuffer(&item); + res = zslConsumer->acquireBuffer(&item); if (res != OK) { if (res != BufferItemConsumer::NO_BUFFER_AVAILABLE) { ALOGE("%s: Camera %d: Error receiving ZSL image buffer: " "%s (%d)", __FUNCTION__, - client->getCameraId(), strerror(-res), res); + mId, strerror(-res), res); } else { ALOGVV(" No buffer"); } @@ -427,7 +447,7 @@ status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) { if (mState == LOCKED) { ALOGVV("In capture, discarding new ZSL buffers"); - mZslConsumer->releaseBuffer(item); + zslConsumer->releaseBuffer(item); return OK; } @@ -435,7 +455,7 @@ status_t ZslProcessor::processNewZslBuffer(sp<Camera2Client> &client) { if ( (mZslQueueHead + 1) % kZslBufferDepth == mZslQueueTail) { ALOGVV("Releasing oldest buffer"); - mZslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer); + zslConsumer->releaseBuffer(mZslQueue[mZslQueueTail].buffer); mZslQueue.replaceAt(mZslQueueTail); mZslQueueTail = (mZslQueueTail + 1) % kZslBufferDepth; } diff --git a/services/camera/libcameraservice/camera2/ZslProcessor.h b/services/camera/libcameraservice/camera2/ZslProcessor.h index b2cf5b1..ee3bcd6 100644 --- a/services/camera/libcameraservice/camera2/ZslProcessor.h +++ b/services/camera/libcameraservice/camera2/ZslProcessor.h @@ -46,7 +46,7 @@ class ZslProcessor: virtual public FrameProcessor::FilteredListener, virtual public CameraDeviceBase::BufferReleasedListener { public: - ZslProcessor(wp<Camera2Client> client, wp<CaptureSequencer> sequencer); + ZslProcessor(sp<Camera2Client> client, wp<CaptureSequencer> sequencer); ~ZslProcessor(); // From mZslConsumer @@ -74,7 +74,9 @@ class ZslProcessor: } mState; wp<Camera2Client> mClient; + wp<CameraDeviceBase> mDevice; wp<CaptureSequencer> mSequencer; + int mId; mutable Mutex mInputMutex; bool mZslBufferAvailable; @@ -109,7 +111,7 @@ class ZslProcessor: virtual bool threadLoop(); - status_t processNewZslBuffer(sp<Camera2Client> &client); + status_t processNewZslBuffer(); // Match up entries from frame list to buffers in ZSL queue void findMatchesLocked(); |