summaryrefslogtreecommitdiffstats
path: root/services/camera
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2013-04-27 00:10:38 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-04-27 00:10:38 +0000
commit7081533bea68a71014d708776d0c384c45321ec5 (patch)
treeb353c2b24099757bec6d4ff34f8046ca0b6352d4 /services/camera
parentc34e097efc5eeefe977972b08a42509e8aa3ccc5 (diff)
parent02f8457cf788e09e4f0c302dda453f13293009e7 (diff)
downloadframeworks_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
Diffstat (limited to 'services/camera')
-rw-r--r--services/camera/libcameraservice/Camera2Client.cpp20
-rw-r--r--services/camera/libcameraservice/Camera2Device.cpp3
-rw-r--r--services/camera/libcameraservice/CameraService.cpp4
-rw-r--r--services/camera/libcameraservice/camera2/CallbackProcessor.cpp78
-rw-r--r--services/camera/libcameraservice/camera2/CallbackProcessor.h8
-rw-r--r--services/camera/libcameraservice/camera2/JpegProcessor.cpp45
-rw-r--r--services/camera/libcameraservice/camera2/JpegProcessor.h8
-rw-r--r--services/camera/libcameraservice/camera2/StreamingProcessor.cpp161
-rw-r--r--services/camera/libcameraservice/camera2/StreamingProcessor.h5
-rw-r--r--services/camera/libcameraservice/camera2/ZslProcessor.cpp74
-rw-r--r--services/camera/libcameraservice/camera2/ZslProcessor.h6
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 &params) {
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 &params) {
&currentWidth, &currentHeight, &currentFormat);
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 &params) {
// 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 &params) {
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 &params) {
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 &params) {
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 &params) {
"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 &params) {
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 &params) {
&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 &params) {
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 &params) {
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 &params) {
&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 &params) {
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 &params) {
&currentWidth, &currentHeight, 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 &params) {
&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 &params) {
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 &params) {
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 &params) {
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 &params) {
&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 &params) {
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 &params) {
&currentWidth, &currentHeight, 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 &params) {
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 &params) {
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 &params) {
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 &params) {
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 &params) {
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 &params) {
&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 &params) {
&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();