ProCamera: add waitForFrameBuffer/waitForFrameResult blocking calls
Change-Id: I851d41aeecaa15245d5b9d622132e8706d6e292c
diff --git a/camera/ProCamera.cpp b/camera/ProCamera.cpp
index c95c4e0..d4a9556 100644
--- a/camera/ProCamera.cpp
+++ b/camera/ProCamera.cpp
@@ -86,12 +86,13 @@
void ProCamera::disconnect()
{
- ALOGV("disconnect");
+ ALOGV("%s: disconnect", __FUNCTION__);
if (mCamera != 0) {
mCamera->disconnect();
mCamera->asBinder()->unlinkToDeath(this);
mCamera = 0;
}
+ ALOGV("%s: disconnect (done)", __FUNCTION__);
}
ProCamera::ProCamera()
@@ -208,6 +209,19 @@
Mutex::Autolock _l(mLock);
listener = mListener;
}
+
+ CameraMetadata tmp(result);
+
+ // Unblock waitForFrame(id) callers
+ {
+ Mutex::Autolock al(mWaitMutex);
+ mMetadataReady = true;
+ mLatestMetadata = tmp;
+ mWaitCondition.broadcast();
+ }
+
+ result = tmp.release();
+
if (listener != NULL) {
listener->onResultReceived(frameId, result);
} else {
@@ -323,11 +337,14 @@
status_t ProCamera::createStreamCpu(int width, int height, int format,
int heapCount,
/*out*/
+ sp<CpuConsumer>* cpuConsumer,
int* streamId)
{
ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height,
format);
+ *cpuConsumer = NULL;
+
sp <IProCameraUser> c = mCamera;
if (c == 0) return NO_INIT;
@@ -357,6 +374,8 @@
cc->setFrameAvailableListener(frameAvailableListener);
+ *cpuConsumer = cc;
+
return s;
}
@@ -399,26 +418,91 @@
ALOGV("%s: streamId = %d", __FUNCTION__, streamId);
sp<ProCameraListener> listener = mListener;
+ StreamInfo& stream = getStreamInfo(streamId);
+
+ CpuConsumer::LockedBuffer buf;
+
if (listener.get() != NULL) {
- StreamInfo& stream = getStreamInfo(streamId);
-
- CpuConsumer::LockedBuffer buf;
-
- status_t stat = stream.cpuConsumer->lockNextBuffer(&buf);
- if (stat != OK) {
- ALOGE("%s: Failed to lock buffer, error code = %d", __FUNCTION__,
- stat);
+ if (listener->useOnFrameAvailable()) {
+ listener->onFrameAvailable(streamId, stream.cpuConsumer);
return;
}
+ }
- listener->onBufferReceived(streamId, buf);
- stat = stream.cpuConsumer->unlockBuffer(buf);
+ // Unblock waitForFrame(id) callers
+ {
+ Mutex::Autolock al(mWaitMutex);
+ getStreamInfo(streamId).frameReady = true;
+ mWaitCondition.broadcast();
+ }
+}
- if (stat != OK) {
- ALOGE("%s: Failed to unlock buffer, error code = %d", __FUNCTION__,
- stat);
+status_t ProCamera::waitForFrameBuffer(int streamId) {
+ status_t stat = BAD_VALUE;
+ Mutex::Autolock al(mWaitMutex);
+
+ StreamInfo& si = getStreamInfo(streamId);
+
+ if (si.frameReady) {
+ si.frameReady = false;
+ return OK;
+ } else {
+ while (true) {
+ stat = mWaitCondition.waitRelative(mWaitMutex,
+ mWaitTimeout);
+ if (stat != OK) {
+ ALOGE("%s: Error while waiting for frame buffer: %d",
+ __FUNCTION__, stat);
+ return stat;
+ }
+
+ if (si.frameReady) {
+ si.frameReady = false;
+ return OK;
+ }
+ // else it was some other stream that got unblocked
}
}
+
+ return stat;
+}
+
+status_t ProCamera::waitForFrameMetadata() {
+ status_t stat = BAD_VALUE;
+ Mutex::Autolock al(mWaitMutex);
+
+ if (mMetadataReady) {
+ return OK;
+ } else {
+ while (true) {
+ stat = mWaitCondition.waitRelative(mWaitMutex,
+ mWaitTimeout);
+
+ if (stat != OK) {
+ ALOGE("%s: Error while waiting for metadata: %d",
+ __FUNCTION__, stat);
+ return stat;
+ }
+
+ if (mMetadataReady) {
+ mMetadataReady = false;
+ return OK;
+ }
+ // else it was some other stream or metadata
+ }
+ }
+
+ return stat;
+}
+
+CameraMetadata ProCamera::consumeFrameMetadata() {
+ Mutex::Autolock al(mWaitMutex);
+
+ // Destructive: Subsequent calls return empty metadatas
+ CameraMetadata tmp = mLatestMetadata;
+ mLatestMetadata.release();
+
+ return tmp;
}
ProCamera::StreamInfo& ProCamera::getStreamInfo(int streamId) {