summaryrefslogtreecommitdiffstats
path: root/camera/ProCamera.cpp
diff options
context:
space:
mode:
authorIgor Murashkin <iam@google.com>2013-02-21 14:45:03 -0800
committerIgor Murashkin <iam@google.com>2013-02-22 10:50:15 -0800
commita140a6efea1db7837984b3578755cfa4eaa8d92d (patch)
treed7ce2fa02ae78e0ca1fedf453290787ce5cd2be3 /camera/ProCamera.cpp
parentdcb07d51e307019731147751946774f45321edfb (diff)
downloadframeworks_av-a140a6efea1db7837984b3578755cfa4eaa8d92d.zip
frameworks_av-a140a6efea1db7837984b3578755cfa4eaa8d92d.tar.gz
frameworks_av-a140a6efea1db7837984b3578755cfa4eaa8d92d.tar.bz2
ProCamera: add waitForFrameBuffer/waitForFrameResult blocking calls
Change-Id: I851d41aeecaa15245d5b9d622132e8706d6e292c
Diffstat (limited to 'camera/ProCamera.cpp')
-rw-r--r--camera/ProCamera.cpp110
1 files changed, 97 insertions, 13 deletions
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 @@ sp<ProCamera> ProCamera::connect(int cameraId)
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 @@ void ProCamera::onResultReceived(int32_t frameId, camera_metadata* result) {
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::createStream(int width, int height, int format,
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 @@ status_t ProCamera::createStreamCpu(int width, int height, int format,
cc->setFrameAvailableListener(frameAvailableListener);
+ *cpuConsumer = cc;
+
return s;
}
@@ -399,26 +418,91 @@ void ProCamera::onFrameAvailable(int streamId) {
ALOGV("%s: streamId = %d", __FUNCTION__, streamId);
sp<ProCameraListener> listener = mListener;
- if (listener.get() != NULL) {
- StreamInfo& stream = getStreamInfo(streamId);
+ StreamInfo& stream = getStreamInfo(streamId);
- CpuConsumer::LockedBuffer buf;
+ 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.get() != NULL) {
+ if (listener->useOnFrameAvailable()) {
+ listener->onFrameAvailable(streamId, stream.cpuConsumer);
return;
}
+ }
+
+ // Unblock waitForFrame(id) callers
+ {
+ Mutex::Autolock al(mWaitMutex);
+ getStreamInfo(streamId).frameReady = true;
+ mWaitCondition.broadcast();
+ }
+}
+
+status_t ProCamera::waitForFrameBuffer(int streamId) {
+ status_t stat = BAD_VALUE;
+ Mutex::Autolock al(mWaitMutex);
- listener->onBufferReceived(streamId, buf);
- stat = stream.cpuConsumer->unlockBuffer(buf);
+ StreamInfo& si = getStreamInfo(streamId);
- if (stat != OK) {
- ALOGE("%s: Failed to unlock buffer, error code = %d", __FUNCTION__,
- stat);
+ 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) {