summaryrefslogtreecommitdiffstats
path: root/services/camera/libcameraservice/device3/Camera3Device.cpp
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2014-08-27 14:41:33 -0700
committerEino-Ville Talvala <etalvala@google.com>2014-08-28 15:47:50 -0700
commit16a2ada049447c156648812b94d25be07869f284 (patch)
treeef74c94c21a8ce5989cca904c87b36146993f58f /services/camera/libcameraservice/device3/Camera3Device.cpp
parent1754351d9199721e7e7943461689e399ef015260 (diff)
downloadframeworks_av-16a2ada049447c156648812b94d25be07869f284.zip
frameworks_av-16a2ada049447c156648812b94d25be07869f284.tar.gz
frameworks_av-16a2ada049447c156648812b94d25be07869f284.tar.bz2
CameraService: Create a dummy stream when 0 streams are requested.
A workaround for a camera device HAL v3.2 or older specification hole - it's not acceptable to configure_streams with 0 output streams. However, we allow for this at the public API level, to allow an application to release all output streams. So in this case, create a dummy stream that doesn't actually do anything as a placeholder. Bug: 17220694 Change-Id: Ib25242ffc2c9f2b2f619fd5fe6d652266579da85
Diffstat (limited to 'services/camera/libcameraservice/device3/Camera3Device.cpp')
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp76
1 files changed, 75 insertions, 1 deletions
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 9b51b99..6f78db5 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -48,6 +48,7 @@
#include "device3/Camera3OutputStream.h"
#include "device3/Camera3InputStream.h"
#include "device3/Camera3ZslStream.h"
+#include "device3/Camera3DummyStream.h"
#include "CameraService.h"
using namespace android::camera3;
@@ -181,6 +182,7 @@ status_t Camera3Device::initialize(camera_module_t *module)
mHal3Device = device;
mStatus = STATUS_UNCONFIGURED;
mNextStreamId = 0;
+ mDummyStreamId = NO_STREAM;
mNeedConfig = true;
mPauseStateNotify = false;
@@ -1418,6 +1420,15 @@ status_t Camera3Device::configureStreamsLocked() {
return OK;
}
+ // Workaround for device HALv3.2 or older spec bug - zero streams requires
+ // adding a dummy stream instead.
+ // TODO: Bug: 17321404 for fixing the HAL spec and removing this workaround.
+ if (mOutputStreams.size() == 0) {
+ addDummyStreamLocked();
+ } else {
+ tryRemoveDummyStreamLocked();
+ }
+
// Start configuring the streams
ALOGV("%s: Camera %d: Starting stream configuration", __FUNCTION__, mId);
@@ -1540,7 +1551,7 @@ status_t Camera3Device::configureStreamsLocked() {
mNeedConfig = false;
- if (config.num_streams > 0) {
+ if (mDummyStreamId == NO_STREAM) {
mStatus = STATUS_CONFIGURED;
} else {
mStatus = STATUS_UNCONFIGURED;
@@ -1554,6 +1565,69 @@ status_t Camera3Device::configureStreamsLocked() {
return OK;
}
+status_t Camera3Device::addDummyStreamLocked() {
+ ATRACE_CALL();
+ status_t res;
+
+ if (mDummyStreamId != NO_STREAM) {
+ // Should never be adding a second dummy stream when one is already
+ // active
+ SET_ERR_L("%s: Camera %d: A dummy stream already exists!",
+ __FUNCTION__, mId);
+ return INVALID_OPERATION;
+ }
+
+ ALOGV("%s: Camera %d: Adding a dummy stream", __FUNCTION__, mId);
+
+ sp<Camera3OutputStreamInterface> dummyStream =
+ new Camera3DummyStream(mNextStreamId);
+
+ res = mOutputStreams.add(mNextStreamId, dummyStream);
+ if (res < 0) {
+ SET_ERR_L("Can't add dummy stream to set: %s (%d)", strerror(-res), res);
+ return res;
+ }
+
+ mDummyStreamId = mNextStreamId;
+ mNextStreamId++;
+
+ return OK;
+}
+
+status_t Camera3Device::tryRemoveDummyStreamLocked() {
+ ATRACE_CALL();
+ status_t res;
+
+ if (mDummyStreamId == NO_STREAM) return OK;
+ if (mOutputStreams.size() == 1) return OK;
+
+ ALOGV("%s: Camera %d: Removing the dummy stream", __FUNCTION__, mId);
+
+ // Ok, have a dummy stream and there's at least one other output stream,
+ // so remove the dummy
+
+ sp<Camera3StreamInterface> deletedStream;
+ ssize_t outputStreamIdx = mOutputStreams.indexOfKey(mDummyStreamId);
+ if (outputStreamIdx == NAME_NOT_FOUND) {
+ SET_ERR_L("Dummy stream %d does not appear to exist", mDummyStreamId);
+ return INVALID_OPERATION;
+ }
+
+ deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
+ mOutputStreams.removeItemsAt(outputStreamIdx);
+
+ // Free up the stream endpoint so that it can be used by some other stream
+ res = deletedStream->disconnect();
+ if (res != OK) {
+ SET_ERR_L("Can't disconnect deleted dummy stream %d", mDummyStreamId);
+ // fall through since we want to still list the stream as deleted.
+ }
+ mDeletedStreams.add(deletedStream);
+ mDummyStreamId = NO_STREAM;
+
+ return res;
+}
+
void Camera3Device::setErrorState(const char *fmt, ...) {
Mutex::Autolock l(mLock);
va_list args;