Loading services/camera/libcameraservice/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ LOCAL_SRC_FILES:= \ device3/Camera3InputStream.cpp \ device3/Camera3OutputStream.cpp \ device3/Camera3ZslStream.cpp \ device3/Camera3DummyStream.cpp \ device3/StatusTracker.cpp \ gui/RingBufferConsumer.cpp \ utils/CameraTraces.cpp \ Loading services/camera/libcameraservice/device3/Camera3Device.cpp +75 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; Loading services/camera/libcameraservice/device3/Camera3Device.h +15 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,8 @@ class Camera3Device : struct RequestTrigger; // minimal jpeg buffer size: 256KB + blob header static const ssize_t kMinJpegBufferSize = 256 * 1024 + sizeof(camera3_jpeg_blob); // Constant to use for stream ID when one doesn't exist static const int NO_STREAM = -1; // A lock to enforce serialization on the input/configure side // of the public interface. Loading Loading @@ -196,6 +198,8 @@ class Camera3Device : int mNextStreamId; bool mNeedConfig; int mDummyStreamId; // Whether to send state updates upstream // Pause when doing transparent reconfiguration bool mPauseStateNotify; Loading Loading @@ -290,6 +294,17 @@ class Camera3Device : */ status_t configureStreamsLocked(); /** * Add a dummy stream to the current stream set as a workaround for * not allowing 0 streams in the camera HAL spec. */ status_t addDummyStreamLocked(); /** * Remove a dummy stream if the current config includes real streams. */ status_t tryRemoveDummyStreamLocked(); /** * Set device into an error state due to some fatal failure, and set an * error message to indicate why. Only the first call's message will be Loading services/camera/libcameraservice/device3/Camera3DummyStream.cpp 0 → 100644 +97 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "Camera3-DummyStream" #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 #include <utils/Log.h> #include <utils/Trace.h> #include "Camera3DummyStream.h" namespace android { namespace camera3 { Camera3DummyStream::Camera3DummyStream(int id) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, DUMMY_WIDTH, DUMMY_HEIGHT, /*maxSize*/0, DUMMY_FORMAT) { } Camera3DummyStream::~Camera3DummyStream() { } status_t Camera3DummyStream::getBufferLocked(camera3_stream_buffer *buffer) { ATRACE_CALL(); ALOGE("%s: Stream %d: Dummy stream cannot produce buffers!", mId); return INVALID_OPERATION; } status_t Camera3DummyStream::returnBufferLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp) { ATRACE_CALL(); ALOGE("%s: Stream %d: Dummy stream cannot return buffers!", mId); return INVALID_OPERATION; } status_t Camera3DummyStream::returnBufferCheckedLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp, bool output, /*out*/ sp<Fence> *releaseFenceOut) { ATRACE_CALL(); ALOGE("%s: Stream %d: Dummy stream cannot return buffers!", mId); return INVALID_OPERATION; } void Camera3DummyStream::dump(int fd, const Vector<String16> &args) const { (void) args; String8 lines; lines.appendFormat(" Stream[%d]: Dummy\n", mId); write(fd, lines.string(), lines.size()); Camera3IOStreamBase::dump(fd, args); } status_t Camera3DummyStream::setTransform(int transform) { ATRACE_CALL(); // Do nothing return OK; } status_t Camera3DummyStream::configureQueueLocked() { // Do nothing return OK; } status_t Camera3DummyStream::disconnectLocked() { mState = (mState == STATE_IN_RECONFIG) ? STATE_IN_CONFIG : STATE_CONSTRUCTED; return OK; } status_t Camera3DummyStream::getEndpointUsage(uint32_t *usage) { *usage = DUMMY_USAGE; return OK; } }; // namespace camera3 }; // namespace android services/camera/libcameraservice/device3/Camera3DummyStream.h 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_SERVERS_CAMERA3_DUMMY_STREAM_H #define ANDROID_SERVERS_CAMERA3_DUMMY_STREAM_H #include <utils/RefBase.h> #include <gui/Surface.h> #include "Camera3Stream.h" #include "Camera3IOStreamBase.h" #include "Camera3OutputStreamInterface.h" namespace android { namespace camera3 { /** * A dummy output stream class, to be used as a placeholder when no valid * streams are configured by the client. * This is necessary because camera HAL v3.2 or older disallow configuring * 0 output streams, while the public camera2 API allows for it. */ class Camera3DummyStream : public Camera3IOStreamBase, public Camera3OutputStreamInterface { public: /** * Set up a dummy stream; doesn't actually connect to anything, and uses * a default dummy format and size. */ Camera3DummyStream(int id); virtual ~Camera3DummyStream(); /** * Camera3Stream interface */ virtual void dump(int fd, const Vector<String16> &args) const; status_t setTransform(int transform); protected: /** * Note that we release the lock briefly in this function */ virtual status_t returnBufferCheckedLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp, bool output, /*out*/ sp<Fence> *releaseFenceOut); virtual status_t disconnectLocked(); private: // Default dummy parameters; 320x240 is a required size for all devices, // otherwise act like a SurfaceView would. static const int DUMMY_WIDTH = 320; static const int DUMMY_HEIGHT = 240; static const int DUMMY_FORMAT = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; static const uint32_t DUMMY_USAGE = GRALLOC_USAGE_HW_COMPOSER; /** * Internal Camera3Stream interface */ virtual status_t getBufferLocked(camera3_stream_buffer *buffer); virtual status_t returnBufferLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp); virtual status_t configureQueueLocked(); virtual status_t getEndpointUsage(uint32_t *usage); }; // class Camera3DummyStream } // namespace camera3 } // namespace android #endif Loading
services/camera/libcameraservice/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ LOCAL_SRC_FILES:= \ device3/Camera3InputStream.cpp \ device3/Camera3OutputStream.cpp \ device3/Camera3ZslStream.cpp \ device3/Camera3DummyStream.cpp \ device3/StatusTracker.cpp \ gui/RingBufferConsumer.cpp \ utils/CameraTraces.cpp \ Loading
services/camera/libcameraservice/device3/Camera3Device.cpp +75 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; Loading
services/camera/libcameraservice/device3/Camera3Device.h +15 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,8 @@ class Camera3Device : struct RequestTrigger; // minimal jpeg buffer size: 256KB + blob header static const ssize_t kMinJpegBufferSize = 256 * 1024 + sizeof(camera3_jpeg_blob); // Constant to use for stream ID when one doesn't exist static const int NO_STREAM = -1; // A lock to enforce serialization on the input/configure side // of the public interface. Loading Loading @@ -196,6 +198,8 @@ class Camera3Device : int mNextStreamId; bool mNeedConfig; int mDummyStreamId; // Whether to send state updates upstream // Pause when doing transparent reconfiguration bool mPauseStateNotify; Loading Loading @@ -290,6 +294,17 @@ class Camera3Device : */ status_t configureStreamsLocked(); /** * Add a dummy stream to the current stream set as a workaround for * not allowing 0 streams in the camera HAL spec. */ status_t addDummyStreamLocked(); /** * Remove a dummy stream if the current config includes real streams. */ status_t tryRemoveDummyStreamLocked(); /** * Set device into an error state due to some fatal failure, and set an * error message to indicate why. Only the first call's message will be Loading
services/camera/libcameraservice/device3/Camera3DummyStream.cpp 0 → 100644 +97 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "Camera3-DummyStream" #define ATRACE_TAG ATRACE_TAG_CAMERA //#define LOG_NDEBUG 0 #include <utils/Log.h> #include <utils/Trace.h> #include "Camera3DummyStream.h" namespace android { namespace camera3 { Camera3DummyStream::Camera3DummyStream(int id) : Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, DUMMY_WIDTH, DUMMY_HEIGHT, /*maxSize*/0, DUMMY_FORMAT) { } Camera3DummyStream::~Camera3DummyStream() { } status_t Camera3DummyStream::getBufferLocked(camera3_stream_buffer *buffer) { ATRACE_CALL(); ALOGE("%s: Stream %d: Dummy stream cannot produce buffers!", mId); return INVALID_OPERATION; } status_t Camera3DummyStream::returnBufferLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp) { ATRACE_CALL(); ALOGE("%s: Stream %d: Dummy stream cannot return buffers!", mId); return INVALID_OPERATION; } status_t Camera3DummyStream::returnBufferCheckedLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp, bool output, /*out*/ sp<Fence> *releaseFenceOut) { ATRACE_CALL(); ALOGE("%s: Stream %d: Dummy stream cannot return buffers!", mId); return INVALID_OPERATION; } void Camera3DummyStream::dump(int fd, const Vector<String16> &args) const { (void) args; String8 lines; lines.appendFormat(" Stream[%d]: Dummy\n", mId); write(fd, lines.string(), lines.size()); Camera3IOStreamBase::dump(fd, args); } status_t Camera3DummyStream::setTransform(int transform) { ATRACE_CALL(); // Do nothing return OK; } status_t Camera3DummyStream::configureQueueLocked() { // Do nothing return OK; } status_t Camera3DummyStream::disconnectLocked() { mState = (mState == STATE_IN_RECONFIG) ? STATE_IN_CONFIG : STATE_CONSTRUCTED; return OK; } status_t Camera3DummyStream::getEndpointUsage(uint32_t *usage) { *usage = DUMMY_USAGE; return OK; } }; // namespace camera3 }; // namespace android
services/camera/libcameraservice/device3/Camera3DummyStream.h 0 → 100644 +98 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_SERVERS_CAMERA3_DUMMY_STREAM_H #define ANDROID_SERVERS_CAMERA3_DUMMY_STREAM_H #include <utils/RefBase.h> #include <gui/Surface.h> #include "Camera3Stream.h" #include "Camera3IOStreamBase.h" #include "Camera3OutputStreamInterface.h" namespace android { namespace camera3 { /** * A dummy output stream class, to be used as a placeholder when no valid * streams are configured by the client. * This is necessary because camera HAL v3.2 or older disallow configuring * 0 output streams, while the public camera2 API allows for it. */ class Camera3DummyStream : public Camera3IOStreamBase, public Camera3OutputStreamInterface { public: /** * Set up a dummy stream; doesn't actually connect to anything, and uses * a default dummy format and size. */ Camera3DummyStream(int id); virtual ~Camera3DummyStream(); /** * Camera3Stream interface */ virtual void dump(int fd, const Vector<String16> &args) const; status_t setTransform(int transform); protected: /** * Note that we release the lock briefly in this function */ virtual status_t returnBufferCheckedLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp, bool output, /*out*/ sp<Fence> *releaseFenceOut); virtual status_t disconnectLocked(); private: // Default dummy parameters; 320x240 is a required size for all devices, // otherwise act like a SurfaceView would. static const int DUMMY_WIDTH = 320; static const int DUMMY_HEIGHT = 240; static const int DUMMY_FORMAT = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; static const uint32_t DUMMY_USAGE = GRALLOC_USAGE_HW_COMPOSER; /** * Internal Camera3Stream interface */ virtual status_t getBufferLocked(camera3_stream_buffer *buffer); virtual status_t returnBufferLocked( const camera3_stream_buffer &buffer, nsecs_t timestamp); virtual status_t configureQueueLocked(); virtual status_t getEndpointUsage(uint32_t *usage); }; // class Camera3DummyStream } // namespace camera3 } // namespace android #endif