diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2014-08-27 14:41:33 -0700 |
---|---|---|
committer | Eino-Ville Talvala <etalvala@google.com> | 2014-08-28 15:47:50 -0700 |
commit | 16a2ada049447c156648812b94d25be07869f284 (patch) | |
tree | ef74c94c21a8ce5989cca904c87b36146993f58f /services/camera/libcameraservice/device3/Camera3Device.cpp | |
parent | 1754351d9199721e7e7943461689e399ef015260 (diff) | |
download | frameworks_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.cpp | 76 |
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; |