Avoid unnecessary buffer copying if at all possible, detect if running in the mediaserver process.
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 39bd5b1..d38c177 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -42,6 +42,11 @@
     typedef void *buffer_id;
     typedef void *node_id;
 
+    // Given the calling process' pid, returns true iff
+    // the implementation of the OMX interface lives in the same
+    // process.
+    virtual bool livesLocally(pid_t pid) = 0;
+
     struct ComponentInfo {
         String8 mName;
         List<String8> mRoles;
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 351763c..2c32386 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -109,6 +109,7 @@
     };
 
     sp<IOMX> mOMX;
+    bool mOMXLivesLocally;
     IOMX::node_id mNode;
     uint32_t mQuirks;
     bool mIsEncoder;
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index b43e48f..277bce1 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -12,6 +12,7 @@
 
 enum {
     CONNECT = IBinder::FIRST_CALL_TRANSACTION,
+    LIVES_LOCALLY,
     LIST_NODES,
     ALLOCATE_NODE,
     FREE_NODE,
@@ -75,6 +76,15 @@
         : BpInterface<IOMX>(impl) {
     }
 
+    virtual bool livesLocally(pid_t pid) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+        data.writeInt32(pid);
+        remote()->transact(LIVES_LOCALLY, data, &reply);
+
+        return reply.readInt32() != 0;
+    }
+
     virtual status_t listNodes(List<ComponentInfo> *list) {
         list->clear();
 
@@ -369,6 +379,14 @@
 status_t BnOMX::onTransact(
     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
     switch (code) {
+        case LIVES_LOCALLY:
+        {
+            CHECK_INTERFACE(IOMX, data, reply);
+            reply->writeInt32(livesLocally((pid_t)data.readInt32()));
+
+            return OK;
+        }
+
         case LIST_NODES:
         {
             CHECK_INTERFACE(IOMX, data, reply);
@@ -408,7 +426,7 @@
             if (err == OK) {
                 reply->writeIntPtr((intptr_t)node);
             }
-                
+
             return NO_ERROR;
         }
 
@@ -419,7 +437,7 @@
             node_id node = (void*)data.readIntPtr();
 
             reply->writeInt32(freeNode(node));
-                
+
             return NO_ERROR;
         }
 
@@ -631,7 +649,7 @@
 
             node_id node = (void*)data.readIntPtr();
             const char *parameter_name = data.readCString();
-            
+
             OMX_INDEXTYPE index;
             status_t err = getExtensionIndex(node, parameter_name, &index);
 
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index c4d3b5d..c583b93 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1016,6 +1016,7 @@
         const char *componentName,
         const sp<MediaSource> &source)
     : mOMX(omx),
+      mOMXLivesLocally(omx->livesLocally(getpid())),
       mNode(node),
       mQuirks(quirks),
       mIsEncoder(isEncoder),
@@ -1191,12 +1192,22 @@
         IOMX::buffer_id buffer;
         if (portIndex == kPortIndexInput
                 && (mQuirks & kRequiresAllocateBufferOnInputPorts)) {
-            err = mOMX->allocateBufferWithBackup(
-                    mNode, portIndex, mem, &buffer);
+            if (mOMXLivesLocally) {
+                err = mOMX->allocateBuffer(
+                        mNode, portIndex, def.nBufferSize, &buffer);
+            } else {
+                err = mOMX->allocateBufferWithBackup(
+                        mNode, portIndex, mem, &buffer);
+            }
         } else if (portIndex == kPortIndexOutput
                 && (mQuirks & kRequiresAllocateBufferOnOutputPorts)) {
-            err = mOMX->allocateBufferWithBackup(
-                    mNode, portIndex, mem, &buffer);
+            if (mOMXLivesLocally) {
+                err = mOMX->allocateBuffer(
+                        mNode, portIndex, def.nBufferSize, &buffer);
+            } else {
+                err = mOMX->allocateBufferWithBackup(
+                        mNode, portIndex, mem, &buffer);
+            }
         } else {
             err = mOMX->useBuffer(mNode, portIndex, mem, &buffer);
         }
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index ce0b0d5..b559101 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -31,6 +31,8 @@
 public:
     OMX();
 
+    virtual bool livesLocally(pid_t pid);
+
     virtual status_t listNodes(List<ComponentInfo> *list);
 
     virtual status_t allocateNode(
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 0d617a5..2121321 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -164,6 +164,10 @@
     instance->onObserverDied(mMaster);
 }
 
+bool OMX::livesLocally(pid_t pid) {
+    return pid == getpid();
+}
+
 status_t OMX::listNodes(List<ComponentInfo> *list) {
     list->clear();