Loading camera/CameraMetadata.cpp +105 −12 Original line number Original line Diff line number Diff line Loading @@ -23,19 +23,22 @@ namespace android { namespace android { CameraMetadata::CameraMetadata() : CameraMetadata::CameraMetadata() : mBuffer(NULL) { mBuffer(NULL), mLocked(false) { } } CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) : mLocked(false) { { mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); } } CameraMetadata::CameraMetadata(const CameraMetadata &other) { CameraMetadata::CameraMetadata(const CameraMetadata &other) : mLocked(false) { mBuffer = clone_camera_metadata(other.mBuffer); mBuffer = clone_camera_metadata(other.mBuffer); } } CameraMetadata::CameraMetadata(camera_metadata_t *buffer) : mBuffer(NULL) { CameraMetadata::CameraMetadata(camera_metadata_t *buffer) : mBuffer(NULL), mLocked(false) { acquire(buffer); acquire(buffer); } } Loading @@ -44,6 +47,11 @@ CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) { } } CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { if (mLocked) { ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__); return *this; } if (CC_LIKELY(buffer != mBuffer)) { if (CC_LIKELY(buffer != mBuffer)) { camera_metadata_t *newBuffer = clone_camera_metadata(buffer); camera_metadata_t *newBuffer = clone_camera_metadata(buffer); clear(); clear(); Loading @@ -53,16 +61,44 @@ CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { } } CameraMetadata::~CameraMetadata() { CameraMetadata::~CameraMetadata() { mLocked = false; clear(); clear(); } } const camera_metadata_t* CameraMetadata::getAndLock() { mLocked = true; return mBuffer; } status_t CameraMetadata::unlock(const camera_metadata_t *buffer) { if (!mLocked) { ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__); return INVALID_OPERATION; } if (buffer != mBuffer) { ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!", __FUNCTION__); return BAD_VALUE; } mLocked = false; return OK; } camera_metadata_t* CameraMetadata::release() { camera_metadata_t* CameraMetadata::release() { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return NULL; } camera_metadata_t *released = mBuffer; camera_metadata_t *released = mBuffer; mBuffer = NULL; mBuffer = NULL; return released; return released; } } void CameraMetadata::clear() { void CameraMetadata::clear() { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } if (mBuffer) { if (mBuffer) { free_camera_metadata(mBuffer); free_camera_metadata(mBuffer); mBuffer = NULL; mBuffer = NULL; Loading @@ -70,15 +106,27 @@ void CameraMetadata::clear() { } } void CameraMetadata::acquire(camera_metadata_t *buffer) { void CameraMetadata::acquire(camera_metadata_t *buffer) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } clear(); clear(); mBuffer = buffer; mBuffer = buffer; } } void CameraMetadata::acquire(CameraMetadata &other) { void CameraMetadata::acquire(CameraMetadata &other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } acquire(other.release()); acquire(other.release()); } } status_t CameraMetadata::append(const CameraMetadata &other) { status_t CameraMetadata::append(const CameraMetadata &other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } return append_camera_metadata(mBuffer, other.mBuffer); return append_camera_metadata(mBuffer, other.mBuffer); } } Loading @@ -92,6 +140,10 @@ bool CameraMetadata::isEmpty() const { } } status_t CameraMetadata::sort() { status_t CameraMetadata::sort() { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } return sort_camera_metadata(mBuffer); return sort_camera_metadata(mBuffer); } } Loading @@ -115,69 +167,101 @@ status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) { status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const int32_t *data, size_t data_count) { const int32_t *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_INT32)) != OK) { if ( (res = checkType(tag, TYPE_INT32)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const uint8_t *data, size_t data_count) { const uint8_t *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_BYTE)) != OK) { if ( (res = checkType(tag, TYPE_BYTE)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const float *data, size_t data_count) { const float *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const int64_t *data, size_t data_count) { const int64_t *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_INT64)) != OK) { if ( (res = checkType(tag, TYPE_INT64)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const double *data, size_t data_count) { const double *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const camera_metadata_rational_t *data, size_t data_count) { const camera_metadata_rational_t *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const String8 &string) { const String8 &string) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_BYTE)) != OK) { if ( (res = checkType(tag, TYPE_BYTE)) != OK) { return res; return res; } } return update(tag, (const void*)string.string(), string.size()); return updateImpl(tag, (const void*)string.string(), string.size()); } } status_t CameraMetadata::update(uint32_t tag, const void *data, status_t CameraMetadata::updateImpl(uint32_t tag, const void *data, size_t data_count) { size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } int type = get_camera_metadata_tag_type(tag); int type = get_camera_metadata_tag_type(tag); if (type == -1) { if (type == -1) { ALOGE("%s: Tag %d not found", __FUNCTION__, tag); ALOGE("%s: Tag %d not found", __FUNCTION__, tag); Loading Loading @@ -216,6 +300,11 @@ bool CameraMetadata::exists(uint32_t tag) const { camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { status_t res; status_t res; camera_metadata_entry entry; camera_metadata_entry entry; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); entry.count = 0; return entry; } res = find_camera_metadata_entry(mBuffer, tag, &entry); res = find_camera_metadata_entry(mBuffer, tag, &entry); if (CC_UNLIKELY( res != OK )) { if (CC_UNLIKELY( res != OK )) { entry.count = 0; entry.count = 0; Loading @@ -238,6 +327,10 @@ camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const { status_t CameraMetadata::erase(uint32_t tag) { status_t CameraMetadata::erase(uint32_t tag) { camera_metadata_entry_t entry; camera_metadata_entry_t entry; status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } res = find_camera_metadata_entry(mBuffer, tag, &entry); res = find_camera_metadata_entry(mBuffer, tag, &entry); if (res == NAME_NOT_FOUND) { if (res == NAME_NOT_FOUND) { return OK; return OK; Loading include/camera/CameraMetadata.h +19 −1 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,23 @@ class CameraMetadata { CameraMetadata &operator=(const CameraMetadata &other); CameraMetadata &operator=(const CameraMetadata &other); CameraMetadata &operator=(const camera_metadata_t *buffer); CameraMetadata &operator=(const camera_metadata_t *buffer); /** * Get reference to the underlying metadata buffer. Ownership remains with * the CameraMetadata object, but non-const CameraMetadata methods will not * work until unlock() is called. Note that the lock has nothing to do with * thread-safety, it simply prevents the camera_metadata_t pointer returned * here from being accidentally invalidated by CameraMetadata operations. */ const camera_metadata_t* getAndLock(); /** * Unlock the CameraMetadata for use again. After this unlock, the pointer * given from getAndLock() may no longer be used. The pointer passed out * from getAndLock must be provided to guarantee that the right object is * being unlocked. */ status_t unlock(const camera_metadata_t *buffer); /** /** * Release a raw metadata buffer to the caller. After this call, * Release a raw metadata buffer to the caller. After this call, * CameraMetadata no longer references the buffer, and the caller takes * CameraMetadata no longer references the buffer, and the caller takes Loading Loading @@ -154,6 +171,7 @@ class CameraMetadata { private: private: camera_metadata_t *mBuffer; camera_metadata_t *mBuffer; bool mLocked; /** /** * Check if tag has a given type * Check if tag has a given type Loading @@ -163,7 +181,7 @@ class CameraMetadata { /** /** * Base update entry method * Base update entry method */ */ status_t update(uint32_t tag, const void *data, size_t data_count); status_t updateImpl(uint32_t tag, const void *data, size_t data_count); /** /** * Resize metadata buffer if needed by reallocating it and copying it over. * Resize metadata buffer if needed by reallocating it and copying it over. Loading services/camera/libcameraservice/Camera3Device.cpp +782 −38 File changed.Preview size limit exceeded, changes collapsed. Show changes services/camera/libcameraservice/Camera3Device.h +152 −11 Original line number Original line Diff line number Diff line Loading @@ -14,8 +14,8 @@ * limitations under the License. * limitations under the License. */ */ #ifndef ANDROID_SERVERS_CAMERA_CAMERA3DEVICE_H #ifndef ANDROID_SERVERS_CAMERA3DEVICE_H #define ANDROID_SERVERS_CAMERA_CAMERA3DEVICE_H #define ANDROID_SERVERS_CAMERA3DEVICE_H #include <utils/Condition.h> #include <utils/Condition.h> #include <utils/Errors.h> #include <utils/Errors.h> Loading @@ -24,6 +24,8 @@ #include <utils/Thread.h> #include <utils/Thread.h> #include "CameraDeviceBase.h" #include "CameraDeviceBase.h" #include "camera3/Camera3Stream.h" #include "camera3/Camera3OutputStream.h" #include "hardware/camera3.h" #include "hardware/camera3.h" Loading Loading @@ -55,44 +57,121 @@ class Camera3Device : virtual ~Camera3Device(); virtual ~Camera3Device(); /** /** * CameraDevice interface * CameraDeviceBase interface */ */ virtual int getId() const; virtual int getId() const; // Transitions to idle state on success. virtual status_t initialize(camera_module_t *module); virtual status_t initialize(camera_module_t *module); virtual status_t disconnect(); virtual status_t disconnect(); virtual status_t dump(int fd, const Vector<String16> &args); virtual status_t dump(int fd, const Vector<String16> &args); virtual const CameraMetadata& info() const; virtual const CameraMetadata& info() const; // Capture and setStreamingRequest will configure streams if currently in // idle state virtual status_t capture(CameraMetadata &request); virtual status_t capture(CameraMetadata &request); virtual status_t setStreamingRequest(const CameraMetadata &request); virtual status_t setStreamingRequest(const CameraMetadata &request); virtual status_t clearStreamingRequest(); virtual status_t clearStreamingRequest(); virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout); virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout); // Actual stream creation/deletion is delayed until first request is submitted // If adding streams while actively capturing, will pause device before adding // stream, reconfiguring device, and unpausing. virtual status_t createStream(sp<ANativeWindow> consumer, virtual status_t createStream(sp<ANativeWindow> consumer, uint32_t width, uint32_t height, int format, size_t size, uint32_t width, uint32_t height, int format, size_t size, int *id); int *id); virtual status_t createReprocessStreamFromStream(int outputId, int *id); virtual status_t createReprocessStreamFromStream(int outputId, int *id); virtual status_t getStreamInfo(int id, virtual status_t getStreamInfo(int id, uint32_t *width, uint32_t *height, uint32_t *format); uint32_t *width, uint32_t *height, uint32_t *format); virtual status_t setStreamTransform(int id, int transform); virtual status_t setStreamTransform(int id, int transform); virtual status_t deleteStream(int id); virtual status_t deleteStream(int id); virtual status_t deleteReprocessStream(int id); virtual status_t deleteReprocessStream(int id); virtual status_t createDefaultRequest(int templateId, CameraMetadata *request); virtual status_t createDefaultRequest(int templateId, CameraMetadata *request); // Transitions to the idle state on success virtual status_t waitUntilDrained(); virtual status_t waitUntilDrained(); virtual status_t setNotifyCallback(NotificationListener *listener); virtual status_t setNotifyCallback(NotificationListener *listener); virtual status_t waitForNextFrame(nsecs_t timeout); virtual status_t waitForNextFrame(nsecs_t timeout); virtual status_t getNextFrame(CameraMetadata *frame); virtual status_t getNextFrame(CameraMetadata *frame); virtual status_t triggerAutofocus(uint32_t id); virtual status_t triggerAutofocus(uint32_t id); virtual status_t triggerCancelAutofocus(uint32_t id); virtual status_t triggerCancelAutofocus(uint32_t id); virtual status_t triggerPrecaptureMetering(uint32_t id); virtual status_t triggerPrecaptureMetering(uint32_t id); virtual status_t pushReprocessBuffer(int reprocessStreamId, virtual status_t pushReprocessBuffer(int reprocessStreamId, buffer_handle_t *buffer, wp<BufferReleasedListener> listener); buffer_handle_t *buffer, wp<BufferReleasedListener> listener); private: private: static const nsecs_t kShutdownTimeout = 5000000000; // 5 sec Mutex mLock; /**** Scope for mLock ****/ const int mId; const int mId; camera3_device_t *mHal3Device; camera3_device_t *mHal3Device; CameraMetadata mDeviceInfo; CameraMetadata mDeviceInfo; vendor_tag_query_ops_t mVendorTagOps; vendor_tag_query_ops_t mVendorTagOps; enum { STATUS_ERROR, STATUS_UNINITIALIZED, STATUS_IDLE, STATUS_ACTIVE } mStatus; // Mapping of stream IDs to stream instances typedef KeyedVector<int, sp<camera3::Camera3OutputStream> > StreamSet; StreamSet mOutputStreams; sp<camera3::Camera3Stream> mInputStream; int mNextStreamId; // Need to hold on to stream references until configure completes. Vector<sp<camera3::Camera3Stream> > mDeletedStreams; /**** End scope for mLock ****/ class CaptureRequest : public LightRefBase<CaptureRequest> { public: CameraMetadata mSettings; sp<camera3::Camera3Stream> mInputStream; Vector<sp<camera3::Camera3Stream> > mOutputStreams; }; typedef List<sp<CaptureRequest> > RequestList; /** * Lock-held version of waitUntilDrained. Will transition to IDLE on * success. */ status_t waitUntilDrainedLocked(); /** * Do common work for setting up a streaming or single capture request. * On success, will transition to ACTIVE if in IDLE. */ sp<CaptureRequest> setUpRequestLocked(const CameraMetadata &request); /** * Build a CaptureRequest request from the CameraDeviceBase request * settings. */ sp<CaptureRequest> createCaptureRequest(const CameraMetadata &request); /** * Take the currently-defined set of streams and configure the HAL to use * them. This is a long-running operation (may be several hundered ms). */ status_t configureStreamsLocked(); /** /** * Thread for managing capture request submission to HAL device. * Thread for managing capture request submission to HAL device. */ */ Loading @@ -100,18 +179,80 @@ class Camera3Device : public: public: RequestThread(wp<Camera3Device> parent); RequestThread(wp<Camera3Device> parent, camera3_device_t *hal3Device); /** * Call after stream (re)-configuration is completed. */ void configurationComplete(); /** * Set or clear the list of repeating requests. Does not block * on either. Use waitUntilPaused to wait until request queue * has emptied out. */ status_t setRepeatingRequests(const RequestList& requests); status_t clearRepeatingRequests(); status_t queueRequest(sp<CaptureRequest> request); /** * Pause/unpause the capture thread. Doesn't block, so use * waitUntilPaused to wait until the thread is paused. */ void setPaused(bool paused); /** * Wait until thread is paused, either due to setPaused(true) * or due to lack of input requests. Returns TIMED_OUT in case * the thread does not pause within the timeout. */ status_t waitUntilPaused(nsecs_t timeout); protected: protected: virtual bool threadLoop(); virtual bool threadLoop(); private: private: static const nsecs_t kRequestTimeout = 50e6; // 50 ms // Waits for a request, or returns NULL if times out. sp<CaptureRequest> waitForNextRequest(); // Return buffers, etc, for a request that couldn't be fully // constructed. The buffers will be returned in the ERROR state // to mark them as not having valid data. // All arguments will be modified. void cleanUpFailedRequest(camera3_capture_request_t &request, sp<CaptureRequest> &nextRequest, Vector<camera3_stream_buffer_t> &outputBuffers); // Pause handling bool waitIfPaused(); wp<Camera3Device> mParent; wp<Camera3Device> mParent; camera3_device_t *mHal3Device; Mutex mRequestLock; Condition mRequestSignal; RequestList mRequestQueue; RequestList mRepeatingRequests; bool mReconfigured; // Used by waitIfPaused, waitForNextRequest, and waitUntilPaused Mutex mPauseLock; bool mDoPause; Condition mDoPauseSignal; bool mPaused; Condition mPausedSignal; sp<CaptureRequest> mPrevRequest; int32_t mFrameNumber; }; }; sp<RequestThread> requestThread; sp<RequestThread> mRequestThread; /** /** * Callback functions from HAL device * Callback functions from HAL device Loading Loading
camera/CameraMetadata.cpp +105 −12 Original line number Original line Diff line number Diff line Loading @@ -23,19 +23,22 @@ namespace android { namespace android { CameraMetadata::CameraMetadata() : CameraMetadata::CameraMetadata() : mBuffer(NULL) { mBuffer(NULL), mLocked(false) { } } CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) : mLocked(false) { { mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); } } CameraMetadata::CameraMetadata(const CameraMetadata &other) { CameraMetadata::CameraMetadata(const CameraMetadata &other) : mLocked(false) { mBuffer = clone_camera_metadata(other.mBuffer); mBuffer = clone_camera_metadata(other.mBuffer); } } CameraMetadata::CameraMetadata(camera_metadata_t *buffer) : mBuffer(NULL) { CameraMetadata::CameraMetadata(camera_metadata_t *buffer) : mBuffer(NULL), mLocked(false) { acquire(buffer); acquire(buffer); } } Loading @@ -44,6 +47,11 @@ CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) { } } CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { if (mLocked) { ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__); return *this; } if (CC_LIKELY(buffer != mBuffer)) { if (CC_LIKELY(buffer != mBuffer)) { camera_metadata_t *newBuffer = clone_camera_metadata(buffer); camera_metadata_t *newBuffer = clone_camera_metadata(buffer); clear(); clear(); Loading @@ -53,16 +61,44 @@ CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { } } CameraMetadata::~CameraMetadata() { CameraMetadata::~CameraMetadata() { mLocked = false; clear(); clear(); } } const camera_metadata_t* CameraMetadata::getAndLock() { mLocked = true; return mBuffer; } status_t CameraMetadata::unlock(const camera_metadata_t *buffer) { if (!mLocked) { ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__); return INVALID_OPERATION; } if (buffer != mBuffer) { ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!", __FUNCTION__); return BAD_VALUE; } mLocked = false; return OK; } camera_metadata_t* CameraMetadata::release() { camera_metadata_t* CameraMetadata::release() { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return NULL; } camera_metadata_t *released = mBuffer; camera_metadata_t *released = mBuffer; mBuffer = NULL; mBuffer = NULL; return released; return released; } } void CameraMetadata::clear() { void CameraMetadata::clear() { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } if (mBuffer) { if (mBuffer) { free_camera_metadata(mBuffer); free_camera_metadata(mBuffer); mBuffer = NULL; mBuffer = NULL; Loading @@ -70,15 +106,27 @@ void CameraMetadata::clear() { } } void CameraMetadata::acquire(camera_metadata_t *buffer) { void CameraMetadata::acquire(camera_metadata_t *buffer) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } clear(); clear(); mBuffer = buffer; mBuffer = buffer; } } void CameraMetadata::acquire(CameraMetadata &other) { void CameraMetadata::acquire(CameraMetadata &other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return; } acquire(other.release()); acquire(other.release()); } } status_t CameraMetadata::append(const CameraMetadata &other) { status_t CameraMetadata::append(const CameraMetadata &other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } return append_camera_metadata(mBuffer, other.mBuffer); return append_camera_metadata(mBuffer, other.mBuffer); } } Loading @@ -92,6 +140,10 @@ bool CameraMetadata::isEmpty() const { } } status_t CameraMetadata::sort() { status_t CameraMetadata::sort() { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } return sort_camera_metadata(mBuffer); return sort_camera_metadata(mBuffer); } } Loading @@ -115,69 +167,101 @@ status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) { status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const int32_t *data, size_t data_count) { const int32_t *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_INT32)) != OK) { if ( (res = checkType(tag, TYPE_INT32)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const uint8_t *data, size_t data_count) { const uint8_t *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_BYTE)) != OK) { if ( (res = checkType(tag, TYPE_BYTE)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const float *data, size_t data_count) { const float *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const int64_t *data, size_t data_count) { const int64_t *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_INT64)) != OK) { if ( (res = checkType(tag, TYPE_INT64)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const double *data, size_t data_count) { const double *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const camera_metadata_rational_t *data, size_t data_count) { const camera_metadata_rational_t *data, size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { return res; return res; } } return update(tag, (const void*)data, data_count); return updateImpl(tag, (const void*)data, data_count); } } status_t CameraMetadata::update(uint32_t tag, status_t CameraMetadata::update(uint32_t tag, const String8 &string) { const String8 &string) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } if ( (res = checkType(tag, TYPE_BYTE)) != OK) { if ( (res = checkType(tag, TYPE_BYTE)) != OK) { return res; return res; } } return update(tag, (const void*)string.string(), string.size()); return updateImpl(tag, (const void*)string.string(), string.size()); } } status_t CameraMetadata::update(uint32_t tag, const void *data, status_t CameraMetadata::updateImpl(uint32_t tag, const void *data, size_t data_count) { size_t data_count) { status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } int type = get_camera_metadata_tag_type(tag); int type = get_camera_metadata_tag_type(tag); if (type == -1) { if (type == -1) { ALOGE("%s: Tag %d not found", __FUNCTION__, tag); ALOGE("%s: Tag %d not found", __FUNCTION__, tag); Loading Loading @@ -216,6 +300,11 @@ bool CameraMetadata::exists(uint32_t tag) const { camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { status_t res; status_t res; camera_metadata_entry entry; camera_metadata_entry entry; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); entry.count = 0; return entry; } res = find_camera_metadata_entry(mBuffer, tag, &entry); res = find_camera_metadata_entry(mBuffer, tag, &entry); if (CC_UNLIKELY( res != OK )) { if (CC_UNLIKELY( res != OK )) { entry.count = 0; entry.count = 0; Loading @@ -238,6 +327,10 @@ camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const { status_t CameraMetadata::erase(uint32_t tag) { status_t CameraMetadata::erase(uint32_t tag) { camera_metadata_entry_t entry; camera_metadata_entry_t entry; status_t res; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } res = find_camera_metadata_entry(mBuffer, tag, &entry); res = find_camera_metadata_entry(mBuffer, tag, &entry); if (res == NAME_NOT_FOUND) { if (res == NAME_NOT_FOUND) { return OK; return OK; Loading
include/camera/CameraMetadata.h +19 −1 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,23 @@ class CameraMetadata { CameraMetadata &operator=(const CameraMetadata &other); CameraMetadata &operator=(const CameraMetadata &other); CameraMetadata &operator=(const camera_metadata_t *buffer); CameraMetadata &operator=(const camera_metadata_t *buffer); /** * Get reference to the underlying metadata buffer. Ownership remains with * the CameraMetadata object, but non-const CameraMetadata methods will not * work until unlock() is called. Note that the lock has nothing to do with * thread-safety, it simply prevents the camera_metadata_t pointer returned * here from being accidentally invalidated by CameraMetadata operations. */ const camera_metadata_t* getAndLock(); /** * Unlock the CameraMetadata for use again. After this unlock, the pointer * given from getAndLock() may no longer be used. The pointer passed out * from getAndLock must be provided to guarantee that the right object is * being unlocked. */ status_t unlock(const camera_metadata_t *buffer); /** /** * Release a raw metadata buffer to the caller. After this call, * Release a raw metadata buffer to the caller. After this call, * CameraMetadata no longer references the buffer, and the caller takes * CameraMetadata no longer references the buffer, and the caller takes Loading Loading @@ -154,6 +171,7 @@ class CameraMetadata { private: private: camera_metadata_t *mBuffer; camera_metadata_t *mBuffer; bool mLocked; /** /** * Check if tag has a given type * Check if tag has a given type Loading @@ -163,7 +181,7 @@ class CameraMetadata { /** /** * Base update entry method * Base update entry method */ */ status_t update(uint32_t tag, const void *data, size_t data_count); status_t updateImpl(uint32_t tag, const void *data, size_t data_count); /** /** * Resize metadata buffer if needed by reallocating it and copying it over. * Resize metadata buffer if needed by reallocating it and copying it over. Loading
services/camera/libcameraservice/Camera3Device.cpp +782 −38 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/camera/libcameraservice/Camera3Device.h +152 −11 Original line number Original line Diff line number Diff line Loading @@ -14,8 +14,8 @@ * limitations under the License. * limitations under the License. */ */ #ifndef ANDROID_SERVERS_CAMERA_CAMERA3DEVICE_H #ifndef ANDROID_SERVERS_CAMERA3DEVICE_H #define ANDROID_SERVERS_CAMERA_CAMERA3DEVICE_H #define ANDROID_SERVERS_CAMERA3DEVICE_H #include <utils/Condition.h> #include <utils/Condition.h> #include <utils/Errors.h> #include <utils/Errors.h> Loading @@ -24,6 +24,8 @@ #include <utils/Thread.h> #include <utils/Thread.h> #include "CameraDeviceBase.h" #include "CameraDeviceBase.h" #include "camera3/Camera3Stream.h" #include "camera3/Camera3OutputStream.h" #include "hardware/camera3.h" #include "hardware/camera3.h" Loading Loading @@ -55,44 +57,121 @@ class Camera3Device : virtual ~Camera3Device(); virtual ~Camera3Device(); /** /** * CameraDevice interface * CameraDeviceBase interface */ */ virtual int getId() const; virtual int getId() const; // Transitions to idle state on success. virtual status_t initialize(camera_module_t *module); virtual status_t initialize(camera_module_t *module); virtual status_t disconnect(); virtual status_t disconnect(); virtual status_t dump(int fd, const Vector<String16> &args); virtual status_t dump(int fd, const Vector<String16> &args); virtual const CameraMetadata& info() const; virtual const CameraMetadata& info() const; // Capture and setStreamingRequest will configure streams if currently in // idle state virtual status_t capture(CameraMetadata &request); virtual status_t capture(CameraMetadata &request); virtual status_t setStreamingRequest(const CameraMetadata &request); virtual status_t setStreamingRequest(const CameraMetadata &request); virtual status_t clearStreamingRequest(); virtual status_t clearStreamingRequest(); virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout); virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout); // Actual stream creation/deletion is delayed until first request is submitted // If adding streams while actively capturing, will pause device before adding // stream, reconfiguring device, and unpausing. virtual status_t createStream(sp<ANativeWindow> consumer, virtual status_t createStream(sp<ANativeWindow> consumer, uint32_t width, uint32_t height, int format, size_t size, uint32_t width, uint32_t height, int format, size_t size, int *id); int *id); virtual status_t createReprocessStreamFromStream(int outputId, int *id); virtual status_t createReprocessStreamFromStream(int outputId, int *id); virtual status_t getStreamInfo(int id, virtual status_t getStreamInfo(int id, uint32_t *width, uint32_t *height, uint32_t *format); uint32_t *width, uint32_t *height, uint32_t *format); virtual status_t setStreamTransform(int id, int transform); virtual status_t setStreamTransform(int id, int transform); virtual status_t deleteStream(int id); virtual status_t deleteStream(int id); virtual status_t deleteReprocessStream(int id); virtual status_t deleteReprocessStream(int id); virtual status_t createDefaultRequest(int templateId, CameraMetadata *request); virtual status_t createDefaultRequest(int templateId, CameraMetadata *request); // Transitions to the idle state on success virtual status_t waitUntilDrained(); virtual status_t waitUntilDrained(); virtual status_t setNotifyCallback(NotificationListener *listener); virtual status_t setNotifyCallback(NotificationListener *listener); virtual status_t waitForNextFrame(nsecs_t timeout); virtual status_t waitForNextFrame(nsecs_t timeout); virtual status_t getNextFrame(CameraMetadata *frame); virtual status_t getNextFrame(CameraMetadata *frame); virtual status_t triggerAutofocus(uint32_t id); virtual status_t triggerAutofocus(uint32_t id); virtual status_t triggerCancelAutofocus(uint32_t id); virtual status_t triggerCancelAutofocus(uint32_t id); virtual status_t triggerPrecaptureMetering(uint32_t id); virtual status_t triggerPrecaptureMetering(uint32_t id); virtual status_t pushReprocessBuffer(int reprocessStreamId, virtual status_t pushReprocessBuffer(int reprocessStreamId, buffer_handle_t *buffer, wp<BufferReleasedListener> listener); buffer_handle_t *buffer, wp<BufferReleasedListener> listener); private: private: static const nsecs_t kShutdownTimeout = 5000000000; // 5 sec Mutex mLock; /**** Scope for mLock ****/ const int mId; const int mId; camera3_device_t *mHal3Device; camera3_device_t *mHal3Device; CameraMetadata mDeviceInfo; CameraMetadata mDeviceInfo; vendor_tag_query_ops_t mVendorTagOps; vendor_tag_query_ops_t mVendorTagOps; enum { STATUS_ERROR, STATUS_UNINITIALIZED, STATUS_IDLE, STATUS_ACTIVE } mStatus; // Mapping of stream IDs to stream instances typedef KeyedVector<int, sp<camera3::Camera3OutputStream> > StreamSet; StreamSet mOutputStreams; sp<camera3::Camera3Stream> mInputStream; int mNextStreamId; // Need to hold on to stream references until configure completes. Vector<sp<camera3::Camera3Stream> > mDeletedStreams; /**** End scope for mLock ****/ class CaptureRequest : public LightRefBase<CaptureRequest> { public: CameraMetadata mSettings; sp<camera3::Camera3Stream> mInputStream; Vector<sp<camera3::Camera3Stream> > mOutputStreams; }; typedef List<sp<CaptureRequest> > RequestList; /** * Lock-held version of waitUntilDrained. Will transition to IDLE on * success. */ status_t waitUntilDrainedLocked(); /** * Do common work for setting up a streaming or single capture request. * On success, will transition to ACTIVE if in IDLE. */ sp<CaptureRequest> setUpRequestLocked(const CameraMetadata &request); /** * Build a CaptureRequest request from the CameraDeviceBase request * settings. */ sp<CaptureRequest> createCaptureRequest(const CameraMetadata &request); /** * Take the currently-defined set of streams and configure the HAL to use * them. This is a long-running operation (may be several hundered ms). */ status_t configureStreamsLocked(); /** /** * Thread for managing capture request submission to HAL device. * Thread for managing capture request submission to HAL device. */ */ Loading @@ -100,18 +179,80 @@ class Camera3Device : public: public: RequestThread(wp<Camera3Device> parent); RequestThread(wp<Camera3Device> parent, camera3_device_t *hal3Device); /** * Call after stream (re)-configuration is completed. */ void configurationComplete(); /** * Set or clear the list of repeating requests. Does not block * on either. Use waitUntilPaused to wait until request queue * has emptied out. */ status_t setRepeatingRequests(const RequestList& requests); status_t clearRepeatingRequests(); status_t queueRequest(sp<CaptureRequest> request); /** * Pause/unpause the capture thread. Doesn't block, so use * waitUntilPaused to wait until the thread is paused. */ void setPaused(bool paused); /** * Wait until thread is paused, either due to setPaused(true) * or due to lack of input requests. Returns TIMED_OUT in case * the thread does not pause within the timeout. */ status_t waitUntilPaused(nsecs_t timeout); protected: protected: virtual bool threadLoop(); virtual bool threadLoop(); private: private: static const nsecs_t kRequestTimeout = 50e6; // 50 ms // Waits for a request, or returns NULL if times out. sp<CaptureRequest> waitForNextRequest(); // Return buffers, etc, for a request that couldn't be fully // constructed. The buffers will be returned in the ERROR state // to mark them as not having valid data. // All arguments will be modified. void cleanUpFailedRequest(camera3_capture_request_t &request, sp<CaptureRequest> &nextRequest, Vector<camera3_stream_buffer_t> &outputBuffers); // Pause handling bool waitIfPaused(); wp<Camera3Device> mParent; wp<Camera3Device> mParent; camera3_device_t *mHal3Device; Mutex mRequestLock; Condition mRequestSignal; RequestList mRequestQueue; RequestList mRepeatingRequests; bool mReconfigured; // Used by waitIfPaused, waitForNextRequest, and waitUntilPaused Mutex mPauseLock; bool mDoPause; Condition mDoPauseSignal; bool mPaused; Condition mPausedSignal; sp<CaptureRequest> mPrevRequest; int32_t mFrameNumber; }; }; sp<RequestThread> requestThread; sp<RequestThread> mRequestThread; /** /** * Callback functions from HAL device * Callback functions from HAL device Loading