diff options
author | Iliyan Malchev <malchev@google.com> | 2011-06-06 17:21:32 -0700 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-06-07 11:43:20 -0700 |
commit | 26adde897188059057b3ffcfde1d60171fc6888c (patch) | |
tree | 8ad4e488ac2efc5e0f5234f4b690c1818eb6e1e8 /services/camera | |
parent | 6e49bd393f263bd17a65eb5c1a0e649933c78504 (diff) | |
download | frameworks_av-26adde897188059057b3ffcfde1d60171fc6888c.zip frameworks_av-26adde897188059057b3ffcfde1d60171fc6888c.tar.gz frameworks_av-26adde897188059057b3ffcfde1d60171fc6888c.tar.bz2 |
frameworks/base: updates for camera HAL memory management
-- when the camera HAL allocates memory
-- it requests is as N buffers by S bytes each
-- it may specify a file descriptor to get mmapped; if -1, then we use ashmem
-- when issuing data and data-timestamp callbacks, the camera HAL specifies a
buffer index
-- range checking is performed on the buffer indices
-- memory requested by a camera HAL is not incStrong'ed, and needs to be
expliciftly released by the camera HAL (by calling the release method on the
camera_memory_t handle)
Change-Id: I0f09603aa786c238590e7288388ab673787e6032
Signed-off-by: Iliyan Malchev <malchev@google.com>
Diffstat (limited to 'services/camera')
-rw-r--r-- | services/camera/libcameraservice/CameraHardwareInterface.h | 88 |
1 files changed, 70 insertions, 18 deletions
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h index f9fa30e..7a18831 100644 --- a/services/camera/libcameraservice/CameraHardwareInterface.h +++ b/services/camera/libcameraservice/CameraHardwareInterface.h @@ -438,18 +438,23 @@ private: } static void __data_cb(int32_t msg_type, - const camera_memory_t *data, + const camera_memory_t *data, unsigned int index, void *user) { LOGV("%s", __FUNCTION__); CameraHardwareInterface *__this = static_cast<CameraHardwareInterface *>(user); sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle)); - __this->mDataCb(msg_type, mem, __this->mCbUser); + if (index >= mem->mNumBufs) { + LOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__, + index, mem->mNumBufs); + return; + } + __this->mDataCb(msg_type, mem->mBuffers[index], __this->mCbUser); } static void __data_cb_timestamp(nsecs_t timestamp, int32_t msg_type, - const camera_memory_t *data, + const camera_memory_t *data, unsigned index, void *user) { LOGV("%s", __FUNCTION__); @@ -459,38 +464,85 @@ private: // drop all references, it will be destroyed (as well as the enclosed // MemoryHeapBase. sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle)); - __this->mDataCbTimestamp(timestamp, msg_type, mem, __this->mCbUser); + if (index >= mem->mNumBufs) { + LOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__, + index, mem->mNumBufs); + return; + } + __this->mDataCbTimestamp(timestamp, msg_type, mem->mBuffers[index], __this->mCbUser); } // This is a utility class that combines a MemoryHeapBase and a MemoryBase // in one. Since we tend to use them in a one-to-one relationship, this is // handy. - class CameraHeapMemory : public MemoryBase { + class CameraHeapMemory : public RefBase { public: - CameraHeapMemory(size_t size) : - MemoryBase(new MemoryHeapBase(size), 0, size) + CameraHeapMemory(int fd, size_t buf_size, uint_t num_buffers = 1) : + mBufSize(buf_size), + mNumBufs(num_buffers) + { + mHeap = new MemoryHeapBase(fd, buf_size * num_buffers); + commonInitialization(); + } + + CameraHeapMemory(size_t buf_size, uint_t num_buffers = 1) : + mBufSize(buf_size), + mNumBufs(num_buffers) { - handle.data = getHeap()->base(); - handle.size = size; + mHeap = new MemoryHeapBase(buf_size * num_buffers); + commonInitialization(); + } + + void commonInitialization() + { + handle.data = mHeap->base(); + handle.size = mBufSize * mNumBufs; handle.handle = this; + + mBuffers = new sp<MemoryBase>[mNumBufs]; + for (uint_t i = 0; i < mNumBufs; i++) + mBuffers[i] = new MemoryBase(mHeap, + i * mBufSize, + mBufSize); + + handle.release = __put_memory; } + virtual ~CameraHeapMemory() + { + delete [] mBuffers; + } + + size_t mBufSize; + uint_t mNumBufs; + sp<MemoryHeapBase> mHeap; + sp<MemoryBase> *mBuffers; + camera_memory_t handle; }; - static camera_memory_t* __get_memory(size_t size, - void *user __attribute__((unused))) + static camera_memory_t* __get_memory(int fd, size_t buf_size, uint_t num_bufs, + void *user __attribute__((unused))) { - // We allocate the object here, but we do not assign it to a strong - // pointer yet. The HAL will pass it back to us via the data callback - // or the data-timestamp callback, and from there on we will wrap it - // within a strong pointer. - - CameraHeapMemory *mem = new CameraHeapMemory(size); + CameraHeapMemory *mem; + if (fd < 0) + mem = new CameraHeapMemory(buf_size, num_bufs); + else + mem = new CameraHeapMemory(fd, buf_size, num_bufs); + mem->incStrong(mem); return &mem->handle; } + static void __put_memory(camera_memory_t *data) + { + if (!data) + return; + + CameraHeapMemory *mem = static_cast<CameraHeapMemory *>(data->handle); + mem->decStrong(mem); + } + static ANativeWindow *__to_anw(void *user) { CameraHardwareInterface *__this = @@ -541,7 +593,7 @@ private: static int __set_buffer_count(struct preview_stream_ops* w, int count) { ANativeWindow *a = anw(w); - return native_window_set_buffer_count(a, count); + return native_window_set_buffer_count(a, count); } static int __set_buffers_geometry(struct preview_stream_ops* w, |