Fix no-copy-overhead OMXCodec implementation to actually work.
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index d38c177..bb7677d 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -82,9 +82,13 @@
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer) = 0;
 
+    // This API clearly only makes sense if the caller lives in the
+    // same process as the callee, i.e. is the media_server, as the
+    // returned "buffer_data" pointer is just that, a pointer into local
+    // address space.
     virtual status_t allocateBuffer(
             node_id node, OMX_U32 port_index, size_t size,
-            buffer_id *buffer) = 0;
+            buffer_id *buffer, void **buffer_data) = 0;
 
     virtual status_t allocateBufferWithBackup(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 2c32386..ac2f662 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -100,6 +100,8 @@
         IOMX::buffer_id mBuffer;
         bool mOwnedByComponent;
         sp<IMemory> mMem;
+        size_t mSize;
+        void *mData;
         MediaBuffer *mMediaBuffer;
     };
 
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 277bce1..0469fd5 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -240,7 +240,7 @@
 
     virtual status_t allocateBuffer(
             node_id node, OMX_U32 port_index, size_t size,
-            buffer_id *buffer) {
+            buffer_id *buffer, void **buffer_data) {
         Parcel data, reply;
         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
         data.writeIntPtr((intptr_t)node);
@@ -255,7 +255,8 @@
             return err;
         }
 
-        *buffer = (void*)reply.readIntPtr();
+        *buffer = (void *)reply.readIntPtr();
+        *buffer_data = (void *)reply.readIntPtr();
 
         return err;
     }
@@ -569,11 +570,14 @@
             size_t size = data.readInt32();
 
             buffer_id buffer;
-            status_t err = allocateBuffer(node, port_index, size, &buffer);
+            void *buffer_data;
+            status_t err = allocateBuffer(
+                    node, port_index, size, &buffer, &buffer_data);
             reply->writeInt32(err);
 
             if (err == OK) {
                 reply->writeIntPtr((intptr_t)buffer);
+                reply->writeIntPtr((intptr_t)buffer_data);
             }
 
             return NO_ERROR;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index c583b93..2686489 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1189,12 +1189,19 @@
         sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
         CHECK(mem.get() != NULL);
 
+        BufferInfo info;
+        info.mData = NULL;
+        info.mSize = def.nBufferSize;
+
         IOMX::buffer_id buffer;
         if (portIndex == kPortIndexInput
                 && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
             if (mOMXLivesLocally) {
+                mem.clear();
+
                 err = mOMX->allocateBuffer(
-                        mNode, portIndex, def.nBufferSize, &buffer);
+                        mNode, portIndex, def.nBufferSize, &buffer,
+                        &info.mData);
             } else {
                 err = mOMX->allocateBufferWithBackup(
                         mNode, portIndex, mem, &buffer);
@@ -1202,8 +1209,11 @@
         } else if (portIndex == kPortIndexOutput
                 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
             if (mOMXLivesLocally) {
+                mem.clear();
+
                 err = mOMX->allocateBuffer(
-                        mNode, portIndex, def.nBufferSize, &buffer);
+                        mNode, portIndex, def.nBufferSize, &buffer,
+                        &info.mData);
             } else {
                 err = mOMX->allocateBufferWithBackup(
                         mNode, portIndex, mem, &buffer);
@@ -1217,14 +1227,17 @@
             return err;
         }
 
-        BufferInfo info;
+        if (mem != NULL) {
+            info.mData = mem->pointer();
+        }
+
         info.mBuffer = buffer;
         info.mOwnedByComponent = false;
         info.mMem = mem;
         info.mMediaBuffer = NULL;
 
         if (portIndex == kPortIndexOutput) {
-            info.mMediaBuffer = new MediaBuffer(mem->pointer(), mem->size());
+            info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize);
             info.mMediaBuffer->setObserver(this);
         }
 
@@ -1599,6 +1612,8 @@
 }
 
 void OMXCodec::onStateChange(OMX_STATETYPE newState) {
+    CODEC_LOGV("onStateChange %d", newState);
+
     switch (newState) {
         case OMX_StateIdle:
         {
@@ -1666,6 +1681,12 @@
             break;
         }
 
+        case OMX_StateInvalid:
+        {
+            setState(ERROR);
+            break;
+        }
+
         default:
         {
             CHECK(!"should not be here.");
@@ -1845,16 +1866,16 @@
             static const uint8_t kNALStartCode[4] =
                     { 0x00, 0x00, 0x00, 0x01 };
 
-            CHECK(info->mMem->size() >= specific->mSize + 4);
+            CHECK(info->mSize >= specific->mSize + 4);
 
             size += 4;
 
-            memcpy(info->mMem->pointer(), kNALStartCode, 4);
-            memcpy((uint8_t *)info->mMem->pointer() + 4,
+            memcpy(info->mData, kNALStartCode, 4);
+            memcpy((uint8_t *)info->mData + 4,
                    specific->mData, specific->mSize);
         } else {
-            CHECK(info->mMem->size() >= specific->mSize);
-            memcpy(info->mMem->pointer(), specific->mData, specific->mSize);
+            CHECK(info->mSize >= specific->mSize);
+            memcpy(info->mData, specific->mData, specific->mSize);
         }
 
         mNoMoreOutputData = false;
@@ -1901,12 +1922,12 @@
 
         srcLength = srcBuffer->range_length();
 
-        if (info->mMem->size() < srcLength) {
-            LOGE("info->mMem->size() = %d, srcLength = %d",
-                 info->mMem->size(), srcLength);
+        if (info->mSize < srcLength) {
+            LOGE("info->mSize = %d, srcLength = %d",
+                 info->mSize, srcLength);
         }
-        CHECK(info->mMem->size() >= srcLength);
-        memcpy(info->mMem->pointer(),
+        CHECK(info->mSize >= srcLength);
+        memcpy(info->mData,
                (const uint8_t *)srcBuffer->data() + srcBuffer->range_offset(),
                srcLength);
 
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index b559101..ea131e8 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -65,7 +65,7 @@
 
     virtual status_t allocateBuffer(
             node_id node, OMX_U32 port_index, size_t size,
-            buffer_id *buffer);
+            buffer_id *buffer, void **buffer_data);
 
     virtual status_t allocateBufferWithBackup(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 923b801..b5b31ac 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -54,7 +54,8 @@
             OMX::buffer_id *buffer);
 
     status_t allocateBuffer(
-            OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer);
+            OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
+            void **buffer_data);
 
     status_t allocateBufferWithBackup(
             OMX_U32 portIndex, const sp<IMemory> &params,
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 2121321..918d055 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -280,9 +280,9 @@
 
 status_t OMX::allocateBuffer(
         node_id node, OMX_U32 port_index, size_t size,
-        buffer_id *buffer) {
+        buffer_id *buffer, void **buffer_data) {
     return findInstance(node)->allocateBuffer(
-            port_index, size, buffer);
+            port_index, size, buffer, buffer_data);
 }
 
 status_t OMX::allocateBufferWithBackup(
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 4eb6417..70c6a58 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -258,7 +258,8 @@
 }
 
 status_t OMXNodeInstance::allocateBuffer(
-        OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer) {
+        OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
+        void **buffer_data) {
     Mutex::Autolock autoLock(mLock);
 
     BufferMeta *buffer_meta = new BufferMeta(size);
@@ -280,6 +281,7 @@
     }
 
     *buffer = header;
+    *buffer_data = header->pBuffer;
 
     addActiveBuffer(portIndex, *buffer);