summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2013-08-14 11:37:00 -0700
committerEino-Ville Talvala <etalvala@google.com>2013-08-23 14:08:27 -0700
commitabaa51d3ca31f0eda99e1d271e6dc64c877dbf58 (patch)
tree52f4cc1078708f7c0099fded06dcb01daf6ca6bb
parent62c1a46eec047eb5fbc4b90432ec1ce65b76fb75 (diff)
downloadframeworks_av-abaa51d3ca31f0eda99e1d271e6dc64c877dbf58.zip
frameworks_av-abaa51d3ca31f0eda99e1d271e6dc64c877dbf58.tar.gz
frameworks_av-abaa51d3ca31f0eda99e1d271e6dc64c877dbf58.tar.bz2
Camera2: Add flush support
- On HAL2 devices, fall back to wait until idle - On HAL3 devices, call HAL flush method Bug: 9758581 Change-Id: Ie1c570a15f6590a1ee6c271e3b989c48079b468a
-rw-r--r--camera/camera2/ICameraDeviceUser.cpp17
-rw-r--r--include/camera/camera2/ICameraDeviceUser.h3
-rw-r--r--services/camera/libcameraservice/api2/CameraDeviceClient.cpp14
-rw-r--r--services/camera/libcameraservice/api2/CameraDeviceClient.h4
-rw-r--r--services/camera/libcameraservice/common/CameraDeviceBase.h7
-rw-r--r--services/camera/libcameraservice/device2/Camera2Device.cpp28
-rw-r--r--services/camera/libcameraservice/device2/Camera2Device.h5
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp18
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.h7
9 files changed, 100 insertions, 3 deletions
diff --git a/camera/camera2/ICameraDeviceUser.cpp b/camera/camera2/ICameraDeviceUser.cpp
index 923f487..ae4cf69 100644
--- a/camera/camera2/ICameraDeviceUser.cpp
+++ b/camera/camera2/ICameraDeviceUser.cpp
@@ -41,6 +41,7 @@ enum {
CREATE_DEFAULT_REQUEST,
GET_CAMERA_INFO,
WAIT_UNTIL_IDLE,
+ FLUSH
};
class BpCameraDeviceUser : public BpInterface<ICameraDeviceUser>
@@ -183,6 +184,16 @@ public:
return reply.readInt32();
}
+ virtual status_t flush()
+ {
+ ALOGV("flush");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
+ remote()->transact(FLUSH, data, &reply);
+ reply.readExceptionCode();
+ return reply.readInt32();
+ }
+
private:
@@ -312,6 +323,12 @@ status_t BnCameraDeviceUser::onTransact(
reply->writeInt32(waitUntilIdle());
return NO_ERROR;
} break;
+ case FLUSH: {
+ CHECK_INTERFACE(ICameraDeviceUser, data, reply);
+ reply->writeNoException();
+ reply->writeInt32(flush());
+ return NO_ERROR;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/include/camera/camera2/ICameraDeviceUser.h b/include/camera/camera2/ICameraDeviceUser.h
index 45988d0..f71f302 100644
--- a/include/camera/camera2/ICameraDeviceUser.h
+++ b/include/camera/camera2/ICameraDeviceUser.h
@@ -63,6 +63,9 @@ public:
// Wait until all the submitted requests have finished processing
virtual status_t waitUntilIdle() = 0;
+
+ // Flush all pending and in-progress work as quickly as possible.
+ virtual status_t flush() = 0;
};
// ----------------------------------------------------------------------------
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 414316d..289ba06 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -436,6 +436,20 @@ status_t CameraDeviceClient::waitUntilIdle()
return res;
}
+status_t CameraDeviceClient::flush() {
+ ATRACE_CALL();
+ ALOGV("%s", __FUNCTION__);
+
+ status_t res = OK;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
+
+ Mutex::Autolock icl(mBinderSerializationLock);
+
+ if (!mDevice.get()) return DEAD_OBJECT;
+
+ return mDevice->flush();
+}
+
status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
String8 result;
result.appendFormat("CameraDeviceClient[%d] (%p) PID: %d, dump:\n",
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 21d633c..c6b6336 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -89,6 +89,10 @@ public:
// Wait until all the submitted requests have finished processing
virtual status_t waitUntilIdle();
+
+ // Flush all active and pending requests as fast as possible
+ virtual status_t flush();
+
/**
* Interface used by CameraService
*/
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index aa92bec..ebbd4ea 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -209,6 +209,13 @@ class CameraDeviceBase : public virtual RefBase {
*/
virtual status_t pushReprocessBuffer(int reprocessStreamId,
buffer_handle_t *buffer, wp<BufferReleasedListener> listener) = 0;
+
+ /**
+ * Flush all pending and in-flight requests. Blocks until flush is
+ * complete.
+ */
+ virtual status_t flush() = 0;
+
};
}; // namespace android
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index 710d0e9..fe2cd77 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -567,6 +567,13 @@ status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
return res;
}
+status_t Camera2Device::flush() {
+ ATRACE_CALL();
+
+ mRequestQueue.clear();
+ return waitUntilDrained();
+}
+
/**
* Camera2Device::MetadataQueue
*/
@@ -591,9 +598,7 @@ Camera2Device::MetadataQueue::MetadataQueue():
Camera2Device::MetadataQueue::~MetadataQueue() {
ATRACE_CALL();
- Mutex::Autolock l(mMutex);
- freeBuffers(mEntries.begin(), mEntries.end());
- freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
+ clear();
}
// Connect to camera2 HAL as consumer (input requests/reprocessing)
@@ -784,6 +789,23 @@ status_t Camera2Device::MetadataQueue::setStreamSlot(
return signalConsumerLocked();
}
+status_t Camera2Device::MetadataQueue::clear()
+{
+ ATRACE_CALL();
+ ALOGV("%s: E", __FUNCTION__);
+
+ Mutex::Autolock l(mMutex);
+
+ // Clear streaming slot
+ freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
+ mStreamSlotCount = 0;
+
+ // Clear request queue
+ freeBuffers(mEntries.begin(), mEntries.end());
+ mCount = 0;
+ return OK;
+}
+
status_t Camera2Device::MetadataQueue::dump(int fd,
const Vector<String16>& /*args*/) {
ATRACE_CALL();
diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h
index 8945ec2..2aa22a2 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.h
+++ b/services/camera/libcameraservice/device2/Camera2Device.h
@@ -67,6 +67,8 @@ class Camera2Device: public CameraDeviceBase {
virtual status_t triggerPrecaptureMetering(uint32_t id);
virtual status_t pushReprocessBuffer(int reprocessStreamId,
buffer_handle_t *buffer, wp<BufferReleasedListener> listener);
+ // Flush implemented as just a wait
+ virtual status_t flush();
private:
const int mId;
camera2_device_t *mHal2Device;
@@ -113,6 +115,9 @@ class Camera2Device: public CameraDeviceBase {
status_t setStreamSlot(camera_metadata_t *buf);
status_t setStreamSlot(const List<camera_metadata_t*> &bufs);
+ // Clear the request queue and the streaming slot
+ status_t clear();
+
status_t dump(int fd, const Vector<String16>& args);
private:
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 0a4a24c..7f2ec7a 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -952,6 +952,16 @@ status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
return INVALID_OPERATION;
}
+status_t Camera3Device::flush() {
+ ATRACE_CALL();
+ ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
+
+ Mutex::Autolock l(mLock);
+
+ mRequestThread->clear();
+ return mHal3Device->ops->flush(mHal3Device);
+}
+
/**
* Camera3Device private methods
*/
@@ -1488,6 +1498,14 @@ status_t Camera3Device::RequestThread::clearRepeatingRequests() {
return OK;
}
+status_t Camera3Device::RequestThread::clear() {
+ Mutex::Autolock l(mRequestLock);
+ mRepeatingRequests.clear();
+ mRequestQueue.clear();
+ mTriggerMap.clear();
+ return OK;
+}
+
void Camera3Device::RequestThread::setPaused(bool paused) {
Mutex::Autolock l(mPauseLock);
mDoPause = paused;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 76c08ae..99e1cc8 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -124,6 +124,8 @@ class Camera3Device :
virtual status_t pushReprocessBuffer(int reprocessStreamId,
buffer_handle_t *buffer, wp<BufferReleasedListener> listener);
+ virtual status_t flush();
+
private:
static const size_t kInFlightWarnLimit = 20;
static const nsecs_t kShutdownTimeout = 5000000000; // 5 sec
@@ -249,6 +251,11 @@ class Camera3Device :
status_t queueRequest(sp<CaptureRequest> request);
/**
+ * Remove all queued and repeating requests, and pending triggers
+ */
+ status_t clear();
+
+ /**
* Queue a trigger to be dispatched with the next outgoing
* process_capture_request. The settings for that request only
* will be temporarily rewritten to add the trigger tag/value.