summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2010-08-08 00:29:51 -0400
committerSteve Kondik <shade@chemlab.org>2010-08-08 16:26:10 -0400
commit41066ed56592a4348220f9b292cf623bcb79f3c9 (patch)
tree0be6e24053a5dccbf2daeb83c819ffaaa8dc3748
parent8009c68c573be61877641ce878b7dfe53f647ae0 (diff)
downloadframeworks_base-41066ed56592a4348220f9b292cf623bcb79f3c9.zip
frameworks_base-41066ed56592a4348220f9b292cf623bcb79f3c9.tar.gz
frameworks_base-41066ed56592a4348220f9b292cf623bcb79f3c9.tar.bz2
HACK: Allow use of Eclair MemoryDealer for compatibility.
Take #2.
-rw-r--r--core/jni/Android.mk4
-rw-r--r--core/jni/CursorWindow.cpp19
-rw-r--r--core/jni/CursorWindow.h12
-rw-r--r--include/binder/MemoryDealer.h5
-rw-r--r--include/binder/MemoryDealerEclair.h257
-rw-r--r--include/binder/MemoryHeapPmem.h10
-rw-r--r--libs/audioflinger/AudioFlinger.cpp4
-rw-r--r--libs/audioflinger/AudioFlinger.h4
-rw-r--r--libs/binder/Android.mk8
-rw-r--r--libs/binder/MemoryDealerEclair.cpp422
-rw-r--r--libs/binder/MemoryHeapPmem.cpp4
-rw-r--r--media/libmedia/Android.mk4
-rw-r--r--media/libmedia/AudioRecord.cpp4
-rw-r--r--media/libmedia/AudioTrack.cpp4
-rw-r--r--media/libmediaplayerservice/MetadataRetrieverClient.cpp42
-rw-r--r--media/libmediaplayerservice/MetadataRetrieverClient.h5
-rw-r--r--media/libstagefright/OMXCodec.cpp5
-rw-r--r--media/libstagefright/omx/tests/OMXHarness.cpp8
18 files changed, 810 insertions, 11 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 6edc45f..bd0f307 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -185,8 +185,8 @@ LOCAL_SHARED_LIBRARIES := \
ifneq ($(BOARD_USES_ECLAIR_LIBCAMERA),true)
LOCAL_SHARED_LIBRARIES += \
- libsurfaceflinger_client \
- libcamera_client
+ libsurfaceflinger_client \
+ libcamera_client
endif
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
diff --git a/core/jni/CursorWindow.cpp b/core/jni/CursorWindow.cpp
index 7877921..f089583 100644
--- a/core/jni/CursorWindow.cpp
+++ b/core/jni/CursorWindow.cpp
@@ -18,9 +18,12 @@
#define LOG_TAG "CursorWindow"
#include <utils/Log.h>
+#ifdef USE_ECLAIR_MEMORYDEALER
+#include <binder/MemoryDealer.h>
+#else
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryBase.h>
-
+#endif
#include <assert.h>
#include <string.h>
#include <stdlib.h>
@@ -38,7 +41,11 @@ CursorWindow::CursorWindow(size_t maxSize) :
{
}
+#ifdef USE_ECLAIR_MEMORYDEALER
+bool CursorWindow::setMemory(sp<IMemory> memory)
+#else
bool CursorWindow::setMemory(const sp<IMemory>& memory)
+#endif
{
mMemory = memory;
mData = (uint8_t *) memory->pointer();
@@ -48,6 +55,9 @@ bool CursorWindow::setMemory(const sp<IMemory>& memory)
mHeader = (window_header_t *) mData;
// Make the window read-only
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mHeap = NULL;
+#endif
ssize_t size = memory->size();
mSize = size;
mMaxSize = size;
@@ -59,11 +69,16 @@ LOG_WINDOW("Created CursorWindow from existing IMemory: mFreeOffset = %d, numRow
bool CursorWindow::initBuffer(bool localOnly)
{
//TODO Use a non-memory dealer mmap region for localOnly
-
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mHeap = new MemoryDealer(new SharedHeap(mMaxSize, 0, "CursorWindow"));
+ if (mHeap != NULL) {
+ mMemory = mHeap->allocate(mMaxSize);
+#else
sp<MemoryHeapBase> heap;
heap = new MemoryHeapBase(mMaxSize, 0, "CursorWindow");
if (heap != NULL) {
mMemory = new MemoryBase(heap, 0, mMaxSize);
+#endif
if (mMemory != NULL) {
mData = (uint8_t *) mMemory->pointer();
if (mData) {
diff --git a/core/jni/CursorWindow.h b/core/jni/CursorWindow.h
index 3fcb560..f5d791a 100644
--- a/core/jni/CursorWindow.h
+++ b/core/jni/CursorWindow.h
@@ -21,9 +21,12 @@
#include <stddef.h>
#include <stdint.h>
+#ifdef USE_ECLAIR_MEMORYDEALER
+#include <binder/MemoryDealer.h>
+#else
#include <binder/IMemory.h>
#include <utils/RefBase.h>
-
+#endif
#include <jni.h>
#define DEFAULT_WINDOW_SIZE 4096
@@ -101,7 +104,11 @@ class CursorWindow
public:
CursorWindow(size_t maxSize);
CursorWindow(){}
+#ifdef USE_ECLAIR_MEMORYDEALER
+ bool setMemory(sp<IMemory>);
+#else
bool setMemory(const sp<IMemory>&);
+#endif
~CursorWindow();
bool initBuffer(bool localOnly);
@@ -189,6 +196,9 @@ private:
size_t mSize;
size_t mMaxSize;
window_header_t * mHeader;
+#ifdef USE_ECLAIR_MEMORYDEALER
+ sp<MemoryDealer> mHeap;
+#endif
sp<IMemory> mMemory;
/**
diff --git a/include/binder/MemoryDealer.h b/include/binder/MemoryDealer.h
index 170f20d..2512c27 100644
--- a/include/binder/MemoryDealer.h
+++ b/include/binder/MemoryDealer.h
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+#ifdef USE_ECLAIR_MEMORYDEALER
+#include <binder/MemoryDealerEclair.h>
+#else
+
#ifndef ANDROID_MEMORY_DEALER_H
#define ANDROID_MEMORY_DEALER_H
@@ -58,3 +62,4 @@ private:
}; // namespace android
#endif // ANDROID_MEMORY_DEALER_H
+#endif // USE_ECLAIR_MEMORYDEALER
diff --git a/include/binder/MemoryDealerEclair.h b/include/binder/MemoryDealerEclair.h
new file mode 100644
index 0000000..03ac70a
--- /dev/null
+++ b/include/binder/MemoryDealerEclair.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2007 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_MEMORY_DEALER_H
+#define ANDROID_MEMORY_DEALER_H
+
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/IMemory.h>
+#include <utils/threads.h>
+#include <binder/MemoryHeapBase.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+class String8;
+
+/*
+ * interface for implementing a "heap". A heap basically provides
+ * the IMemoryHeap interface for cross-process sharing and the
+ * ability to map/unmap pages within the heap.
+ */
+class HeapInterface : public virtual BnMemoryHeap
+{
+public:
+ // all values must be page-aligned
+ virtual sp<IMemory> mapMemory(size_t offset, size_t size) = 0;
+
+ HeapInterface();
+protected:
+ virtual ~HeapInterface();
+};
+
+// ----------------------------------------------------------------------------
+
+/*
+ * interface for implementing an allocator. An allocator provides
+ * methods for allocating and freeing memory blocks and dumping
+ * its state.
+ */
+class AllocatorInterface : public RefBase
+{
+public:
+ enum {
+ PAGE_ALIGNED = 0x00000001
+ };
+
+ virtual size_t allocate(size_t size, uint32_t flags = 0) = 0;
+ virtual status_t deallocate(size_t offset) = 0;
+ virtual size_t size() const = 0;
+ virtual void dump(const char* what, uint32_t flags = 0) const = 0;
+ virtual void dump(String8& res,
+ const char* what, uint32_t flags = 0) const = 0;
+
+ AllocatorInterface();
+protected:
+ virtual ~AllocatorInterface();
+};
+
+// ----------------------------------------------------------------------------
+
+/*
+ * concrete implementation of HeapInterface on top of mmap()
+ */
+class SharedHeap : public HeapInterface, public MemoryHeapBase
+{
+public:
+ SharedHeap();
+ SharedHeap(size_t size, uint32_t flags = 0, char const * name = NULL);
+ virtual ~SharedHeap();
+ virtual sp<IMemory> mapMemory(size_t offset, size_t size);
+};
+
+// ----------------------------------------------------------------------------
+
+/*
+ * A simple templatized doubly linked-list implementation
+ */
+
+template <typename NODE>
+class LinkedList
+{
+ NODE* mFirst;
+ NODE* mLast;
+
+public:
+ LinkedList() : mFirst(0), mLast(0) { }
+ bool isEmpty() const { return mFirst == 0; }
+ NODE const* head() const { return mFirst; }
+ NODE* head() { return mFirst; }
+ NODE const* tail() const { return mLast; }
+ NODE* tail() { return mLast; }
+
+ void insertAfter(NODE* node, NODE* newNode) {
+ newNode->prev = node;
+ newNode->next = node->next;
+ if (node->next == 0) mLast = newNode;
+ else node->next->prev = newNode;
+ node->next = newNode;
+ }
+
+ void insertBefore(NODE* node, NODE* newNode) {
+ newNode->prev = node->prev;
+ newNode->next = node;
+ if (node->prev == 0) mFirst = newNode;
+ else node->prev->next = newNode;
+ node->prev = newNode;
+ }
+
+ void insertHead(NODE* newNode) {
+ if (mFirst == 0) {
+ mFirst = mLast = newNode;
+ newNode->prev = newNode->next = 0;
+ } else {
+ newNode->prev = 0;
+ newNode->next = mFirst;
+ mFirst->prev = newNode;
+ mFirst = newNode;
+ }
+ }
+
+ void insertTail(NODE* newNode) {
+ if (mLast == 0) {
+ insertHead(newNode);
+ } else {
+ newNode->prev = mLast;
+ newNode->next = 0;
+ mLast->next = newNode;
+ mLast = newNode;
+ }
+ }
+
+ NODE* remove(NODE* node) {
+ if (node->prev == 0) mFirst = node->next;
+ else node->prev->next = node->next;
+ if (node->next == 0) mLast = node->prev;
+ else node->next->prev = node->prev;
+ return node;
+ }
+};
+
+
+/*
+ * concrete implementation of AllocatorInterface using a simple
+ * best-fit allocation scheme
+ */
+class SimpleBestFitAllocator : public AllocatorInterface
+{
+public:
+
+ SimpleBestFitAllocator(size_t size);
+ virtual ~SimpleBestFitAllocator();
+
+ virtual size_t allocate(size_t size, uint32_t flags = 0);
+ virtual status_t deallocate(size_t offset);
+ virtual size_t size() const;
+ virtual void dump(const char* what, uint32_t flags = 0) const;
+ virtual void dump(String8& res,
+ const char* what, uint32_t flags = 0) const;
+
+private:
+
+ struct chunk_t {
+ chunk_t(size_t start, size_t size)
+ : start(start), size(size), free(1), prev(0), next(0) {
+ }
+ size_t start;
+ size_t size : 28;
+ int free : 4;
+ mutable chunk_t* prev;
+ mutable chunk_t* next;
+ };
+
+ ssize_t alloc(size_t size, uint32_t flags);
+ chunk_t* dealloc(size_t start);
+ void dump_l(const char* what, uint32_t flags = 0) const;
+ void dump_l(String8& res, const char* what, uint32_t flags = 0) const;
+
+ static const int kMemoryAlign;
+ mutable Mutex mLock;
+ LinkedList<chunk_t> mList;
+ size_t mHeapSize;
+};
+
+// ----------------------------------------------------------------------------
+
+class MemoryDealer : public RefBase
+{
+public:
+
+ enum {
+ READ_ONLY = MemoryHeapBase::READ_ONLY,
+ PAGE_ALIGNED = AllocatorInterface::PAGE_ALIGNED
+ };
+
+ // creates a memory dealer with the SharedHeap and SimpleBestFitAllocator
+ MemoryDealer(size_t size, uint32_t flags = 0, const char* name = 0);
+
+ // provide a custom heap but use the SimpleBestFitAllocator
+ MemoryDealer(const sp<HeapInterface>& heap);
+
+ // provide both custom heap and allocotar
+ MemoryDealer(
+ const sp<HeapInterface>& heap,
+ const sp<AllocatorInterface>& allocator);
+
+ virtual sp<IMemory> allocate(size_t size, uint32_t flags = 0);
+ virtual void deallocate(size_t offset);
+ virtual void dump(const char* what, uint32_t flags = 0) const;
+
+
+ sp<IMemoryHeap> getMemoryHeap() const { return heap(); }
+ sp<AllocatorInterface> getAllocator() const { return allocator(); }
+
+protected:
+ virtual ~MemoryDealer();
+
+private:
+ const sp<HeapInterface>& heap() const;
+ const sp<AllocatorInterface>& allocator() const;
+
+ class Allocation : public BnMemory {
+ public:
+ Allocation(const sp<MemoryDealer>& dealer,
+ ssize_t offset, size_t size, const sp<IMemory>& memory);
+ virtual ~Allocation();
+ virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+ private:
+ sp<MemoryDealer> mDealer;
+ ssize_t mOffset;
+ size_t mSize;
+ sp<IMemory> mMemory;
+ };
+
+ sp<HeapInterface> mHeap;
+ sp<AllocatorInterface> mAllocator;
+};
+
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_MEMORY_DEALER_H
diff --git a/include/binder/MemoryHeapPmem.h b/include/binder/MemoryHeapPmem.h
index e1660c4..02e83f8 100644
--- a/include/binder/MemoryHeapPmem.h
+++ b/include/binder/MemoryHeapPmem.h
@@ -20,18 +20,26 @@
#include <stdlib.h>
#include <stdint.h>
+#ifdef USE_ECLAIR_MEMORYDEALER
+#include <binder/MemoryDealer.h>
+#endif
#include <binder/MemoryHeapBase.h>
#include <binder/IMemory.h>
#include <utils/SortedVector.h>
+#ifndef USE_ECLAIR_MEMORYDEALER
#include <utils/threads.h>
+#endif
namespace android {
class MemoryHeapBase;
// ---------------------------------------------------------------------------
-
+#ifdef USE_ECLAIR_MEMORYDEALER
+class MemoryHeapPmem : public HeapInterface, public MemoryHeapBase
+#else
class MemoryHeapPmem : public MemoryHeapBase
+#endif
{
public:
class MemoryPmem : public BnMemory {
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index a2fbca1..890692d 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -3069,7 +3069,11 @@ void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
: RefBase(),
mAudioFlinger(audioFlinger),
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mMemoryDealer(new MemoryDealer(1024*1024)),
+#else
mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
+#endif
mPid(pid)
{
// 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 8f99cf8..05915e5 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -31,7 +31,11 @@
#include <utils/Atomic.h>
#include <utils/Errors.h>
#include <utils/threads.h>
+#ifdef USE_ECLAIR_MEMORYDEALER
#include <binder/MemoryDealer.h>
+#else
+#include <binder/MemoryDealer.h>
+#endif
#include <utils/SortedVector.h>
#include <utils/Vector.h>
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
index 13dc500..85cd488 100644
--- a/libs/binder/Android.mk
+++ b/libs/binder/Android.mk
@@ -21,7 +21,6 @@ sources := \
IPCThreadState.cpp \
IPermissionController.cpp \
IServiceManager.cpp \
- MemoryDealer.cpp \
MemoryBase.cpp \
MemoryHeapBase.cpp \
MemoryHeapPmem.cpp \
@@ -30,6 +29,13 @@ sources := \
ProcessState.cpp \
Static.cpp
+ifeq ($(BOARD_USES_ECLAIR_LIBCAMERA),true)
+ LOCAL_CFLAGS += -DUSE_ECLAIR_MEMORYDEALER
+ sources += MemoryDealerEclair.cpp
+else
+ sources += MemoryDealer.cpp
+endif
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
diff --git a/libs/binder/MemoryDealerEclair.cpp b/libs/binder/MemoryDealerEclair.cpp
new file mode 100644
index 0000000..a48a619
--- /dev/null
+++ b/libs/binder/MemoryDealerEclair.cpp
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2007 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 "MemoryDealer"
+#define USE_ECLAIR_MEMORYDEALER
+
+#include <binder/MemoryDealer.h>
+
+#include <utils/Log.h>
+#include <binder/IPCThreadState.h>
+#include <utils/SortedVector.h>
+#include <utils/String8.h>
+#include <binder/MemoryBase.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/file.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+HeapInterface::HeapInterface() { }
+HeapInterface::~HeapInterface() { }
+
+// ----------------------------------------------------------------------------
+
+AllocatorInterface::AllocatorInterface() { }
+AllocatorInterface::~AllocatorInterface() { }
+
+// ----------------------------------------------------------------------------
+
+class SimpleMemory : public MemoryBase {
+public:
+ SimpleMemory(const sp<IMemoryHeap>& heap, ssize_t offset, size_t size);
+ virtual ~SimpleMemory();
+};
+
+
+// ----------------------------------------------------------------------------
+
+MemoryDealer::Allocation::Allocation(
+ const sp<MemoryDealer>& dealer, ssize_t offset, size_t size,
+ const sp<IMemory>& memory)
+ : mDealer(dealer), mOffset(offset), mSize(size), mMemory(memory)
+{
+}
+
+MemoryDealer::Allocation::~Allocation()
+{
+ if (mSize) {
+ /* NOTE: it's VERY important to not free allocations of size 0 because
+ * they're special as they don't have any record in the allocator
+ * and could alias some real allocation (their offset is zero). */
+ mDealer->deallocate(mOffset);
+ }
+}
+
+sp<IMemoryHeap> MemoryDealer::Allocation::getMemory(
+ ssize_t* offset, size_t* size) const
+{
+ return mMemory->getMemory(offset, size);
+}
+
+// ----------------------------------------------------------------------------
+
+MemoryDealer::MemoryDealer(size_t size, uint32_t flags, const char* name)
+ : mHeap(new SharedHeap(size, flags, name)),
+ mAllocator(new SimpleBestFitAllocator(size))
+{
+}
+
+MemoryDealer::MemoryDealer(const sp<HeapInterface>& heap)
+ : mHeap(heap),
+ mAllocator(new SimpleBestFitAllocator(heap->virtualSize()))
+{
+}
+
+MemoryDealer::MemoryDealer( const sp<HeapInterface>& heap,
+ const sp<AllocatorInterface>& allocator)
+ : mHeap(heap), mAllocator(allocator)
+{
+}
+
+MemoryDealer::~MemoryDealer()
+{
+}
+
+sp<IMemory> MemoryDealer::allocate(size_t size, uint32_t flags)
+{
+ sp<IMemory> memory;
+ const ssize_t offset = allocator()->allocate(size, flags);
+ if (offset >= 0) {
+ sp<IMemory> new_memory = heap()->mapMemory(offset, size);
+ if (new_memory != 0) {
+ memory = new Allocation(this, offset, size, new_memory);
+ } else {
+ LOGE("couldn't map [%8lx, %u]", offset, size);
+ if (size) {
+ /* NOTE: it's VERY important to not free allocations of size 0
+ * because they're special as they don't have any record in the
+ * allocator and could alias some real allocation
+ * (their offset is zero). */
+ allocator()->deallocate(offset);
+ }
+ }
+ }
+ return memory;
+}
+
+void MemoryDealer::deallocate(size_t offset)
+{
+ allocator()->deallocate(offset);
+}
+
+void MemoryDealer::dump(const char* what, uint32_t flags) const
+{
+ allocator()->dump(what, flags);
+}
+
+const sp<HeapInterface>& MemoryDealer::heap() const {
+ return mHeap;
+}
+
+const sp<AllocatorInterface>& MemoryDealer::allocator() const {
+ return mAllocator;
+}
+
+// ----------------------------------------------------------------------------
+
+// align all the memory blocks on a cache-line boundary
+const int SimpleBestFitAllocator::kMemoryAlign = 32;
+
+SimpleBestFitAllocator::SimpleBestFitAllocator(size_t size)
+{
+ size_t pagesize = getpagesize();
+ mHeapSize = ((size + pagesize-1) & ~(pagesize-1));
+
+ chunk_t* node = new chunk_t(0, mHeapSize / kMemoryAlign);
+ mList.insertHead(node);
+}
+
+SimpleBestFitAllocator::~SimpleBestFitAllocator()
+{
+ while(!mList.isEmpty()) {
+ delete mList.remove(mList.head());
+ }
+}
+
+size_t SimpleBestFitAllocator::size() const
+{
+ return mHeapSize;
+}
+
+size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
+{
+ Mutex::Autolock _l(mLock);
+ ssize_t offset = alloc(size, flags);
+ return offset;
+}
+
+status_t SimpleBestFitAllocator::deallocate(size_t offset)
+{
+ Mutex::Autolock _l(mLock);
+ chunk_t const * const freed = dealloc(offset);
+ if (freed) {
+ return NO_ERROR;
+ }
+ return NAME_NOT_FOUND;
+}
+
+ssize_t SimpleBestFitAllocator::alloc(size_t size, uint32_t flags)
+{
+ if (size == 0) {
+ return 0;
+ }
+ size = (size + kMemoryAlign-1) / kMemoryAlign;
+ chunk_t* free_chunk = 0;
+ chunk_t* cur = mList.head();
+
+ size_t pagesize = getpagesize();
+ while (cur) {
+ int extra = 0;
+ if (flags & PAGE_ALIGNED)
+ extra = ( -cur->start & ((pagesize/kMemoryAlign)-1) ) ;
+
+ // best fit
+ if (cur->free && (cur->size >= (size+extra))) {
+ if ((!free_chunk) || (cur->size < free_chunk->size)) {
+ free_chunk = cur;
+ }
+ if (cur->size == size) {
+ break;
+ }
+ }
+ cur = cur->next;
+ }
+
+ if (free_chunk) {
+ const size_t free_size = free_chunk->size;
+ free_chunk->free = 0;
+ free_chunk->size = size;
+ if (free_size > size) {
+ int extra = 0;
+ if (flags & PAGE_ALIGNED)
+ extra = ( -free_chunk->start & ((pagesize/kMemoryAlign)-1) ) ;
+ if (extra) {
+ chunk_t* split = new chunk_t(free_chunk->start, extra);
+ free_chunk->start += extra;
+ mList.insertBefore(free_chunk, split);
+ }
+
+ LOGE_IF((flags&PAGE_ALIGNED) &&
+ ((free_chunk->start*kMemoryAlign)&(pagesize-1)),
+ "PAGE_ALIGNED requested, but page is not aligned!!!");
+
+ const ssize_t tail_free = free_size - (size+extra);
+ if (tail_free > 0) {
+ chunk_t* split = new chunk_t(
+ free_chunk->start + free_chunk->size, tail_free);
+ mList.insertAfter(free_chunk, split);
+ }
+ }
+ return (free_chunk->start)*kMemoryAlign;
+ }
+ return NO_MEMORY;
+}
+
+SimpleBestFitAllocator::chunk_t* SimpleBestFitAllocator::dealloc(size_t start)
+{
+ start = start / kMemoryAlign;
+ chunk_t* cur = mList.head();
+ while (cur) {
+ if (cur->start == start) {
+ LOG_FATAL_IF(cur->free,
+ "block at offset 0x%08lX of size 0x%08lX already freed",
+ cur->start*kMemoryAlign, cur->size*kMemoryAlign);
+
+ // merge freed blocks together
+ chunk_t* freed = cur;
+ cur->free = 1;
+ do {
+ chunk_t* const p = cur->prev;
+ chunk_t* const n = cur->next;
+ if (p && (p->free || !cur->size)) {
+ freed = p;
+ p->size += cur->size;
+ mList.remove(cur);
+ delete cur;
+ }
+ cur = n;
+ } while (cur && cur->free);
+
+ #ifndef NDEBUG
+ if (!freed->free) {
+ dump_l("dealloc (!freed->free)");
+ }
+ #endif
+ LOG_FATAL_IF(!freed->free,
+ "freed block at offset 0x%08lX of size 0x%08lX is not free!",
+ freed->start * kMemoryAlign, freed->size * kMemoryAlign);
+
+ return freed;
+ }
+ cur = cur->next;
+ }
+ return 0;
+}
+
+void SimpleBestFitAllocator::dump(const char* what, uint32_t flags) const
+{
+ Mutex::Autolock _l(mLock);
+ dump_l(what, flags);
+}
+
+void SimpleBestFitAllocator::dump_l(const char* what, uint32_t flags) const
+{
+ String8 result;
+ dump_l(result, what, flags);
+ LOGD("%s", result.string());
+}
+
+void SimpleBestFitAllocator::dump(String8& result,
+ const char* what, uint32_t flags) const
+{
+ Mutex::Autolock _l(mLock);
+ dump_l(result, what, flags);
+}
+
+void SimpleBestFitAllocator::dump_l(String8& result,
+ const char* what, uint32_t flags) const
+{
+ size_t size = 0;
+ int32_t i = 0;
+ chunk_t const* cur = mList.head();
+
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ snprintf(buffer, SIZE, " %s (%p, size=%u)\n",
+ what, this, (unsigned int)mHeapSize);
+
+ result.append(buffer);
+
+ while (cur) {
+ const char* errs[] = {"", "| link bogus NP",
+ "| link bogus PN", "| link bogus NP+PN" };
+ int np = ((cur->next) && cur->next->prev != cur) ? 1 : 0;
+ int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0;
+
+ snprintf(buffer, SIZE, " %3u: %08x | 0x%08X | 0x%08X | %s %s\n",
+ i, int(cur), int(cur->start*kMemoryAlign),
+ int(cur->size*kMemoryAlign),
+ int(cur->free) ? "F" : "A",
+ errs[np|pn]);
+
+ result.append(buffer);
+
+ if (!cur->free)
+ size += cur->size*kMemoryAlign;
+
+ i++;
+ cur = cur->next;
+ }
+ snprintf(buffer, SIZE, " size allocated: %u (%u KB)\n", int(size), int(size/1024));
+ result.append(buffer);
+}
+
+// ----------------------------------------------------------------------------
+
+SharedHeap::SharedHeap()
+ : HeapInterface(), MemoryHeapBase()
+{
+}
+
+SharedHeap::SharedHeap(size_t size, uint32_t flags, char const * name)
+ : MemoryHeapBase(size, flags, name)
+{
+}
+
+SharedHeap::~SharedHeap()
+{
+}
+
+sp<IMemory> SharedHeap::mapMemory(size_t offset, size_t size)
+{
+ return new SimpleMemory(this, offset, size);
+}
+
+
+SimpleMemory::SimpleMemory(const sp<IMemoryHeap>& heap,
+ ssize_t offset, size_t size)
+ : MemoryBase(heap, offset, size)
+{
+#ifndef NDEBUG
+ void* const start_ptr = (void*)(intptr_t(heap->base()) + offset);
+ memset(start_ptr, 0xda, size);
+#endif
+}
+
+SimpleMemory::~SimpleMemory()
+{
+ size_t freedOffset = getOffset();
+ size_t freedSize = getSize();
+
+ // keep the size to unmap in excess
+ size_t pagesize = getpagesize();
+ size_t start = freedOffset;
+ size_t end = start + freedSize;
+ start &= ~(pagesize-1);
+ end = (end + pagesize-1) & ~(pagesize-1);
+
+ // give back to the kernel the pages we don't need
+ size_t free_start = freedOffset;
+ size_t free_end = free_start + freedSize;
+ if (start < free_start)
+ start = free_start;
+ if (end > free_end)
+ end = free_end;
+ start = (start + pagesize-1) & ~(pagesize-1);
+ end &= ~(pagesize-1);
+
+ if (start < end) {
+ void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start);
+ size_t size = end-start;
+
+#ifndef NDEBUG
+ memset(start_ptr, 0xdf, size);
+#endif
+
+ // MADV_REMOVE is not defined on Dapper based Goobuntu
+#ifdef MADV_REMOVE
+ if (size) {
+ int err = madvise(start_ptr, size, MADV_REMOVE);
+ LOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s",
+ start_ptr, size, err<0 ? strerror(errno) : "Ok");
+ }
+#endif
+ }
+}
+
+}; // namespace android
diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp
index 16e92f9..5cc60f8 100644
--- a/libs/binder/MemoryHeapPmem.cpp
+++ b/libs/binder/MemoryHeapPmem.cpp
@@ -127,7 +127,11 @@ void SubRegionMemory::revoke()
MemoryHeapPmem::MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
uint32_t flags)
+#ifdef USE_ECLAIR_MEMORYDEALER
+ : HeapInterface(), MemoryHeapBase()
+#else
: MemoryHeapBase()
+#endif
{
char const * const device = pmemHeap->getDevice();
#if HAVE_ANDROID_OS
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index b660eec..02b8324 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -33,8 +33,8 @@ LOCAL_SHARED_LIBRARIES := \
ifneq ($(BOARD_USES_ECLAIR_LIBCAMERA),true)
LOCAL_SHARED_LIBRARIES += \
- libsurfaceflinger_client \
- libcamera_client
+ libsurfaceflinger_client \
+ libcamera_client
endif
LOCAL_MODULE:= libmedia
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index ad037d6..4e38773 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -37,6 +37,10 @@
#include <utils/Timers.h>
#include <cutils/atomic.h>
+#ifdef USE_ECLAIR_MEMORYDEALER
+#include <binder/MemoryDealer.h>
+#endif
+
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index cd7bcd5..ba99d81 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -37,6 +37,10 @@
#include <utils/Timers.h>
#include <cutils/atomic.h>
+#ifdef USE_ECLAIR_MEMORYDEALER
+#include <binder/MemoryDealer.h>
+#endif
+
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 550b84d..070680e 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -28,8 +28,12 @@
#include <string.h>
#include <cutils/atomic.h>
#include <cutils/properties.h>
+#ifdef USE_ECLAIR_MEMORYDEALER
+#include <binder/MemoryDealer.h>
+#else
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
+#endif
#include <android_runtime/ActivityManager.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -63,6 +67,10 @@ MetadataRetrieverClient::MetadataRetrieverClient(pid_t pid)
{
LOGV("MetadataRetrieverClient constructor pid(%d)", pid);
mPid = pid;
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mThumbnailDealer = NULL;
+ mAlbumArtDealer = NULL;
+#endif
mThumbnail = NULL;
mAlbumArt = NULL;
mRetriever = NULL;
@@ -93,6 +101,10 @@ void MetadataRetrieverClient::disconnect()
LOGV("disconnect from pid %d", mPid);
Mutex::Autolock lock(mLock);
mRetriever.clear();
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mThumbnailDealer.clear();
+ mAlbumArtDealer.clear();
+#endif
mThumbnail.clear();
mAlbumArt.clear();
mMode = METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL;
@@ -239,6 +251,9 @@ sp<IMemory> MetadataRetrieverClient::captureFrame()
LOGV("captureFrame");
Mutex::Autolock lock(mLock);
mThumbnail.clear();
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mThumbnailDealer.clear();
+#endif
if (mRetriever == NULL) {
LOGE("retriever is not initialized");
return NULL;
@@ -249,15 +264,27 @@ sp<IMemory> MetadataRetrieverClient::captureFrame()
return NULL;
}
size_t size = sizeof(VideoFrame) + frame->mSize;
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mThumbnailDealer = new MemoryDealer(size);
+ if (mThumbnailDealer == NULL) {
+#else
sp<MemoryHeapBase> heap = new MemoryHeapBase(size, 0, "MetadataRetrieverClient");
if (heap == NULL) {
+#endif
LOGE("failed to create MemoryDealer");
delete frame;
return NULL;
}
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mThumbnail = mThumbnailDealer->allocate(size);
+#else
mThumbnail = new MemoryBase(heap, 0, size);
+#endif
if (mThumbnail == NULL) {
LOGE("not enough memory for VideoFrame size=%u", size);
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mThumbnailDealer.clear();
+#endif
delete frame;
return NULL;
}
@@ -278,6 +305,9 @@ sp<IMemory> MetadataRetrieverClient::extractAlbumArt()
LOGV("extractAlbumArt");
Mutex::Autolock lock(mLock);
mAlbumArt.clear();
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mAlbumArtDealer.clear();
+#endif
if (mRetriever == NULL) {
LOGE("retriever is not initialized");
return NULL;
@@ -288,15 +318,27 @@ sp<IMemory> MetadataRetrieverClient::extractAlbumArt()
return NULL;
}
size_t size = sizeof(MediaAlbumArt) + albumArt->mSize;
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mAlbumArtDealer = new MemoryDealer(size);
+ if (mAlbumArtDealer == NULL) {
+#else
sp<MemoryHeapBase> heap = new MemoryHeapBase(size, 0, "MetadataRetrieverClient");
if (heap == NULL) {
+#endif
LOGE("failed to create MemoryDealer object");
delete albumArt;
return NULL;
}
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mAlbumArt = mAlbumArtDealer->allocate(size);
+#else
mAlbumArt = new MemoryBase(heap, 0, size);
+#endif
if (mAlbumArt == NULL) {
LOGE("not enough memory for MediaAlbumArt size=%u", size);
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mAlbumArtDealer.clear();
+#endif
delete albumArt;
return NULL;
}
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h
index 4aab94f..7e6d223 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.h
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.h
@@ -24,7 +24,6 @@
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <binder/IMemory.h>
-
#include <media/MediaMetadataRetrieverInterface.h>
@@ -63,6 +62,10 @@ private:
int mMode;
// Keep the shared memory copy of album art and capture frame (for thumbnail)
+#ifdef USE_ECLAIR_MEMORYDEALER
+ sp<MemoryDealer> mAlbumArtDealer;
+ sp<MemoryDealer> mThumbnailDealer;
+#endif
sp<IMemory> mAlbumArt;
sp<IMemory> mThumbnail;
};
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 69da7ef..e9a7248 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1211,8 +1211,11 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
}
size_t totalSize = def.nBufferCountActual * def.nBufferSize;
+#ifdef USE_ECLAIR_MEMORYDEALER
+ mDealer[portIndex] = new MemoryDealer(totalSize);
+#else
mDealer[portIndex] = new MemoryDealer(totalSize, "OMXCodec");
-
+#endif
for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
CHECK(mem.get() != NULL);
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index fcf506d..0245c11 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -24,7 +24,11 @@
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
+#ifdef USE_ECLAIR_MEMORYDEALER
#include <binder/MemoryDealer.h>
+#else
+#include <binder/MemoryDealer.h>
+#endif
#include <media/IMediaPlayerService.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaBuffer.h>
@@ -286,7 +290,11 @@ status_t Harness::testStateTransitions(
return OK;
}
+#ifdef USE_ECLAIR_MEMORYDEALER
+ sp<MemoryDealer> dealer = new MemoryDealer(8 * 1024 * 1024);
+#else
sp<MemoryDealer> dealer = new MemoryDealer(8 * 1024 * 1024, "OMXHarness");
+#endif
IOMX::node_id node;
status_t err =